changeset 3717:be8045e2d792

Merge
author lana
date Fri, 11 Feb 2011 12:14:38 -0800
parents 493a9eeb9bca 326aac19a89f
children 82f7b8f6b174
files make/java/hpi/Makefile make/java/hpi/hpi_common.gmk make/java/hpi/native/Makefile make/java/hpi/native/mapfile-vers make/java/hpi/native/reorder-i586 make/java/hpi/native/reorder-sparc make/java/hpi/native/reorder-sparcv9 make/java/hpi/windows/Makefile src/share/hpi/export/bool.h src/share/hpi/export/dll.h src/share/hpi/export/hpi.h src/share/hpi/include/hpi_impl.h src/share/hpi/include/vm_calls.h src/share/hpi/src/hpi.c src/solaris/classes/sun/awt/fontconfigs/solaris.fontconfig.5.8.properties src/solaris/classes/sun/awt/fontconfigs/solaris.fontconfig.5.9.properties src/solaris/hpi/export/byteorder_md.h src/solaris/hpi/export/hpi_md.h src/solaris/hpi/export/io_md.h src/solaris/hpi/export/path_md.h src/solaris/hpi/export/timeval_md.h src/solaris/hpi/include/hpi_init.h src/solaris/hpi/include/interrupt.h src/solaris/hpi/include/largefile.h src/solaris/hpi/include/largefile_linux.h src/solaris/hpi/include/largefile_solaris.h src/solaris/hpi/native_threads/include/condvar_md.h src/solaris/hpi/native_threads/include/monitor_md.h src/solaris/hpi/native_threads/include/mutex_md.h src/solaris/hpi/native_threads/include/np.h src/solaris/hpi/native_threads/include/porting.h src/solaris/hpi/native_threads/include/threads_md.h src/solaris/hpi/native_threads/src/condvar_md.c src/solaris/hpi/native_threads/src/interrupt_md.c src/solaris/hpi/native_threads/src/monitor_md.c src/solaris/hpi/native_threads/src/mutex_md.c src/solaris/hpi/native_threads/src/sys_api_td.c src/solaris/hpi/native_threads/src/threads_linux.c src/solaris/hpi/native_threads/src/threads_md.c src/solaris/hpi/native_threads/src/threads_solaris.c src/solaris/hpi/src/interrupt.c src/solaris/hpi/src/linker_md.c src/solaris/hpi/src/memory_md.c src/solaris/hpi/src/system_md.c src/windows/hpi/export/byteorder_md.h src/windows/hpi/export/hpi_md.h src/windows/hpi/export/io_md.h src/windows/hpi/export/path_md.h src/windows/hpi/export/timeval_md.h src/windows/hpi/include/monitor_md.h src/windows/hpi/include/mutex_md.h src/windows/hpi/include/threads_md.h src/windows/hpi/src/linker_md.c src/windows/hpi/src/memory_md.c src/windows/hpi/src/monitor_md.c src/windows/hpi/src/path_md.c src/windows/hpi/src/socket_md.c src/windows/hpi/src/sys_api_md.c src/windows/hpi/src/system_md.c src/windows/hpi/src/threads_md.c test/java/net/InetAddress/B4762344.java test/java/net/InetAddress/META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor test/java/net/InetAddress/Simple1NameServiceDescriptor.java test/java/net/InetAddress/Simple2NameServiceDescriptor.java test/java/net/InetAddress/SimpleNameService.java test/sun/net/InetAddress/nameservice/B6442088.java test/sun/net/InetAddress/nameservice/CacheTest.java test/sun/net/InetAddress/nameservice/META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor test/sun/net/InetAddress/nameservice/SimpleNameService.java test/sun/net/InetAddress/nameservice/SimpleNameServiceDescriptor.java
diffstat 328 files changed, 8839 insertions(+), 16334 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Thu Feb 10 21:36:18 2011 +0300
+++ b/.hgtags	Fri Feb 11 12:14:38 2011 -0800
@@ -100,3 +100,7 @@
 869190935eedee7750d955019ab2a1b80f0a13a8 jdk7-b123
 1c72adc9d5f331cb882cf5354ba0dcb118a60b23 jdk7-b124
 0a56bdd709d01c1663047e55201d19152ffd3d69 jdk7-b125
+8361ef97a0f90086c9048beaf7cea1a37216c4cd jdk7-b126
+29e09de1d0b4f84faea114cf10b3ec08b59acc4e jdk7-b127
+f08682e23279d6cccbdcafda1eb0647ba4900874 jdk7-b128
+14cd5d54a8d0b9c368d60ea83a066735b9931015 jdk7-b129
--- a/make/Makefile	Thu Feb 10 21:36:18 2011 +0300
+++ b/make/Makefile	Fri Feb 11 12:14:38 2011 -0800
@@ -100,7 +100,6 @@
 DEVTOOLS_PATH.desc         = Directory containing zip and unzip
 CUPS_HEADERS_PATH.desc     = Include directory location for CUPS header files
 DXSDK_PATH.desc            = Root directory of DirectX SDK
-MSVCRT_DLL_PATH.desc       = Directory containing mscvrt.dll
 
 # Make variables to print out (description and value)
 VARIABLE_PRINTVAL_LIST +=       \
@@ -133,12 +132,10 @@
 ifeq ($(PLATFORM), windows)
 
 VARIABLE_PRINTVAL_LIST +=       \
-    DXSDK_PATH                  \
-    MSVCRT_DLL_PATH
+    DXSDK_PATH
 
 VARIABLE_CHECKDIR_LIST +=       \
-    DXSDK_PATH                  \
-    MSVCRT_DLL_PATH
+    DXSDK_PATH
 
 endif
 
--- a/make/com/sun/java/pack/Makefile	Thu Feb 10 21:36:18 2011 +0300
+++ b/make/com/sun/java/pack/Makefile	Fri Feb 11 12:14:38 2011 -0800
@@ -155,6 +155,7 @@
 	$(MT) /manifest $(OBJDIR)/unpack200$(EXE_SUFFIX).manifest /outputresource:$(TEMPDIR)/unpack200$(EXE_SUFFIX);#1
 endif
 	$(CP) $(TEMPDIR)/unpack200$(EXE_SUFFIX) $(UNPACK_EXE)
+	@$(call binary_file_verification,$@)
 	$(install-module-file)
 
 ifeq ($(PLATFORM), windows) 
--- a/make/common/Defs-linux.gmk	Thu Feb 10 21:36:18 2011 +0300
+++ b/make/common/Defs-linux.gmk	Fri Feb 11 12:14:38 2011 -0800
@@ -75,15 +75,6 @@
 CC_PROGRAM_OUTPUT_FLAG = -o #trailing blank required!
 
 #
-# Default HPI libraries. Build will build only native, unless
-# overriden at the make command line. This makes it convenient for
-# people doing, say, a pthreads port -- they can create a posix
-# directory here, and say "gnumake HPIS=posix" at the top
-# level.
-#
-HPIS = native
-
-#
 # Default optimization
 #
 
--- a/make/common/Defs-solaris.gmk	Thu Feb 10 21:36:18 2011 +0300
+++ b/make/common/Defs-solaris.gmk	Fri Feb 11 12:14:38 2011 -0800
@@ -75,15 +75,6 @@
 CC_PROGRAM_OUTPUT_FLAG = -o #trailing blank required!
 
 #
-# Default HPI libraries. Build will build only native unless
-# overriden at the make command line. This makes it convenient for
-# people doing, say, a pthreads port -- they can create a posix
-# directory here, and say "gnumake HPIS=posix" at the top
-# level.
-#
-HPIS = native
-
-#
 # Java default optimization (-x04/-O2) etc.  Applies to the VM.
 #
 ifndef OPTIMIZATION_LEVEL
--- a/make/common/Defs-windows.gmk	Thu Feb 10 21:36:18 2011 +0300
+++ b/make/common/Defs-windows.gmk	Fri Feb 11 12:14:38 2011 -0800
@@ -43,7 +43,6 @@
 # The suffix applied to scripts (.bat for windows, nothing for unix)
 SCRIPT_SUFFIX = .bat
 
-HPIS = windows
 # LIB_LOCATION, which for windows identifies where .exe files go, may be
 # set by each GNUmakefile. The default is BINDIR.
 ifndef LIB_LOCATION
@@ -68,28 +67,27 @@
 
 # The following DLL's are considered MS runtime libraries and should
 #     not to be REBASEd, see deploy/make/common/Release.gmk.
-#     msvcrt.dll, msvcrnn.dll [msvcr71 or msvcr80 or msvcr90] : Microsoft runtimes
-MS_RUNTIME_LIBRARIES = msvcrt.dll
+#     msvcr*.dll: Microsoft runtimes
 ifeq ($(ARCH_DATA_MODEL), 32)
   ifeq ($(COMPILER_VERSION), VS2003)
     MSVCRNN_DLL = msvcr71.dll
     MSVCPNN_DLL = msvcp71.dll
-    MS_RUNTIME_LIBRARIES += $(MSVCRNN_DLL)
+    MS_RUNTIME_LIBRARIES = msvcrt.dll $(MSVCRNN_DLL)
   endif
   ifeq ($(COMPILER_VERSION), VS2005)
     MSVCRNN_DLL = msvcr80.dll
     MSVCPNN_DLL = msvcp80.dll
-    MS_RUNTIME_LIBRARIES += $(MSVCRNN_DLL)
+    MS_RUNTIME_LIBRARIES = msvcrt.dll $(MSVCRNN_DLL)
   endif
   ifeq ($(COMPILER_VERSION), VS2008)
     MSVCRNN_DLL = msvcr90.dll
     MSVCPNN_DLL = msvcp90.dll
-    MS_RUNTIME_LIBRARIES += $(MSVCRNN_DLL)
+    MS_RUNTIME_LIBRARIES = msvcrt.dll $(MSVCRNN_DLL)
   endif
   ifeq ($(COMPILER_VERSION), VS2010)
     MSVCRNN_DLL = msvcr100.dll
     MSVCPNN_DLL = msvcp100.dll
-    MS_RUNTIME_LIBRARIES += $(MSVCRNN_DLL)
+    MS_RUNTIME_LIBRARIES = $(MSVCRNN_DLL)
   endif
 endif
 
@@ -97,12 +95,12 @@
   ifeq ($(COMPILER_VERSION), VS2008)
     MSVCRNN_DLL = msvcr90.dll
     MSVCPNN_DLL = msvcp90.dll
-    MS_RUNTIME_LIBRARIES += $(MSVCRNN_DLL)
+    MS_RUNTIME_LIBRARIES = msvcrt.dll $(MSVCRNN_DLL)
   endif
   ifeq ($(COMPILER_VERSION), VS2010)
     MSVCRNN_DLL = msvcr100.dll
     MSVCPNN_DLL = msvcp100.dll
-    MS_RUNTIME_LIBRARIES += $(MSVCRNN_DLL)
+    MS_RUNTIME_LIBRARIES = $(MSVCRNN_DLL)
   endif
 endif
 
@@ -284,7 +282,7 @@
     MS_RUNTIME_OPTION=-MTd
   else
     # This MS debugging flag forces a dependence on the debug
-    #     version of the runtime library (MSVCRTD.DLL), as does -MDd.
+    #     version of the runtime library (MSVCR*D.DLL), as does -MDd.
     #     We cannot re-distribute this debug runtime.
     MS_RUNTIME_OPTION=-MDd
   endif
@@ -365,10 +363,6 @@
 
   # LFLAGS are the flags given to $(LINK) and used to build the actual DLL file
   BASELFLAGS = -nologo /opt:REF /incremental:no
-ifdef MT
-    # VS2005, VS2008, and beyond: ask LINK to generate manifests for .dll & .exe
-    BASELFLAGS += /manifest
-endif
 
   LFLAGS = $(BASELFLAGS) $(LDEBUG) $(EXTRA_LFLAGS) $(LFLAGS_$(COMPILER_VERSION))
   LDDFLAGS += $(LFLAGS_$(COMPILER_VERSION))
--- a/make/common/Defs.gmk	Thu Feb 10 21:36:18 2011 +0300
+++ b/make/common/Defs.gmk	Fri Feb 11 12:14:38 2011 -0800
@@ -271,10 +271,9 @@
 # An attempt is made to generate unique enough directories for the
 # generated files to not have name collisisons. Most build units
 # defines PRODUCT (except Release.gmk), but then they may or may 
-# not define PACKAGE, THREADIR (only HPI uses this), PROGRAM, and 
-# LIBRARY. This code chunk attempts to generate a unique 
-# OBJDIR/CLASSHDRDIR for each build unit based on which of those 
-# values are set within each build unit.
+# not define PACKAGE, PROGRAM, and LIBRARY. This code attempts to
+# generate a unique OBJDIR/CLASSHDRDIR for each build unit based
+# on which of those values are set within each build unit.
 
 UNIQUE_LOCATION_STRING = tmp
 
@@ -298,10 +297,6 @@
   endif
 endif
 
-ifneq ($(THREADDIR),)
-  UNIQUE_LOCATION_STRING += /$(THREADDIR)
-endif
-
 #
 # Build units may or may not define MODULE.  Default to "other".
 #
--- a/make/common/Demo.gmk	Thu Feb 10 21:36:18 2011 +0300
+++ b/make/common/Demo.gmk	Fri Feb 11 12:14:38 2011 -0800
@@ -294,6 +294,7 @@
 	@$(prep-target)
 	$(LINK.demo) $(SHARED_LIBRARY_FLAG) $(CC_PROGRAM_OUTPUT_FLAG)$@ \
 	    $(DEMO_FULL_OBJECTS) $(LDLIBS.demo)
+	@$(call binary_file_verification,$@)
 
   # Generation of any javah include file, make sure objects are dependent on it
   ifdef DEMO_NATIVECLASS
--- a/make/common/Library.gmk	Thu Feb 10 21:36:18 2011 +0300
+++ b/make/common/Library.gmk	Fri Feb 11 12:14:38 2011 -0800
@@ -159,9 +159,6 @@
 # build it into $(OBJDIR) so that the other generated files get put 
 # there, then copy just the DLL (and MAP file) to the requested directory.
 #
-# In VS2005 or VS2008 the link command creates a .manifest file that we want
-# to insert into the linked artifact so we do not need to track it separately.
-# Use ";#2" for .dll and ";#1" for .exe in the MT command below:
 $(ACTUAL_LIBRARY):: $(OBJDIR)/$(LIBRARY).lcf
 	@$(prep-target)
 	@$(MKDIR) -p $(OBJDIR)
@@ -169,10 +166,8 @@
 	  -map:$(OBJDIR)/$(LIBRARY).map \
 	  $(LFLAGS) @$(OBJDIR)/$(LIBRARY).lcf \
 	  $(OTHER_LCF) $(JAVALIB) $(LDLIBS)
-ifdef MT
-	$(MT) /manifest $(OBJDIR)/$(@F).manifest /outputresource:$(OBJDIR)/$(@F);#2
-endif
 	$(CP) $(OBJDIR)/$(@F) $@
+	@$(call binary_file_verification,$@)
 	$(install-module-file)
 	$(CP) $(OBJDIR)/$(LIBRARY).map $(@D)
 	$(CP) $(OBJDIR)/$(LIBRARY).pdb $(@D)
@@ -239,6 +234,7 @@
 	$(AR) -r $@ $(FILES_o)
 else # LIBRARY
 	$(LINKER) $(SHARED_LIBRARY_FLAG) -o $@ $(FILES_o) $(LDLIBS)
+	@$(call binary_file_verification,$@)
 	$(install-module-file)
 ifeq ($(WRITE_LIBVERSION),true)
 	$(MCS) -d -a "$(FULL_VERSION)" $@
--- a/make/common/Modules.gmk	Thu Feb 10 21:36:18 2011 +0300
+++ b/make/common/Modules.gmk	Fri Feb 11 12:14:38 2011 -0800
@@ -73,47 +73,20 @@
 
 #
 # Paths to these files we need
-JDK_MODULE_LICENSES   = $(LICENSE_DOCLIST_JDK:%=$(JDK_MODULE_IMAGE_DIR)/%)
-JDK_MODULE_64_LICENSES = $(LICENSE_DOCLIST_JDK:%=$(JDK_MODULE_IMAGE_DIR)/%64)
-JDK_MODULE_DOCFILES   = $(OTHER_DOCLIST_JDK:%=$(JDK_MODULE_IMAGE_DIR)/%)
-
-JRE_MODULE_LICENSES   = $(LICENSE_DOCLIST_JRE:%=$(JRE_MODULE_IMAGE_DIR)/%)
-JRE_MODULE_64_LICENSES = $(LICENSE_DOCLIST_JRE:%=$(JRE_MODULE_IMAGE_DIR)/%64)
-JRE_MODULE_DOCFILES   = $(OTHER_DOCLIST_JRE:%=$(JRE_MODULE_IMAGE_DIR)/%)
-JRE_MODULE_DOCFILES  += $(JRE_NAMECHANGE_DOCLIST:%=$(JRE_MODULE_IMAGE_DIR)/%$(TEXT_SUFFIX))
+JDK_MODULE_DOCFILES   = $(IMAGE_DOCLIST_JDK:%=$(JDK_MODULE_IMAGE_DIR)/%)
+JRE_MODULE_DOCFILES   = $(IMAGE_DOCLIST_JRE:%=$(JRE_MODULE_IMAGE_DIR)/%)
 
 ###### RULES
 
 # JDK files
 $(JDK_MODULE_IMAGE_DIR)/%: $(SHARE_JDK_DOC_SRC)/%
 	$(process-doc-file)
-# Removes LICENSE_VERSION or not
-ifdef LICENSE_VERSION
-$(JDK_MODULE_IMAGE_DIR)/%: $(SHARE_JDK_DOC_SRC)/%$(LICENSE_VERSION)
-	$(process-doc-file)
-$(JDK_MODULE_IMAGE_DIR)/%64: $(SHARE_JDK_DOC_SRC)/%$(LICENSE_VERSION)
-	$(process-doc-file)
-else
-$(JDK_MODULE_IMAGE_DIR)/%64: $(SHARE_JDK_DOC_SRC)/%
-	$(process-doc-file)
-endif
 
 # JRE files 
 $(JRE_MODULE_IMAGE_DIR)/%: $(SHARE_JRE_DOC_SRC)/%
 	$(process-doc-file)
-# Add $(TEXT_SUFFIX) suffix
-ifdef TEXT_SUFFIX
-$(JRE_MODULE_IMAGE_DIR)/%$(TEXT_SUFFIX): $(SHARE_JRE_DOC_SRC)/%
-	$(process-doc-file)
-endif
-# Removes LICENSE_VERSION or not
-ifdef LICENSE_VERSION
-$(JRE_MODULE_IMAGE_DIR)/%: $(SHARE_JRE_DOC_SRC)/%$(LICENSE_VERSION)
-	$(process-doc-file)
-$(JRE_MODULE_IMAGE_DIR)/%64: $(SHARE_JRE_DOC_SRC)/%$(LICENSE_VERSION)
-	$(process-doc-file)
-else
-$(JRE_MODULE_IMAGE_DIR)/%64: $(SHARE_JRE_DOC_SRC)/%
+ifeq ($(PLATFORM), windows)
+$(JRE_MODULE_IMAGE_DIR)/README.txt: $(SHARE_JRE_DOC_SRC)/README
 	$(process-doc-file)
 endif
 
@@ -157,8 +130,7 @@
 	$(MKDIR) -p $(JRE_MODULE_IMAGE_DIR)
 
 # 64-bit solaris jre image contains only the 64-bit add-on files.
-initial-module-image-jre-sol64:: initial-module-image-jre-setup \
-			  $(JRE_MODULE_LICENSES) $(JRE_MODULE_64_LICENSES)
+initial-module-image-jre-sol64:: initial-module-image-jre-setup
 	@# Use tar instead of cp to preserve the symbolic links
 	for dir in bin lib ; do \
 	  ( $(CD) $(OUTPUTDIR) && \
@@ -174,7 +146,7 @@
 
 # Construct an initial jre image (initial jdk jre) no trimming or stripping
 initial-module-image-jre:: initial-module-image-jre-setup \
-		    $(JRE_LICENSES) $(JRE_MODULE_DOCFILES) \
+		    $(JRE_MODULE_DOCFILES) \
 		    $(BUILDMETAINDEX_JARFILE)
 	@# Copy in bin directory
 	$(CD) $(OUTPUTDIR) && $(FIND) bin -depth | $(CPIO) -pdum $(JRE_MODULE_IMAGE_DIR)
@@ -222,7 +194,7 @@
 	@# Remove certain *.lib files
 	$(CD) $(JRE_MODULE_IMAGE_DIR)/lib && \
             $(RM) java.$(LIB_SUFFIX) jvm.$(LIB_SUFFIX) \
-                  hpi.$(LIB_SUFFIX) awt.$(LIB_SUFFIX) jawt.$(LIB_SUFFIX)
+                  awt.$(LIB_SUFFIX) jawt.$(LIB_SUFFIX)
   ifeq ($(ARCH_DATA_MODEL), 32)
 	@# The Java Kernel JRE image ships with a special VM.  It is not included
 	@# in the full JRE image, so remove it.  Also, is it only for 32-bit windows.
@@ -310,8 +282,7 @@
 
 # Solaris 64 bit image is special
 initial-module-image-jdk-sol64:: initial-module-image-jdk-setup \
-			  initial-module-image-jdk64-bindemos \
-			  $(JDK_MODULE_LICENSES) $(JDK_MODULARLIZED_64_LICENSES)
+			  initial-module-image-jdk64-bindemos
 
 # DB files to add
 ifeq ($(OPENJDK),true)
@@ -335,7 +306,7 @@
 # Standard jdk image
 initial-module-image-jdk:: initial-module-image-jdk-setup \
 		    initial-module-image-jdk-db \
-		    $(JDK_MODULE_LICENSES) $(JDK_MODULE_DOCFILES)
+		    $(JDK_MODULE_DOCFILES)
 	$(MKDIR) $(JDK_MODULE_IMAGE_DIR)/lib
 	@#
 	@# copy jdk modules to jdk/lib
@@ -415,8 +386,7 @@
 trim-module-image-jdk::
 	@# Remove tools that should not be part of SDK.
 	for t in $(NOTJDKTOOLS); do \
-	    $(RM) $(JDK_MODULE_IMAGE_DIR)/bin/$${t}$(EXE_SUFFIX) \
-		  $(JDK_MODULE_IMAGE_DIR)/bin/*/native_threads/$${t}$(EXE_SUFFIX); \
+	    $(RM) $(JDK_MODULE_IMAGE_DIR)/bin/$${t}$(EXE_SUFFIX); \
 	done
 
 # Get list of Elf files in the jdk
--- a/make/common/Program.gmk	Thu Feb 10 21:36:18 2011 +0300
+++ b/make/common/Program.gmk	Fri Feb 11 12:14:38 2011 -0800
@@ -142,10 +142,15 @@
   STACK_SIZE=1048576
 endif
 
-# In VS2005 or VS2008 the link command creates a .manifest file that we want
-# to insert into the linked artifact so we do not need to track it separately.
+IMVERSION=$(JDK_MINOR_VERSION).$(JDK_MICRO_VERSION).$(JDK_UPDATE_VER).$(COOKED_BUILD_NUMBER)
+$(OBJDIR)/$(PROGRAM).exe.manifest: $(JDK_TOPDIR)/src/windows/resource/java.manifest
+	@$(prep-target)
+	$(SED) 's%IMVERSION%$(IMVERSION)%g;s%PROGRAM%$(PROGRAM)%g' $< > $@
+
+# We used a hand-crafted manifest file for all executables.
+# It is tweaked to embed the build number and executable name.
 # Use ";#2" for .dll and ";#1" for .exe in the MT command below:
-$(OBJDIR)/$(PROGRAM)$(EXE_SUFFIX):: $(OBJDIR)/$(PROGRAM).lcf $(FILES_o) $(JLI_LCF) 
+$(OBJDIR)/$(PROGRAM)$(EXE_SUFFIX):: $(OBJDIR)/$(PROGRAM).lcf $(FILES_o) $(JLI_LCF) $(OBJDIR)/$(PROGRAM).exe.manifest
 	@$(prep-target)
 	@set -- $?; \
 	    $(ECHO) Rebuilding $@ because of $$1 $$2 $$3 $$4 $$5 $$6 $${7:+...};
@@ -155,6 +160,7 @@
 ifdef MT
 	$(MT) /manifest $(OBJDIR)/$(PROGRAM).exe.manifest /outputresource:$@;#1
 endif
+	@$(call binary_file_verification,$@)
 
 else # PLATFORM
 
@@ -179,6 +185,7 @@
 	@$(MKDIR) -p $(TEMPDIR)
 	$(LINK_PRE_CMD) $(CC) $(CC_OBJECT_OUTPUT_FLAG)$@ $(LDFLAGS) \
 	    $(FILES_o) $(THREADLIBS) $(LDLIBS)
+	@$(call binary_file_verification,$@)
 	$(install-module-file)
 
 endif # PLATFORM
--- a/make/common/Release.gmk	Thu Feb 10 21:36:18 2011 +0300
+++ b/make/common/Release.gmk	Fri Feb 11 12:14:38 2011 -0800
@@ -26,6 +26,9 @@
 include $(JDK_TOPDIR)/make/docs/CORE_PKGS.gmk
 include $(JDK_TOPDIR)/make/docs/NON_CORE_PKGS.gmk
 
+# What jdk version are we building
+THIS_JDK_VERSION := $(JDK_MAJOR_VERSION).$(JDK_MINOR_VERSION).$(JDK_MICRO_VERSION)
+
 #
 # Perform release engineering tasks.
 #
@@ -72,14 +75,6 @@
 
 JTG_DOCS            = $(JDK_TOPDIR)/src/solaris/doc
 
-#We use this for man page header
-jdkversion := $(JDK_MAJOR_VERSION).$(JDK_MINOR_VERSION).$(JDK_MICRO_VERSION)
-
-# Text documents on windows use this suffix
-ifeq ($(PLATFORM), windows)
-  TEXT_SUFFIX = .txt
-endif
-
 # The base names of all the license and document files for the jdk and jre
 #   (These files get placed in the jdk and jre install images)
 ifdef OPENJDK
@@ -87,53 +82,28 @@
   SHARE_JDK_DOC_SRC = $(JDK_TOPDIR)
   SHARE_JRE_DOC_SRC = $(JDK_TOPDIR)
   # Same files for jdk and jre, no name changes
-  LICENSE_DOCLIST_JDK = LICENSE     ASSEMBLY_EXCEPTION
-  LICENSE_DOCLIST_JRE = LICENSE     ASSEMBLY_EXCEPTION
-  OTHER_DOCLIST_JDK   = THIRD_PARTY_README
-  OTHER_DOCLIST_JRE   = THIRD_PARTY_README
+  IMAGE_DOCLIST_JDK = LICENSE ASSEMBLY_EXCEPTION THIRD_PARTY_README
+  IMAGE_DOCLIST_JRE = LICENSE ASSEMBLY_EXCEPTION THIRD_PARTY_README
 else
   # Where to find these files
   SHARE_JDK_DOC_SRC = $(CLOSED_SHARE_SRC)/doc/jdk
   SHARE_JRE_DOC_SRC = $(CLOSED_SHARE_SRC)/doc/jre
-  # Select the pre-release or FCS license version based on the build milestone.
-  LICENSE_VERSION=.pre
-  ifeq ($(MILESTONE), fcs)
-    LICENSE_VERSION=.fcs
+  IMAGE_DOCLIST_JDK = COPYRIGHT README.html  THIRDPARTYLICENSEREADME.txt
+  IMAGE_DOCLIST_JRE = COPYRIGHT Welcome.html THIRDPARTYLICENSEREADME.txt
+  ifeq ($(PLATFORM), windows)
+    IMAGE_DOCLIST_JRE += README.txt
+  else
+    IMAGE_DOCLIST_JRE += README
   endif
-  ifeq ($(PLATFORM), windows)
-    LICENSE_DOCLIST_JDK = $(subst $(LICENSE_VERSION),,\
-		   $(shell $(CD) $(SHARE_JDK_DOC_SRC) && \
-		           $(LS) *LICENSE*$(LICENSE_VERSION)))
-    LICENSE_DOCLIST_JRE = $(subst $(LICENSE_VERSION),,\
-		   $(shell $(CD) $(SHARE_JRE_DOC_SRC) && \
-		           $(LS) *LICENSE*$(LICENSE_VERSION)))
-  else
-    LICENSE_DOCLIST_JDK = $(subst $(LICENSE_VERSION),,\
-	         $(shell $(CD) $(SHARE_JDK_DOC_SRC) && \
-		         $(LS) *LICENSE*$(LICENSE_VERSION) | $(GREP) -v rtf))
-    LICENSE_DOCLIST_JRE = $(subst $(LICENSE_VERSION),,\
-	         $(shell $(CD) $(SHARE_JRE_DOC_SRC) && \
-		         $(LS) *LICENSE*$(LICENSE_VERSION) | $(GREP) -v rtf))
-  endif
-  OTHER_DOCLIST_JDK = COPYRIGHT README.html README_ja.html README_zh_CN.html
-  OTHER_DOCLIST_JRE = COPYRIGHT Welcome.html
-  JRE_NAMECHANGE_DOCLIST = README
 endif
 
 # Paths to these files we need
-JDK_LICENSES   = $(LICENSE_DOCLIST_JDK:%=$(JDK_IMAGE_DIR)/%)
-JDK64_LICENSES = $(LICENSE_DOCLIST_JDK:%=$(JDK_IMAGE_DIR)/%64)
-JDK_DOCFILES   = $(OTHER_DOCLIST_JDK:%=$(JDK_IMAGE_DIR)/%)
-
-JRE_LICENSES   = $(LICENSE_DOCLIST_JRE:%=$(JRE_IMAGE_DIR)/%)
-JRE64_LICENSES = $(LICENSE_DOCLIST_JRE:%=$(JRE_IMAGE_DIR)/%64)
-JRE_DOCFILES   = $(OTHER_DOCLIST_JRE:%=$(JRE_IMAGE_DIR)/%)
-JRE_DOCFILES  += $(JRE_NAMECHANGE_DOCLIST:%=$(JRE_IMAGE_DIR)/%$(TEXT_SUFFIX))
+JDK_DOCFILES   = $(IMAGE_DOCLIST_JDK:%=$(JDK_IMAGE_DIR)/%)
+JRE_DOCFILES   = $(IMAGE_DOCLIST_JRE:%=$(JRE_IMAGE_DIR)/%)
 
 # absolute directory names: note, these must exist prior to build
 # time - they are created in the main Makefile.
 JRE_IMAGE_BINDIR   = $(JRE_IMAGE_DIR)/bin
-JRE_IMAGE_THREADIR = $(JRE_IMAGE_DIR)/bin/*/native_threads
 
 MAINMANIFEST  = $(JDK_TOPDIR)/make/tools/manifest.mf
 BEANMANIFEST  = $(JDK_TOPDIR)/make/javax/swing/beaninfo/manifest
@@ -214,7 +184,7 @@
         $(MKDIR) -p $1/man/$${ja_dir}/man1; \
         $(CAT) $${manbase}/ja/$${manpage} \
           | $(NATIVE2ASCII) -encoding $(JA_SOURCE_ENCODING) \
-          | $(SED) 's/@@VERSION@@/$(jdkversion)/g' \
+          | $(SED) 's/@@VERSION@@/$(THIS_JDK_VERSION)/g' \
           | $(NATIVE2ASCII) -reverse -encoding $${ja_encoding} \
             > $1/man/$${ja_dir}/man1/$${manpage}; \
       done; \
@@ -244,6 +214,7 @@
 initial-image-jre initial-image-jdk \
 initial-image-jre-sol64 initial-image-jdk-sol64 \
 trim-image-jre trim-image-jdk \
+identify-image-jre identify-image-jdk \
 process-image-jre process-image-jdk \
 compare-image \
 sec-files sec-files-win jgss-files ::
@@ -253,11 +224,12 @@
 images:: sanity-images post-sanity-images  \
 	 $(INITIAL_IMAGE_JRE) $(INITIAL_IMAGE_JDK) \
 	 trim-image-jre trim-image-jdk \
+         identify-image-jre identify-image-jdk \
 	 process-image-jre process-image-jdk sec-files sec-files-win jgss-files
 
 # Don't use these
-image-jre:: initial-image-jre trim-image-jre process-image-jre
-image-jdk:: initial-image-jdk trim-image-jdk process-image-jdk
+image-jre:: initial-image-jre trim-image-jre identify-image-jre process-image-jre
+image-jdk:: initial-image-jdk trim-image-jdk identify-image-jdk process-image-jdk
 
 #
 # Sources we ship in the SDK.
@@ -504,33 +476,12 @@
 # JDK files
 $(JDK_IMAGE_DIR)/%: $(SHARE_JDK_DOC_SRC)/%
 	$(process-doc-file)
-# Removes LICENSE_VERSION or not
-ifdef LICENSE_VERSION
-$(JDK_IMAGE_DIR)/%: $(SHARE_JDK_DOC_SRC)/%$(LICENSE_VERSION)
-	$(process-doc-file)
-$(JDK_IMAGE_DIR)/%64: $(SHARE_JDK_DOC_SRC)/%$(LICENSE_VERSION)
-	$(process-doc-file)
-else
-$(JDK_IMAGE_DIR)/%64: $(SHARE_JDK_DOC_SRC)/%
-	$(process-doc-file)
-endif
 
 # JRE files 
 $(JRE_IMAGE_DIR)/%: $(SHARE_JRE_DOC_SRC)/%
 	$(process-doc-file)
-# Add $(TEXT_SUFFIX) suffix
-ifdef TEXT_SUFFIX
-$(JRE_IMAGE_DIR)/%$(TEXT_SUFFIX): $(SHARE_JRE_DOC_SRC)/%
-	$(process-doc-file)
-endif
-# Removes LICENSE_VERSION or not
-ifdef LICENSE_VERSION
-$(JRE_IMAGE_DIR)/%: $(SHARE_JRE_DOC_SRC)/%$(LICENSE_VERSION)
-	$(process-doc-file)
-$(JRE_IMAGE_DIR)/%64: $(SHARE_JRE_DOC_SRC)/%$(LICENSE_VERSION)
-	$(process-doc-file)
-else
-$(JRE_IMAGE_DIR)/%64: $(SHARE_JRE_DOC_SRC)/%
+ifeq ($(PLATFORM), windows)
+$(JRE_IMAGE_DIR)/README.txt: $(SHARE_JRE_DOC_SRC)/README
 	$(process-doc-file)
 endif
 
@@ -738,8 +689,7 @@
 	$(MKDIR) -p $(JRE_IMAGE_DIR)
 
 # 64-bit solaris jre image contains only the 64-bit add-on files.
-initial-image-jre-sol64:: initial-image-jre-setup \
-			  $(JRE_LICENSES) $(JRE64_LICENSES)
+initial-image-jre-sol64:: initial-image-jre-setup
 	@# Use tar instead of cp to preserve the symbolic links
 	for dir in bin lib ; do \
 	  ( $(CD) $(OUTPUTDIR) && \
@@ -760,7 +710,7 @@
 # See "initial-image-jdk-setup" for an explanation of the rm of
 # drive names like C:
 initial-image-jre:: initial-image-jre-setup \
-		    $(JRE_LICENSES) $(JRE_DOCFILES) \
+		    $(JRE_DOCFILES) \
 		    $(RT_JAR) $(RESOURCES_JAR) $(JSSE_JAR) \
 		    $(BUILDMETAINDEX_JARFILE)
 	@# Copy in bin directory
@@ -802,7 +752,7 @@
 	@# Remove certain *.lib files
 	$(CD) $(JRE_IMAGE_DIR)/lib && \
             $(RM) java.$(LIB_SUFFIX) jvm.$(LIB_SUFFIX) \
-                  hpi.$(LIB_SUFFIX) awt.$(LIB_SUFFIX) jawt.$(LIB_SUFFIX)
+                  awt.$(LIB_SUFFIX) jawt.$(LIB_SUFFIX)
   ifeq ($(ARCH_DATA_MODEL), 32)
 	@# The Java Kernel JRE image ships with a special VM.  It is not included
 	@# in the full JRE image, so remove it.  Also, is it only for 32-bit windows.
@@ -836,11 +786,14 @@
   endif
 endif # PLATFORM
 
-# Get list of all Elf files in the jre
-JRE_ELF_LIST=$(TEMPDIR)/jre-elf-files.list
-$(JRE_ELF_LIST):
-ifneq ($(PLATFORM), windows)
+# Get list of all binary (COFF or Elf) files in the jre
+JRE_BIN_LIST=$(TEMPDIR)/jre-bin-files.list
+$(JRE_BIN_LIST):
 	$(RM) $@
+ifeq ($(PLATFORM), windows)
+	$(FIND) $(JRE_IMAGE_DIR)/bin -type f -name \*.exe \
+	   -o -name \*.dll | $(EGREP) -v -i "$(MSVCRNN_DLL)" > $@
+else
 	$(FIND) $(JRE_IMAGE_DIR)/lib -type f -name \*.$(LIB_SUFFIX) >> $@
 	$(FILE) `$(FIND) $(JRE_IMAGE_DIR)/bin -type f -name \*$(EXE_SUFFIX)` \
 	    | $(EGREP) 'ELF' | $(CUT) -d':' -f1 >> $@
@@ -848,9 +801,9 @@
 
 # Post process the image (strips and mcs on Elf files we are shipping)
 #   (Note the jdk WILL want the jre image before this processing)
-process-image-jre:: $(JRE_ELF_LIST)
+process-image-jre:: $(JRE_BIN_LIST)
 ifneq ($(POST_STRIP_PROCESS), )
-	for f in `$(CAT) $(JRE_ELF_LIST)`; do \
+	@for f in `$(CAT) $(JRE_BIN_LIST)`; do \
 	  $(CHMOD) u+w $${f}; \
 	  $(ECHO) $(POST_STRIP_PROCESS) $${f}; \
 	  $(POST_STRIP_PROCESS) $${f}; \
@@ -858,14 +811,17 @@
 	done
 endif
 ifneq ($(POST_MCS_PROCESS), )
-	for f in `$(CAT) $(JRE_ELF_LIST)`; do \
+	@for f in `$(CAT) $(JRE_BIN_LIST)`; do \
 	  $(CHMOD) u+w $${f}; \
 	  $(ECHO) $(POST_MCS_PROCESS) $${f}; \
 	  $(POST_MCS_PROCESS) $${f}; \
 	  $(CHMOD) go-w $${f}; \
 	done
 endif
-	$(RM) $(JRE_ELF_LIST)
+	@for f in `$(CAT) $(JRE_BIN_LIST)`; do \
+	  $(call binary_file_verification,$${f}); \
+	done
+	$(RM) $(JRE_BIN_LIST)
 
 ######################################################
 # JDK Image
@@ -905,8 +861,7 @@
 
 # Solaris 64 bit image is special
 initial-image-jdk-sol64:: initial-image-jdk-setup \
-			  initial-image-jdk64-bindemos \
-			  $(JDK_LICENSES) $(JDK64_LICENSES)
+			  initial-image-jdk64-bindemos
 
 # DB files to add
 ifdef OPENJDK
@@ -930,7 +885,7 @@
 # Standard jdk image
 initial-image-jdk:: initial-image-jdk-setup \
 		    initial-image-jdk-db \
-		    $(JDK_LICENSES) $(JDK_DOCFILES)
+		    $(JDK_DOCFILES)
 	$(MKDIR) $(JDK_IMAGE_DIR)/lib
 	@#
 	@# Copy in the jars in lib that only belong in the JDK
@@ -1089,14 +1044,18 @@
 trim-image-jdk::
 	@# Remove tools that should not be part of SDK.
 	for t in $(NOTJDKTOOLS); do \
-	    $(RM) $(JDK_IMAGE_DIR)/bin/$${t}$(EXE_SUFFIX) \
-		  $(JDK_IMAGE_DIR)/bin/*/native_threads/$${t}$(EXE_SUFFIX); \
+	    $(RM) $(JDK_IMAGE_DIR)/bin/$${t}$(EXE_SUFFIX); \
 	done
 
-# Get list of Elf files in the jdk
-JDK_ELF_LIST=$(TEMPDIR)/jdk-elf-files.list
-$(JDK_ELF_LIST):
-ifneq ($(PLATFORM), windows)
+# Get list of binary (COFF or Elf) files in the jdk
+JDK_BIN_LIST=$(TEMPDIR)/jdk-bin-files.list
+$(JDK_BIN_LIST):
+ifeq ($(PLATFORM), windows)
+	$(FIND) $(JDK_IMAGE_DIR)/jre/bin -type f -name \*.exe \
+	   -o -name \*.dll | $(EGREP) -v -i "$(MSVCRNN_DLL)" > $@
+	$(FIND) $(JDK_IMAGE_DIR)/bin -type f -name \*.exe \
+	   -o -name \*.dll | $(EGREP) -v -i "$(MSVCRNN_DLL)" >> $@
+else
 	$(RM) $@
 	$(FIND) $(JDK_IMAGE_DIR)/jre/lib -type f -name \*.$(LIB_SUFFIX) >> $@
 	$(FILE) `$(FIND) $(JDK_IMAGE_DIR)/jre/bin -type f -name \*$(EXE_SUFFIX)` \
@@ -1106,9 +1065,9 @@
 endif
 
 # Post process the image (strips and mcs on files we are shipping)
-process-image-jdk:: $(JDK_ELF_LIST)
+process-image-jdk:: $(JDK_BIN_LIST)
 ifneq ($(POST_STRIP_PROCESS), )
-	for f in `$(CAT) $(JDK_ELF_LIST)`; do \
+	@for f in `$(CAT) $(JDK_BIN_LIST)`; do \
 	  $(CHMOD) u+w $${f}; \
 	  $(ECHO) $(POST_STRIP_PROCESS) $${f}; \
 	  $(POST_STRIP_PROCESS) $${f}; \
@@ -1116,14 +1075,56 @@
 	done
 endif
 ifneq ($(POST_MCS_PROCESS), )
-	for f in `$(CAT) $(JDK_ELF_LIST)`; do \
+	@for f in `$(CAT) $(JDK_BIN_LIST)`; do \
 	  $(CHMOD) u+w $${f}; \
 	  $(ECHO) $(POST_MCS_PROCESS) $${f}; \
 	  $(POST_MCS_PROCESS) $${f}; \
 	  $(CHMOD) go-w $${f}; \
 	done
 endif
-	$(RM) $(JDK_ELF_LIST)
+	@for f in `$(CAT) $(JDK_BIN_LIST)`; do \
+	  $(call binary_file_verification,$${f}); \
+	done
+	$(RM) $(JDK_BIN_LIST)
+
+###################################################################
+# What did we build
+###################################################################
+
+# The jdk text info file that lives at the root of the install image.
+
+JDK_INFO_FILE = $(JDK_IMAGE_DIR)/release
+JRE_INFO_FILE = $(JRE_IMAGE_DIR)/release
+
+# Common way to emit a line into the release or info file
+define info-file-item # name value
+$(PRINTF) "%s=\"%s\"\n" $1 $2 >> $@
+endef
+
+# Values to emit
+MINIMUM_OS_NAME    := $(REQUIRED_OS_NAME)
+MINIMUM_OS_VERSION := $(REQUIRED_OS_VERSION)
+MINIMUM_OS_ARCH    := $(ARCH)
+
+$(JDK_INFO_FILE): FRC
+	$(prep-target)
+	$(call info-file-item, "JAVA_VERSION", "$(THIS_JDK_VERSION)")
+	$(call info-file-item, "OS_NAME",      "$(MINIMUM_OS_NAME)")
+	$(call info-file-item, "OS_VERSION",   "$(MINIMUM_OS_VERSION)")
+	$(call info-file-item, "OS_ARCH",      "$(MINIMUM_OS_ARCH)")
+
+# Create release file to identify this image
+identify-image-jdk:: $(JDK_INFO_FILE)
+
+$(JRE_INFO_FILE): FRC
+	$(prep-target)
+	$(call info-file-item, "JAVA_VERSION", "$(THIS_JDK_VERSION)")
+	$(call info-file-item, "OS_NAME",      "$(MINIMUM_OS_NAME)")
+	$(call info-file-item, "OS_VERSION",   "$(MINIMUM_OS_VERSION)")
+	$(call info-file-item, "OS_ARCH",      "$(MINIMUM_OS_ARCH)")
+
+# Create release file to identify this image
+identify-image-jre:: $(JRE_INFO_FILE)
 
 ###################################################################
 # What do we compare against
@@ -1278,6 +1279,7 @@
         initial-image-jre-setup \
 	trim-image-jre trim-image-jdk \
 	process-image-jre process-image-jdk \
+	identify-image-jre identify-image-jdk \
 	install-previous-jre install-previous-jdk \
 	compare-image-jre compare-image-jdk \
 	compare-image compare-image-clobber \
--- a/make/common/shared/Compiler-msvc.gmk	Thu Feb 10 21:36:18 2011 +0300
+++ b/make/common/shared/Compiler-msvc.gmk	Fri Feb 11 12:14:38 2011 -0800
@@ -35,6 +35,7 @@
   LIBEXE       = $(COMPILER_PATH)lib
   LINK         = $(COMPILER_PATH)link
   LINK32       = $(LINK)
+  DUMPBIN      = $(COMPILER_PATH)dumpbin.exe
  
   # Fill in unknown values
   COMPILER_NAME=Unknown MSVC Compiler
@@ -139,8 +140,8 @@
         _OTHER_TOOLS_BIN = $(WINDOWSSDKDIR)/Bin/x64
       endif
     endif
-    RC     = $(_OTHER_TOOLS_BIN)/rc.exe
-    REBASE = $(_OTHER_TOOLS_BIN)/rebase.exe
+    RC     = $(_OTHER_TOOLS_BIN)/RC.Exe
+    REBASE = $(_OTHER_TOOLS_BIN)/ReBase.Exe
     MT     = $(_OTHER_TOOLS_BIN)/mt.exe
     MTL    = $(_OTHER_TOOLS_BIN)/midl.exe
   endif
--- a/make/common/shared/Defs-control.gmk	Thu Feb 10 21:36:18 2011 +0300
+++ b/make/common/shared/Defs-control.gmk	Fri Feb 11 12:14:38 2011 -0800
@@ -76,12 +76,9 @@
 ABS_SRC_BUNDLEDIR   = $(ABS_OUTPUTDIR)/source-bundles
 BIN_BUNDLEDIR       = $(OUTPUTDIR)/bundles
 ABS_BIN_BUNDLEDIR   = $(ABS_OUTPUTDIR)/bundles
-JRL_BUNDLEDIR       = $(OUTPUTDIR)/java.net
-ABS_JRL_BUNDLEDIR   = $(ABS_OUTPUTDIR)/java.net
 
 dummy := $(shell $(MKDIR) -p $(BIN_BUNDLEDIR))
 dummy := $(shell $(MKDIR) -p $(SRC_BUNDLEDIR) )
-dummy := $(shell $(MKDIR) -p $(JRL_BUNDLEDIR) )
 
 TEMP_DIR = $(OUTPUTDIR)/tmp
 ABS_TEMP_DIR = $(ABS_OUTPUTDIR)/tmp
--- a/make/common/shared/Defs-linux.gmk	Thu Feb 10 21:36:18 2011 +0300
+++ b/make/common/shared/Defs-linux.gmk	Fri Feb 11 12:14:38 2011 -0800
@@ -177,3 +177,20 @@
 endif
 HOTSPOT_SERVER_PATH:=$(call AltCheckValue,HOTSPOT_SERVER_PATH)
 
+# Special define for checking the binaries
+
+# Macro to check it's input file for banned dependencies and verify the
+#   binary built properly. Relies on process exit code.
+define binary_file_verification # binary_file
+( \
+  $(ECHO) "Checking for mapfile use in: $1" && \
+  if [ "`$(NM) -D -g --defined-only $1 | $(EGREP) 'SUNWprivate'`" = "" ] ; then \
+    $(ECHO) "WARNING: File was not built with a mapfile: $1"; \
+  fi && \
+  $(ECHO) "Library loads for: $1" && \
+  $(LDD) $1 && \
+  $(ECHO) "RUNPATH for: $1" && \
+  ( $(READELF) -d $1 | $(EGREP) 'NEEDED|RUNPATH|RPATH' ) \
+)
+endef
+
--- a/make/common/shared/Defs-solaris.gmk	Thu Feb 10 21:36:18 2011 +0300
+++ b/make/common/shared/Defs-solaris.gmk	Fri Feb 11 12:14:38 2011 -0800
@@ -186,3 +186,20 @@
 endif
 HOTSPOT_SERVER_PATH:=$(call AltCheckValue,HOTSPOT_SERVER_PATH)
 
+# Special define for checking the binaries
+
+# Macro to check it's input file for banned dependencies and verify the
+#   binary built properly. Relies on process exit code.
+define binary_file_verification # binary_file
+( \
+  $(ECHO) "Checking for mapfile use in: $1" && \
+  if [ "`$(NM) -g -D $1 | $(EGREP) -v 'UNDEF' | $(EGREP) 'SUNWprivate'`" = "" ] ; then \
+    $(ECHO) "WARNING: File was not built with a mapfile: $1"; \
+  fi && \
+  $(ECHO) "Library loads for: $1" && \
+  $(LDD) $1 && \
+  $(ECHO) "RUNPATH for: $1" && \
+  ( $(DUMP) -L -v $1 | $(EGREP) 'NEEDED|RUNPATH|RPATH' ) \
+)
+endef
+
--- a/make/common/shared/Defs-utils.gmk	Thu Feb 10 21:36:18 2011 +0300
+++ b/make/common/shared/Defs-utils.gmk	Fri Feb 11 12:14:38 2011 -0800
@@ -85,6 +85,7 @@
 DF             = $(UTILS_COMMAND_PATH)df
 DIFF           = $(UTILS_USR_BIN_PATH)diff
 DIRNAME        = $(UTILS_USR_BIN_PATH)dirname
+DUMP           = $(UTILS_CCS_BIN_PATH)dump
 ECHO           = $(UTILS_COMMAND_PATH)echo
 EGREP          = $(UTILS_COMMAND_PATH)egrep
 EXPR           = $(UTILS_USR_BIN_PATH)expr
@@ -99,6 +100,7 @@
 ISAINFO        = $(UTILS_COMMAND_PATH)isainfo
 KSH            = $(UTILS_COMMAND_PATH)ksh
 LD             = $(UTILS_CCS_BIN_PATH)ld
+LDD            = $(UTILS_USR_BIN_PATH)ldd
 LEX            = $(UTILS_CCS_BIN_PATH)lex
 LN             = $(UTILS_COMMAND_PATH)ln
 LS             = $(UTILS_COMMAND_PATH)ls
@@ -114,6 +116,7 @@
 PRINTF         = $(UTILS_USR_BIN_PATH)printf
 PWD            = $(UTILS_COMMAND_PATH)pwd
 RC             = $(UTILS_COMMAND_PATH)rc
+READELF        = $(UTILS_USR_BIN_PATH)readelf
 RMDIR          = $(UTILS_COMMAND_PATH)rmdir
 RPM            = $(UTILS_COMMAND_PATH)rpm
 RPMBUILD       = $(UTILS_COMMAND_PATH)rpmbuild
--- a/make/common/shared/Defs-versions.gmk	Thu Feb 10 21:36:18 2011 +0300
+++ b/make/common/shared/Defs-versions.gmk	Fri Feb 11 12:14:38 2011 -0800
@@ -127,6 +127,7 @@
 
 # Solaris specific
 ifeq ($(PLATFORM), solaris)
+  REQUIRED_OS_NAME            = SunOS
   REQUIRED_OS_VERSION         = 5.10
   REQUIRED_OS_VARIANT_NAME    = Solaris
   REQUIRED_OS_VARIANT_VERSION = $(REQUIRED_OS_VERSION)
@@ -148,6 +149,7 @@
 
 # Linux specific
 ifeq ($(PLATFORM), linux)
+  REQUIRED_OS_NAME            = Linux
   REQUIRED_OS_VERSION         = 2.6
   REQUIRED_OS_VARIANT_NAME    = Fedora
   REQUIRED_OS_VARIANT_VERSION = 9
@@ -166,6 +168,7 @@
 
 # Windows specific
 ifeq ($(PLATFORM), windows)
+  REQUIRED_OS_NAME            = Windows
   ifeq ($(ARCH_DATA_MODEL),64)
     REQUIRED_OS_VERSION       = 5.2
     REQUIRED_OS_VARIANT_NAME  = Windows2003
@@ -205,7 +208,7 @@
 endif
 
 # Generic
-REQUIRED_ANT_VER          = 1.6.3
+REQUIRED_ANT_VER          = 1.7.1
 REQUIRED_BOOT_VER         = 1.6
 REQUIRED_FREETYPE_VERSION = 2.3.0
 REQUIRED_MAKE_VER         = 3.81
--- a/make/common/shared/Defs-windows.gmk	Thu Feb 10 21:36:18 2011 +0300
+++ b/make/common/shared/Defs-windows.gmk	Fri Feb 11 12:14:38 2011 -0800
@@ -288,8 +288,8 @@
     xVS100COMNTOOLS :="$(_program_files32)/Microsoft Visual Studio 10.0/Common7/Tools/"
     fVS100COMNTOOLS :=$(call FullPath,$(xVS100COMNTOOLS))
   else
+    xVS100COMNTOOLS :="$(subst \,/,$(VS100COMNTOOLS))"
     ifneq ($(word 2,$(VS100COMNTOOLS)),)
-      xVS100COMNTOOLS :="$(subst \,/,$(VS100COMNTOOLS))"
       fVS100COMNTOOLS :=$(call FullPath,$(xVS100COMNTOOLS))
     else
       fVS100COMNTOOLS :=$(xVS100COMNTOOLS)
@@ -551,18 +551,6 @@
   _BOOTDIR3  =$(SLASH_JAVA)/re/jdk/$(PREVIOUS_JDK_VERSION)/archive/fcs/binaries/$(PLATFORM)-$(ARCH)
 endif
 
-# 32 bit always needs 2 runtimes, 64 bit usually does too
-
-# MSVCRT_DLL_PATH: location of msvcrt.dll that will be re-distributed
-ifdef ALT_MSVCRT_DLL_PATH
-  xALT_MSVCRT_DLL_PATH :="$(subst \,/,$(ALT_MSVCRT_DLL_PATH))"
-  MSVCRT_DLL_PATH      :=$(call FullPath,$(xALT_MSVCRT_DLL_PATH))
-else
-  MSVCRT_DLL_PATH :=$(call FullPath,$(_system_root)/system32/)
-endif
-MSVCRT_DLL_PATH:=$(call AltCheckSpaces,MSVCRT_DLL_PATH)
-MSVCRT_DLL_PATH:=$(call AltCheckValue,MSVCRT_DLL_PATH)
-
 # 32bit always needs the MSVCRNN runtime, 64bit does when using VS2008
 ifeq ($(ARCH_DATA_MODEL), 32)
   _NEEDS_MSVCRNN = true
@@ -641,15 +629,6 @@
 endif
 INSTALL_MSSDK:=$(call AltCheckSpaces,INSTALL_MSSDK)
 
-# INSTALL_MSIVAL2: Installation of MsiVal2 for this platform (for install)
-ifdef ALT_INSTALL_MSIVAL2
-  xALT_INSTALL_MSIVAL2 :="$(subst \,/,$(ALT_INSTALL_MSIVAL2))"
-  INSTALL_MSIVAL2      :=$(call FullPath,$(xALT_INSTALL_MSIVAL2))
-else
-  INSTALL_MSIVAL2      :=$(_program_files32)/MsiVal2
-endif
-INSTALL_MSIVAL2:=$(call AltCheckSpaces,INSTALL_MSIVAL2)
-
 # WSCRIPT: path to wscript.exe (used in creating install bundles)
 ifdef ALT_WSCRIPT
   xALT_WSCRIPT :="$(subst \,/,$(ALT_WSCRIPT))"
@@ -685,43 +664,6 @@
 endif
 CABARC:=$(call AltCheckSpaces,CABARC)
 
-# MSIVAL2: path to msival2.exe (used in validating install msi files)
-ifdef ALT_MSIVAL2
-  xALT_MSIVAL2 :="$(subst \,/,$(ALT_MSIVAL2))"
-  MSIVAL2  =$(xALT_MSIVAL2)
-else
-  _MSIVAL2_1 :=$(INSTALL_MSIVAL2)/msival2.exe
-  _MSIVAL2_2 :=$(DEVTOOLS_PATH)msival2.exe
-  MSIVAL2    :=$(call FileExists,$(_MSIVAL2_1),$(_MSIVAL2_2))
-endif
-MSIVAL2:=$(call AltCheckSpaces,MSIVAL2)
-# suppress msival2 checks, as it hangs jprt builds
-ifdef SKIP_MSIVAL2
-  MSIVAL2    := $(ECHO)
-endif
-
-# LOGOCUB: path to cub file for (used in validating install msi files)
-ifdef ALT_LOGOCUB
-  xALT_LOGOCUB :="$(subst \,/,$(ALT_LOGOCUB))"
-  LOGOCUB  =$(xALT_LOGOCUB)
-else
-  _LOGOCUB1 :=$(INSTALL_MSIVAL2)/logo.cub
-  _LOGOCUB2 :=$(DEVTOOLS_PATH)logo.cub
-  LOGOCUB   :=$(call FileExists,$(_LOGOCUB1),$(_LOGOCUB2))
-endif
-LOGOCUB:=$(call AltCheckSpaces,LOGOCUB)
-
-# MSITRAN: path to msitran.exe (used in creating install bundles and sponsors)
-ifdef ALT_MSITRAN
-  xALT_MSITRAN :="$(subst \,/,$(ALT_MSITRAN))"
-  MSITRAN  =$(xALT_MSITRAN)
-else
-  _MSITRAN1 :=$(INSTALL_MSSDK)/Bin/msitran.exe
-  _MSITRAN2 :=$(DEVTOOLS_PATH)msitran.exe
-  MSITRAN   :=$(call FileExists,$(_MSITRAN1),$(_MSITRAN2))
-endif
-MSITRAN:=$(call AltCheckSpaces,MSITRAN)
-
 # MSICERT: path to msicert.exe (used in creating install bundles)
 ifdef ALT_MSICERT
   xALT_MSICERT :="$(subst \,/,$(ALT_MSICERT))"
@@ -798,3 +740,50 @@
 endif
 HOTSPOT_LIB_PATH:=$(call AltCheckSpaces,HOTSPOT_LIB_PATH)
 HOTSPOT_LIB_PATH:=$(call AltCheckValue,HOTSPOT_LIB_PATH)
+
+# Special define for checking the binaries
+
+ifeq ($(VS2010_EXISTS),true)
+
+# All windows dll and exe files should have been built with /NXCOMPAT
+#   and be setup for dynamic base addresses.
+#   In addition, we should not be dependent on certain dll files that
+#   we do not or cannot redistribute.
+
+# List of filenames we should NOT be dependent on
+BANNED_DLLS=msvcp100[.]dll|msvcr100d[.]dll|msvcrtd[.]dll
+
+# Macro to check it's input file for banned dependencies and verify the
+#   binary was built properly. Relies on process exit code.
+define binary_file_verification # binary_file
+( \
+  $(ECHO) "Checking for /NXCOMPAT usage in: $1" && \
+  if [ "`$(DUMPBIN) /headers $1 | $(EGREP) -i 'NX compatible'`" = "" ] ; then \
+    $(ECHO) "ERROR: Did not find 'NX compatible' in headers: $1" ; \
+    $(DUMPBIN) /headers $1 ; \
+    exit 7 ; \
+  fi ; \
+  $(ECHO) "Checking for /DYNAMICBASE usage in: $1" && \
+  if [ "`$(DUMPBIN) /headers $1 | $(EGREP) -i 'Dynamic base'`" = "" ] ; then \
+    $(ECHO) "ERROR: Did not find 'Dynamic base' in headers: $1" ; \
+    $(DUMPBIN) /headers $1 ; \
+    exit 8 ; \
+  fi ; \
+  $(ECHO) "Checking for banned dependencies in: $1" && \
+  if [ "`$(DUMPBIN) /dependents $1 | $(EGREP) -i '$(BANNED_DLLS)'`" != "" ] ; then \
+    $(ECHO) "ERROR: Found us of $(BANNED_DLLS)"; \
+    $(DUMPBIN) /dependents $1 ; \
+    exit 9 ; \
+  fi ; \
+)
+endef
+
+else
+
+# Macro to check it's input file for banned dependencies and verify the
+#   binary was built properly. Relies on process exit code.
+define binary_file_verification # binary_file
+endef
+
+endif
+
--- a/make/common/shared/Sanity-Settings.gmk	Thu Feb 10 21:36:18 2011 +0300
+++ b/make/common/shared/Sanity-Settings.gmk	Fri Feb 11 12:14:38 2011 -0800
@@ -96,7 +96,6 @@
   endif
 endif
 ifeq ($(PLATFORM),windows)
-  ALL_SETTINGS+=$(call addAltSetting,MSVCRT_DLL_PATH)
   ifneq ($(MSVCRNN_DLL),)
     ALL_SETTINGS+=$(call addAltSetting,MSVCRNN_DLL_PATH)
   endif
@@ -117,6 +116,9 @@
 ALL_SETTINGS+=$(call addRequiredVersionSetting,UNZIP_VER)
 ifeq ($(PLATFORM),windows)
   ALL_SETTINGS+=$(call addRequiredVersionSetting,LINK_VER)
+  ALL_SETTINGS+=$(call addRequiredSetting,CC)
+  ALL_SETTINGS+=$(call addRequiredSetting,LINK)
+  ALL_SETTINGS+=$(call addRequiredSetting,DUMPBIN)
 endif
 ALL_SETTINGS+=$(call addRequiredVersionSetting,ANT_VER)
 ALL_SETTINGS+=$(call addRequiredSetting,TEMPDIR)
@@ -226,13 +228,13 @@
   ALL_SETTINGS+=$(call addAltSetting,DXSDK_INCLUDE_PATH)
   ALL_SETTINGS+=$(call addAltSetting,DXSDK_LIB_PATH)
   ALL_SETTINGS+=$(call addAltSetting,WINDOWSSDKDIR)
+  ALL_SETTINGS+=$(call addRequiredSetting,RC)
+  ALL_SETTINGS+=$(call addRequiredSetting,REBASE)
   ifndef OPENJDK
     ALL_SETTINGS+=$(call addAltSetting,DEPLOY_MSSDK)
     ALL_SETTINGS+=$(call addAltSetting,INSTALL_MSSDK)
     ALL_SETTINGS+=$(call addAltSetting,WSCRIPT)
     ALL_SETTINGS+=$(call addAltSetting,MSICERT)
-    ALL_SETTINGS+=$(call addAltSetting,MSITRAN)
-    ALL_SETTINGS+=$(call addAltSetting,MSIVAL2)
   endif
 endif
 ALL_SETTINGS+=$(call addAltSetting,CACERTS_FILE)
--- a/make/common/shared/Sanity.gmk	Thu Feb 10 21:36:18 2011 +0300
+++ b/make/common/shared/Sanity.gmk	Fri Feb 11 12:14:38 2011 -0800
@@ -255,10 +255,10 @@
 MAKE_CHECK :=$(call CheckVersions,$(MAKE_VER),$(REQUIRED_MAKE_VER))
 sane-make:
 	@if [ "$(MAKE_CHECK)" != "same" -a "$(MAKE_CHECK)" != "newer" ]; then \
-	  $(ECHO) "WARNING: The version of make being used is older than \n" \
+	  $(ECHO) "ERROR: The version of make being used is older than \n" \
 	    "      the required version of '$(REQUIRED_MAKE_VER)'. \n" \
 	    "      The version of make found was '$(MAKE_VER)'. \n" \
-	    "" >> $(WARNING_FILE) ; \
+	    "" >> $(ERROR_FILE) ; \
 	fi
 
 ######################################################
@@ -879,13 +879,6 @@
 ######################################################
 sane-msvcrt_path:
 ifeq ($(PLATFORM), windows)
-	@if [ ! -r "$(MSVCRT_DLL_PATH)/msvcrt.dll" ]; then \
-	  $(ECHO) "ERROR: You do not have access to msvcrt.dll. \n" \
-	    "      Please check your access to \n" \
-	    "          $(MSVCRT_DLL_PATH) \n" \
-	    "      and/or check your value of ALT_MSVCRT_DLL_PATH. \n" \
-	    "" >> $(ERROR_FILE) ; \
-	fi
   ifneq ($(MSVCRNN_DLL),)
 	@if [ ! -r "$(MSVCRNN_DLL_PATH)/$(MSVCRNN_DLL)" ]; then \
 	  $(ECHO) "ERROR: You do not have access to $(MSVCRNN_DLL). \n" \
@@ -1018,6 +1011,22 @@
 	    "      and/or check your value of ALT_MSDEVTOOLS_PATH. \n" \
 	    "" >> $(ERROR_FILE) ; \
 	fi
+  else
+    ifeq ($(wildcard $(REBASE)),)
+	@$(ECHO) "ERROR: Cannot find the REBASE utility from path: $(REBASE)\n" \
+	    "      This is normally obtained from the WINDOWSSDKDIR." \
+	    "" >> $(ERROR_FILE)
+    endif
+    ifeq ($(wildcard $(RC)),)
+	@$(ECHO) "ERROR: Cannot find the RC utility from path: $(RC)\n" \
+	    "      This is normally obtained from the WINDOWSSDKDIR." \
+	    "" >> $(ERROR_FILE)
+    endif
+    ifeq ($(wildcard $(DUMPBIN)),)
+	@$(ECHO) "ERROR: Cannot find the DUMPBIN utility from path: $(DUMPBIN)\n" \
+	    "      This is normally obtained from the WINDOWSSDKDIR." \
+	    "" >> $(ERROR_FILE)
+    endif
   endif
 endif
 
@@ -1250,10 +1259,10 @@
 sane-ant_version:
 	@if [ "$(ANT_CHECK)" != "same" \
 	      -a "$(ANT_CHECK)" != "newer" ]; then \
-	  $(ECHO) "WARNING: The version of ant being used is older than \n" \
+	  $(ECHO) "ERROR: The version of ant being used is older than \n" \
 	    "      the required version of '$(REQUIRED_ANT_VER)'. \n" \
 	    "      The version of ant found was '$(ANT_VER)'. \n" \
-	    "" >> $(WARNING_FILE) ; \
+	    "" >> $(ERROR_FILE) ; \
 	fi
 
 ######################################################
@@ -1460,25 +1469,6 @@
 endif
 
 ######################################################
-# Check for existence of INSTALL_MSIVAL2 on windows
-######################################################
-sane-install-msival2_path:
-ifeq ($(PLATFORM), windows)
-	@if [ -z "$(INSTALL_MSIVAL2)" ]; then \
-	  $(ECHO) "WARNING: Your INSTALL_MSIVAL2 setting is empty.\n" \
-	    "        It is recommended to set ALT_INSTALL_MSIVAL2.\n" \
-	    "" >> $(WARNING_FILE) ; \
-	fi
-	@if [ ! -r "$(INSTALL_MSIVAL2)" ]; then \
-	  $(ECHO) "ERROR: You do not have a valid INSTALL_MSIVAL2 setting. \n" \
-	    "      Please check your access to \n" \
-	    "          $(INSTALL_MSIVAL2) \n" \
-	    "      and/or check your value of ALT_INSTALL_MSIVAL2. \n" \
-	    "" >> $(ERROR_FILE) ; \
-	fi
-endif
-
-######################################################
 # Check the GNU C++ compiler for OJI plugin
 ######################################################
 sane-gcc-compiler:
--- a/make/java/Makefile	Thu Feb 10 21:36:18 2011 +0300
+++ b/make/java/Makefile	Fri Feb 11 12:14:38 2011 -0800
@@ -34,7 +34,7 @@
 #
 # The order of subdirs here is important
 #
-SUBDIRS += hpi version jvm redist verify fdlibm java sun_nio jli main zip
+SUBDIRS += version jvm redist verify fdlibm java sun_nio jli main zip
 
 # Others
 #    Note: java_crw_demo java_hprof_demo are demos but must be delivered built in sdk
--- a/make/java/fdlibm/Makefile	Thu Feb 10 21:36:18 2011 +0300
+++ b/make/java/fdlibm/Makefile	Fri Feb 11 12:14:38 2011 -0800
@@ -24,7 +24,7 @@
 #
 
 #
-# Makefile for native threads HPI.
+# Makefile for fdlibm
 #
 # Note:
 # The fdlibm libraries are built using special rules in Library.gmk.
--- a/make/java/hpi/Makefile	Thu Feb 10 21:36:18 2011 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +0,0 @@
-#
-# Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute 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.
-#
-
-#
-# Build HPI (Host Porting Interface) libraries
-#
-
-BUILDDIR = ../..
-include $(BUILDDIR)/common/Defs.gmk
-
-#
-# Build specified the HPI implementations
-#
-SUBDIRS = $(HPIS)
-include $(BUILDDIR)/common/Subdirs.gmk
-
-all build clean clobber::
-	$(SUBDIRS-loop)
-
--- a/make/java/hpi/hpi_common.gmk	Thu Feb 10 21:36:18 2011 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,90 +0,0 @@
-#
-# Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute 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.
-#
-
-#
-# Shared files between the different threads types on Solaris. Be
-# careful when including this, you must get your variables right.
-#
-
-#
-# Common files on Solaris.
-#
-ifneq ($(PLATFORM), windows)
-FILES_c += \
-    interrupt.c \
-    linker_md.c \
-    memory_md.c \
-    system_md.c \
-    hpi.c
-endif
-
-#
-# Include paths can also be shared.
-#
-ifneq ($(PLATFORM), windows)
-OTHER_INCLUDES += \
-    -I$(PLATFORM_SRC)/hpi/$(THREADDIR)/include \
-    -I$(PLATFORM_SRC)/hpi/include \
-    -I$(PLATFORM_SRC)/hpi/export \
-    -I$(SHARE_SRC)/hpi/include \
-    -I$(SHARE_SRC)/hpi/export
-else
-OTHER_INCLUDES += \
-    -I$(PLATFORM_SRC)/hpi/include \
-    -I$(PLATFORM_SRC)/hpi/export \
-    -I$(SHARE_SRC)/hpi/include \
-    -I$(SHARE_SRC)/hpi/export
-endif
-
-#
-# Add to the default C and assembly file search paths.  Clear any initial
-# vpath settings to ensure that we don't look in unexpected places for HPI
-# files.
-#
-vpath %.c
-vpath %.c   $(PLATFORM_SRC)/hpi/$(THREADDIR)/src
-vpath %.c   $(PLATFORM_SRC)/hpi/src
-vpath %.c   $(SHARE_SRC)/hpi/src
-
-vpath %.s
-vpath %.s   $(PLATFORM_SRC)/hpi/$(THREADDIR)/src
-vpath %.s   $(PLATFORM_SRC)/hpi/src
-
-#
-# By default leave out locking statistics
-#
-ifneq ($(PLATFORM), windows)
-LOCKSTATS = false
-ifeq ($(LOCKSTATS), true)
-    CFLAGS_COMMON += -DLOCKSTATS
-endif
-endif
-
-#
-# Things that must be linked in.
-#
-ifneq ($(PLATFORM), windows)
-OTHER_LDLIBS += $(LIBSOCKET) $(LIBNSL) $(LIBM) -ldl
-endif
--- a/make/java/hpi/native/Makefile	Thu Feb 10 21:36:18 2011 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,93 +0,0 @@
-#
-# Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute 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.
-#
-
-#
-# Makefile for native threads HPI.
-#
-
-BUILDDIR     = ../../..
-MODULE       = base
-LIBRARY      = hpi
-PRODUCT      = java
-THREADDIR    = native_threads
-LIB_LOCATION = $(LIBDIR)/$(LIBARCH)/$(THREADDIR)
-include $(BUILDDIR)/common/Defs.gmk
-
-#
-# Native threads specific C and .s files.
-#
-FILES_c = \
-	monitor_md.c \
-	threads_md.c \
-	condvar_md.c \
-	interrupt_md.c \
-	mutex_md.c \
-	sys_api_td.c \
-	threads_$(PLATFORM).c
-
-#
-# Other files/flags shared between the HPIs.
-#
-include $(BUILDDIR)/java/hpi/hpi_common.gmk
-
-#
-# Rules for the .so file.
-#
-ifeq ($(PLATFORM), solaris)
-  ifneq ($(ARCH), amd64)
-    FILES_reorder += reorder-$(ARCH)
-  endif
-endif
-include $(BUILDDIR)/common/Mapfile-vers.gmk
-include $(BUILDDIR)/common/Library.gmk
-
-#
-# HPI flags for native threads.
-#
-OTHER_CPPFLAGS += -D_REENTRANT -DNATIVE
-
-ifeq ($(USE_PTHREADS),true)
-OTHER_CPPFLAGS += -DUSE_PTHREADS
-ifeq ($(MOOT_PRIORITIES),true)
-OTHER_CPPFLAGS += -DMOOT_PRIORITIES
-endif
-LIBPOSIX4	= -lposix4
-OTHER_LDLIBS   += -lpthread $(LIBPOSIX4)
-endif
-
-HAVE_GETHRVTIME=true
-ifeq ($(HAVE_GETHRVTIME),true)
-OTHER_CPPFLAGS += -DHAVE_GETHRVTIME
-endif
-
-HAVE_FILIOH=true
-ifeq ($(HAVE_FILIOH),true)
-OTHER_CPPFLAGS += -DHAVE_FILIOH
-endif
-
-ifeq ($(NO_INTERRUPTIBLE_IO),true)
-OTHER_CPPFLAGS += -DNO_INTERRUPTIBLE_IO
-endif
-
--- a/make/java/hpi/native/mapfile-vers	Thu Feb 10 21:36:18 2011 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-#
-# Copyright (c) 2000, 2002, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute 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.
-#
-
-SUNWprivate_1.1 {
-   global:
-		DLL_Initialize;
-
-   local:
-           *;
-};
--- a/make/java/hpi/native/reorder-i586	Thu Feb 10 21:36:18 2011 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-data = R0x2000;
-text = LOAD ?RXO;
-# Test Null
-text: .text%_init;
-text: .text%checkForCorrectLibthread: OUTPUTDIR/tmp/java/hpi/native_threads/obj/threads_solaris.o;
-text: .text%init64IO: OUTPUTDIR/tmp/java/hpi/native_threads/obj/system_md.o;
-text: .text%DLL_Initialize;
-text: .text%GetInterface: OUTPUTDIR/tmp/java/hpi/native_threads/obj/hpi.o;
-text: .text%sysBuildLibName;
-text: .text%sysLoadLibrary;
-text: .text%sysFindLibraryEntry;
-text: .text%sysNativePath;
-text: .text%sysOpen;
-text: .text%sysSeek;
-text: .text%lseek64_w;
-# Test Exit
-# Test Hello
-# Test Sleep
-# Test IntToString
-# Test LoadToolkit
-text: .text%sysAvailable;
-text: .text%sysFfileMode;
-text: .text%sysGetLastErrorString;
-# Test LoadFrame
-# Test LoadJFrame
-# Test JHello
-# SwingSet
--- a/make/java/hpi/native/reorder-sparc	Thu Feb 10 21:36:18 2011 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-data = R0x2000;
-text = LOAD ?RXO;
-# Test Null
-text: .text%checkForCorrectLibthread: OUTPUTDIR/tmp/java/hpi/native_threads/obj/threads_solaris.o;
-text: .text%init64IO: OUTPUTDIR/tmp/java/hpi/native_threads/obj/system_md.o;
-text: .text%DLL_Initialize;
-text: .text%GetInterface: OUTPUTDIR/tmp/java/hpi/native_threads/obj/hpi.o;
-text: .text%sysBuildLibName;
-text: .text%sysLoadLibrary;
-text: .text%sysFindLibraryEntry;
-text: .text%sysNativePath;
-text: .text%sysOpen;
-text: .text%sysFfileMode;
-text: .text%sysSeek;
-text: .text%lseek64_w;
-text: .text%sysAvailable;
-# Test Exit
-# Test Hello
-# Test Sleep
-# Test IntToString
-# Test LoadToolkit
-text: .text%sysGetLastErrorString;
-# Test LoadFrame
-# Test LoadJFrame
-# Test JHello
-# SwingSet
--- a/make/java/hpi/native/reorder-sparcv9	Thu Feb 10 21:36:18 2011 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-data = R0x2000;
-text = LOAD ?RXO;
-# Test Null
-text: .text%checkForCorrectLibthread: OUTPUTDIR/tmp/java/hpi/native_threads/obj64/threads_solaris.o;
-text: .text%init64IO: OUTPUTDIR/tmp/java/hpi/native_threads/obj64/system_md.o;
-text: .text%DLL_Initialize;
-text: .text%GetInterface: OUTPUTDIR/tmp/java/hpi/native_threads/obj64/hpi.o;
-text: .text%sysBuildLibName;
-text: .text%sysLoadLibrary;
-text: .text%sysFindLibraryEntry;
-text: .text%sysNativePath;
-text: .text%sysOpen;
-text: .text%sysFfileMode;
-text: .text%sysSeek;
-text: .text%lseek64_w;
-text: .text%sysAvailable;
-# Test Exit
-# Test Hello
-# Test Sleep
-# Test IntToString
-# Test LoadToolkit
-text: .text%sysGetLastErrorString;
-# Test LoadFrame
-# Test LoadJFrame
-# Test JHello
-# SwingSet
--- a/make/java/hpi/windows/Makefile	Thu Feb 10 21:36:18 2011 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-#
-# Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute 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.
-#
-
-#
-# Makefile for Windows HPI DLL
-#
-BUILDDIR     = ../../..
-MODULE       = base
-LIBRARY      = hpi
-PRODUCT      = java
-THREADDIR    = windows_threads
-LIB_LOCATION = $(BINDIR)
-
-include $(BUILDDIR)/common/Defs.gmk
-
-# windows compiler flags
-ifeq ($(PLATFORM),windows)
-  CPPFLAGS_DBG += -DLOGGING
-endif
-
-FILES_c = \
-    linker_md.c \
-    memory_md.c \
-    monitor_md.c \
-    path_md.c \
-    socket_md.c \
-    sys_api_md.c \
-    system_md.c \
-    threads_md.c \
-    hpi.c # trailing blank required!
-
-JVMLIB = 
-JAVALIB =
-OTHER_LCF = -export:DLL_Initialize
-EXTRA_LIBS =
-
-
-#
-# Other files/flags shared between the HPIs.
-#
-include $(BUILDDIR)/java/hpi/hpi_common.gmk
-
-#
-# Rules for the .so file.
-#
-include $(BUILDDIR)/common/Library.gmk
-
--- a/make/java/management/mapfile-vers	Thu Feb 10 21:36:18 2011 +0300
+++ b/make/java/management/mapfile-vers	Fri Feb 11 12:14:38 2011 -0800
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2005, 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
@@ -70,14 +70,18 @@
 	    Java_sun_management_ThreadImpl_dumpThreads0;
 	    Java_sun_management_ThreadImpl_findDeadlockedThreads0;
 	    Java_sun_management_ThreadImpl_findMonitorDeadlockedThreads0;
-	    Java_sun_management_ThreadImpl_getThreadInfo0;
+	    Java_sun_management_ThreadImpl_getThreadInfo1;
 	    Java_sun_management_ThreadImpl_getThreads;
 	    Java_sun_management_ThreadImpl_getThreadTotalCpuTime0;
+	    Java_sun_management_ThreadImpl_getThreadTotalCpuTime1;
 	    Java_sun_management_ThreadImpl_getThreadUserCpuTime0;
+	    Java_sun_management_ThreadImpl_getThreadUserCpuTime1;
+	    Java_sun_management_ThreadImpl_getThreadAllocatedMemory1;
 	    Java_sun_management_ThreadImpl_resetContentionTimes0;
 	    Java_sun_management_ThreadImpl_resetPeakThreadCount0;
 	    Java_sun_management_ThreadImpl_setThreadContentionMonitoringEnabled0;
 	    Java_sun_management_ThreadImpl_setThreadCpuTimeEnabled0;
+	    Java_sun_management_ThreadImpl_setThreadAllocatedMemoryEnabled0;
 	    Java_sun_management_VMManagementImpl_getAvailableProcessors;
 	    Java_sun_management_VMManagementImpl_getClassInitializationTime;
 	    Java_sun_management_VMManagementImpl_getClassLoadingTime;
@@ -106,6 +110,7 @@
 	    Java_sun_management_VMManagementImpl_initOptionalSupportFields;
 	    Java_sun_management_VMManagementImpl_isThreadContentionMonitoringEnabled;
 	    Java_sun_management_VMManagementImpl_isThreadCpuTimeEnabled;
+	    Java_sun_management_VMManagementImpl_isThreadAllocatedMemoryEnabled;
             JNI_OnLoad;
 	local:
 	    *;
--- a/make/java/nio/Makefile	Thu Feb 10 21:36:18 2011 +0300
+++ b/make/java/nio/Makefile	Fri Feb 11 12:14:38 2011 -0800
@@ -296,7 +296,7 @@
 OTHER_LDLIBS += -L$(LIBDIR)/$(LIBARCH) -ljava -lnet -lpthread -ldl
 endif
 ifeq ($(PLATFORM), solaris)
-OTHER_LDLIBS += $(JVMLIB) $(LIBSOCKET) -lposix4 -ldl \
+OTHER_LDLIBS += $(JVMLIB) $(LIBSOCKET) -lposix4 -ldl -lsendfile \
 		-L$(LIBDIR)/$(LIBARCH) -ljava -lnet
 endif # PLATFORM
 
--- a/make/java/redist/Makefile	Thu Feb 10 21:36:18 2011 +0300
+++ b/make/java/redist/Makefile	Fri Feb 11 12:14:38 2011 -0800
@@ -93,10 +93,6 @@
 
 IMPORT_LIST += $(MS_RUNTIME_LIBRARIES:%=$(BINDIR)/%)
 
-# NOTE: These might actually come from BUILDDIR, depends on the settings.
-$(BINDIR)/msvcrt.dll: $(MSVCRT_DLL_PATH)/msvcrt.dll
-	$(install-import-file)
-	$(call chmod-file, a+x)
 $(BINDIR)/$(MSVCRNN_DLL): $(MSVCRNN_DLL_PATH)/$(MSVCRNN_DLL)
 	$(install-import-file)
 	$(call chmod-file, a+x)
@@ -223,12 +219,15 @@
 
 $(LIB_LOCATION)/$(CLIENT_LOCATION)/$(JVM_NAME): $(HOTSPOT_CLIENT_PATH)/$(JVM_NAME)
 	$(install-import-file)
+	@$(call binary_file_verification,$@)
 
 $(LIB_LOCATION)/$(KERNEL_LOCATION)/$(JVM_NAME): $(HOTSPOT_KERNEL_PATH)/$(JVM_NAME)
 	$(install-file)
+	@$(call binary_file_verification,$@)
 
 $(LIB_LOCATION)/$(LIBJSIG_NAME): $(HOTSPOT_IMPORT_PATH)/$(ARCH_VM_SUBDIR)/$(LIBJSIG_NAME)
 	$(install-import-file)
+	@$(call binary_file_verification,$@)
 
 $(LIB_LOCATION)/$(CLIENT_LOCATION)/$(LIBJSIG_NAME) \
 $(LIB_LOCATION)/$(SERVER_LOCATION)/$(LIBJSIG_NAME):
@@ -237,30 +236,39 @@
 
 $(LIB_LOCATION)/$(CLIENT_LOCATION)/$(JVMDB_NAME): $(HOTSPOT_CLIENT_PATH)/$(JVMDB_NAME)
 	$(install-import-file)
+	@$(call binary_file_verification,$@)
 
 $(LIB_LOCATION)/$(CLIENT_LOCATION)/64/$(JVMDB_NAME): $(HOTSPOT_CLIENT_PATH)/64/$(JVMDB_NAME)
 	$(install-import-file)
+	@$(call binary_file_verification,$@)
 
 $(LIB_LOCATION)/$(SERVER_LOCATION)/$(JVMDB_NAME): $(HOTSPOT_SERVER_PATH)/$(JVMDB_NAME)
 	$(install-import-file)
+	@$(call binary_file_verification,$@)
 
 $(LIB_LOCATION)/$(SERVER_LOCATION)/64/$(JVMDB_NAME): $(HOTSPOT_SERVER_PATH)/64/$(JVMDB_NAME)
 	$(install-import-file)
+	@$(call binary_file_verification,$@)
 
 $(LIB_LOCATION)/$(CLIENT_LOCATION)/$(JVMDTRACE_NAME): $(HOTSPOT_CLIENT_PATH)/$(JVMDTRACE_NAME)
 	$(install-import-file)
+	@$(call binary_file_verification,$@)
 
 $(LIB_LOCATION)/$(CLIENT_LOCATION)/64/$(JVMDTRACE_NAME): $(HOTSPOT_CLIENT_PATH)/64/$(JVMDTRACE_NAME)
 	$(install-import-file)
+	@$(call binary_file_verification,$@)
 
 $(LIB_LOCATION)/$(SERVER_LOCATION)/$(JVMDTRACE_NAME): $(HOTSPOT_SERVER_PATH)/$(JVMDTRACE_NAME)
 	$(install-import-file)
+	@$(call binary_file_verification,$@)
 
 $(LIB_LOCATION)/$(SERVER_LOCATION)/64/$(JVMDTRACE_NAME): $(HOTSPOT_SERVER_PATH)/64/$(JVMDTRACE_NAME)
 	$(install-import-file)
+	@$(call binary_file_verification,$@)
 
 $(LIB_LOCATION)/$(SERVER_LOCATION)/$(JVM_NAME): $(HOTSPOT_SERVER_PATH)/$(JVM_NAME)
 	$(install-import-file)
+	@$(call binary_file_verification,$@)
 
 $(LIB_LOCATION)/$(SERVER_LOCATION)/Xusage.txt : $(HOTSPOT_SERVER_PATH)/Xusage.txt
 	$(install-import-file)
--- a/make/jdk_generic_profile.sh	Thu Feb 10 21:36:18 2011 +0300
+++ b/make/jdk_generic_profile.sh	Fri Feb 11 12:14:38 2011 -0800
@@ -50,7 +50,7 @@
 #
 # Assumes basic unix utilities are in the PATH already (uname, hostname, etc.).
 #
-# On Windows, assumes PROCESSOR_IDENTIFIER, VS71COMNTOOLS,
+# On Windows, assumes PROCESSOR_IDENTIFIER, VS100COMNTOOLS,
 #   SYSTEMROOT (or SystemRoot), COMPUTERNAME (or hostname works), and
 #   USERNAME is defined in the environment.
 #   This profile does not rely on using vcvars32.bat and 64bit Setup.bat.
@@ -81,8 +81,7 @@
 #    Windows Only:
 #      ALT_UNIXCOMMAND_PATH
 #      ALT_DXSDK_PATH
-#      ALT_MSVCRT_DLL_PATH
-#      ALT_MSVCR71_DLL_PATH
+#      ALT_MSVCRNN_DLL_PATH
 #
 #############################################################################
 #
@@ -213,78 +212,17 @@
   # Compiler setup (nasty part)
   #   NOTE: You can use vcvars32.bat to set PATH, LIB, and INCLUDE.
   #   NOTE: CYGWIN has a link.exe too, make sure the compilers are first
-  if [ "${windows_arch}" = i586 ] ; then
-    # 32bit Windows compiler settings
-    # VisualStudio .NET 2003 VC++ 7.1 (VS71COMNTOOLS should be defined)
-    vs_root=$(${cygpath} "${VS71COMNTOOLS}/../..")
-    # Fill in PATH, LIB, and INCLUDE (unset all others to make sure)
-    vc7_root="${vs_root}/Vc7"
-    compiler_path="${vc7_root}/bin"
-    platform_sdk="${vc7_root}/PlatformSDK"
-        
-    # LIB and INCLUDE must use ; as a separator
-    include4sdk="${vc7_root}/atlmfc/include"
-    include4sdk="${include4sdk};${vc7_root}/include"
-    include4sdk="${include4sdk};${platform_sdk}/include/prerelease"
-    include4sdk="${include4sdk};${platform_sdk}/include"
-    include4sdk="${include4sdk};${vs_root}/SDK/v1.1/include"
-    lib4sdk="${lib4sdk};${vc7_root}/lib"
-    lib4sdk="${lib4sdk};${platform_sdk}/lib/prerelease"
-    lib4sdk="${lib4sdk};${platform_sdk}/lib"
-    lib4sdk="${lib4sdk};${vs_root}/SDK/v1.1/lib"
-    # Search path and DLL locating path
-    #   WARNING: CYGWIN has a link.exe too, make sure compilers are first
-    path4sdk="${vs_root}/Common7/Tools/bin;${path4sdk}"
-    path4sdk="${vs_root}/SDK/v1.1/bin;${path4sdk}"
-    path4sdk="${vs_root}/Common7/Tools;${path4sdk}"
-    path4sdk="${vs_root}/Common7/Tools/bin/prerelease;${path4sdk}"
-    path4sdk="${vs_root}/Common7/IDE;${path4sdk}"
-    path4sdk="${compiler_path};${path4sdk}"
-  elif [ "${windows_arch}" = amd64 ] ; then
-    # AMD64 64bit Windows compiler settings
-    if [ "${ALT_DEPLOY_MSSDK}" != "" ] ; then
-      platform_sdk=${ALT_DEPLOY_MSSDK}
-    else
-      platform_sdk=$(${cygpath} "C:/Program Files/Microsoft Platform SDK/")
-    fi
-    if [ "${ALT_COMPILER_PATH}" != "" ] ; then
-      compiler_path=${ALT_COMPILER_PATH}
-      if [ "${ALT_DEPLOY_MSSDK}" = "" ] ; then
-        platform_sdk=${ALT_COMPILER_PATH}/../../../..
-      fi
-    else
-      compiler_path="${platform_sdk}/Bin/win64/x86/AMD64"
-    fi
-    # LIB and INCLUDE must use ; as a separator
-    include4sdk="${platform_sdk}/Include"
-    include4sdk="${include4sdk};${platform_sdk}/Include/crt/sys"
-    include4sdk="${include4sdk};${platform_sdk}/Include/mfc"
-    include4sdk="${include4sdk};${platform_sdk}/Include/atl"
-    include4sdk="${include4sdk};${platform_sdk}/Include/crt"
-    lib4sdk="${platform_sdk}/Lib/AMD64"
-    lib4sdk="${lib4sdk};${platform_sdk}/Lib/AMD64/atlmfc"
-    # Search path and DLL locating path
-    #   WARNING: CYGWIN has a link.exe too, make sure compilers are first
-    path4sdk="${platform_sdk}/bin;${path4sdk}"
-    path4sdk="${compiler_path};${path4sdk}"
+
+  # Use supplied vsvars.sh
+  repo=`hg root`
+  if [ -f "${repo}/make/scripts/vsvars.sh" ] ; then
+    eval `sh ${repo}/make/scripts/vsvars.sh -v10`
+  elif [ -f "${repo}/../make/scripts/vsvars.sh" ] ; then
+    eval `sh ${repo}/../make/scripts/vsvars.sh -v10`
+  else
+    echo "WARNING: No make/scripts/vsvars.sh file found"
   fi
-  # Export LIB and INCLUDE
-  unset lib
-  unset Lib
-  LIB="${lib4sdk}"
-  export LIB
-  unset include
-  unset Include
-  INCLUDE="${include4sdk}"
-  export INCLUDE
     
-  # Turn all \\ into /, remove duplicates and trailing /
-  slash_path="$(echo ${path4sdk} | sed -e 's@\\\\@/@g' -e 's@//@/@g' -e 's@/$@@' -e 's@/;@;@g')"
-  path4sdk="${slash_path}"
-   
-  # Convert path4sdk to cygwin style
-  path4sdk="$(/usr/bin/cygpath -p ${path4sdk})"
-
 fi
 
 # Get the previous JDK to be used to bootstrap the build
--- a/make/sun/awt/Makefile	Thu Feb 10 21:36:18 2011 +0300
+++ b/make/sun/awt/Makefile	Fri Feb 11 12:14:38 2011 -0800
@@ -369,10 +369,6 @@
 _FONTCONFIGS	= \
 	fontconfig.properties				\
 	fontconfig.RedHat.properties			\
-	fontconfig.RedHat.2.1.properties		\
-	fontconfig.RedHat.3.properties		        \
-	fontconfig.RedHat.4.properties			\
-	fontconfig.Sun.properties			\
 	fontconfig.Turbo.properties			\
 	fontconfig.SuSE.10.properties                   \
 	fontconfig.SuSE.11.properties
@@ -388,9 +384,7 @@
 
 FONTCONFIGS_SRC	= $(PLATFORM_SRC)/classes/sun/awt/fontconfigs
 _FONTCONFIGS	= \
-	fontconfig.properties	\
-	fontconfig.5.9.properties	\
-	fontconfig.5.8.properties
+	fontconfig.properties
 
 FONTCONFIGS_SRC_PREFIX = $(PLATFORM).
 
--- a/make/sun/awt/mapfile-mawt-vers	Thu Feb 10 21:36:18 2011 +0300
+++ b/make/sun/awt/mapfile-mawt-vers	Fri Feb 11 12:14:38 2011 -0800
@@ -515,8 +515,7 @@
 		getDefaultConfig;
                 Java_sun_font_FontConfigManager_getFontConfig;
                 Java_sun_font_FontConfigManager_getFontConfigAASettings;
-		Java_sun_awt_X11FontManager_getFontPath;
-		Java_sun_awt_X11FontManager_setNativeFontPath;
+		Java_sun_awt_X11FontManager_getFontPathNative;
 		Java_sun_font_SunFontManager_populateFontFileNameMap;
 
 		# CDE private entry point
--- a/make/sun/awt/mapfile-vers-linux	Thu Feb 10 21:36:18 2011 +0300
+++ b/make/sun/awt/mapfile-vers-linux	Fri Feb 11 12:14:38 2011 -0800
@@ -537,8 +537,7 @@
 		getDefaultConfig;
                 Java_sun_font_FontConfigManager_getFontConfig;
                 Java_sun_font_FontConfigManager_getFontConfigAASettings;
-		Java_sun_awt_X11FontManager_getFontPath;
-		Java_sun_awt_X11FontManager_setNativeFontPath;
+		Java_sun_awt_X11FontManager_getFontPathNative;
 		Java_sun_font_SunFontManager_populateFontFileNameMap;
 
 		# CDE private entry point
--- a/make/sun/headless/mapfile-vers	Thu Feb 10 21:36:18 2011 +0300
+++ b/make/sun/headless/mapfile-vers	Fri Feb 11 12:14:38 2011 -0800
@@ -65,7 +65,7 @@
                 Java_sun_font_FontConfigManager_getFontConfig;
                 Java_sun_font_FontConfigManager_getFontConfigAASettings;
                 Java_sun_font_FontConfigManager_getFontConfigVersion;
-		Java_sun_awt_X11FontManager_getFontPath;
+                Java_sun_awt_X11FontManager_getFontPathNative;
 
 		Java_sun_awt_FontDescriptor_initIDs;
 		Java_sun_awt_PlatformFont_initIDs;
--- a/make/sun/net/FILES_java.gmk	Thu Feb 10 21:36:18 2011 +0300
+++ b/make/sun/net/FILES_java.gmk	Fri Feb 11 12:14:38 2011 -0800
@@ -33,6 +33,7 @@
 	sun/net/ProgressEvent.java \
 	sun/net/ProgressListener.java \
 	sun/net/ProgressMeteringPolicy.java \
+	sun/net/SocksProxy.java \
 	sun/net/TelnetInputStream.java \
 	sun/net/TelnetOutputStream.java \
 	sun/net/TelnetProtocolException.java \
--- a/make/sun/xawt/Makefile	Thu Feb 10 21:36:18 2011 +0300
+++ b/make/sun/xawt/Makefile	Fri Feb 11 12:14:38 2011 -0800
@@ -136,8 +136,25 @@
               -I$(OPENWIN_HOME)/include 
 endif
 
+# We have some odd logic here because some Solaris 10 updates
+# have a render.h file that suggests gradients are supported, but
+# the Xrender.h doesn't have the corresponding type definitions.
+# Earlier updates have neither. We'd like to know if there's a mismatch.
+# Whilst in the C preprocessor we can tell if the render.h define's are set
+# we can't tell anything about C declarations.
+# A grep of Xrender.h is the only way to know this. If they are absent
+# we will set a flag indicating this mismatch and the JDK source file
+# will interpret it to resolve the problem.
 ifeq ($(PLATFORM), solaris)
   CPPFLAGS += -I$(OPENWIN_HOME)/include/X11/extensions
+  OS_VERSION := $(shell uname -r)
+  XRENDER_H := $(OPENWIN_HOME)/share/include/X11/extensions/Xrender.h
+  ifeq ($(OS_VERSION),5.10) 
+     LINEARGRADIENT_CNT := $(shell $(EGREP) -c XLinearGradient $(XRENDER_H))
+     ifeq ($(LINEARGRADIENT_CNT),0) 
+       CFLAGS+= -DSOLARIS10_NO_XRENDER_STRUCTS
+     endif
+ endif
 endif
 
 ifeq ($(MILESTONE), internal)
--- a/make/sun/xawt/mapfile-vers	Thu Feb 10 21:36:18 2011 +0300
+++ b/make/sun/xawt/mapfile-vers	Fri Feb 11 12:14:38 2011 -0800
@@ -188,8 +188,7 @@
         Java_sun_font_FontConfigManager_getFontConfig;
         Java_sun_font_FontConfigManager_getFontConfigAASettings;
         Java_sun_font_FontConfigManager_getFontConfigVersion;
-	Java_sun_awt_X11FontManager_getFontPath;
-	Java_sun_font_X11FontManager_setNativeFontPath;
+	Java_sun_awt_X11FontManager_getFontPathNative;
         Java_sun_awt_X11GraphicsEnvironment_initDisplay;
         Java_sun_awt_X11GraphicsEnvironment_initGLX;
 	Java_sun_awt_X11GraphicsEnvironment_initXRender;
--- a/make/tools/reorder/Makefile	Thu Feb 10 21:36:18 2011 +0300
+++ b/make/tools/reorder/Makefile	Fri Feb 11 12:14:38 2011 -0800
@@ -85,7 +85,6 @@
 libs.reorder :
 ifeq ($(PLATFORM), solaris)
 	$(MAKE) LIBBLDDIR=java/zip        LIBTMPDIR=sun/java.util.zip/zip   reorder.lib
-	$(MAKE) LIBBLDDIR=java/hpi/native LIBTMPDIR=java/hpi/native_threads reorder.lib
 	$(MAKE) LIBBLDDIR=java/java       LIBTMPDIR=java/java.lang/java     reorder.lib
 	$(MAKE) LIBBLDDIR=java/nio        LIBTMPDIR=java/java.nio/nio       reorder.lib
 	$(MAKE) LIBBLDDIR=sun/font        LIBTMPDIR=sun/sun.awt.font/fontmanager reorder.lib
@@ -96,7 +95,6 @@
 libs.copy:
 ifeq ($(PLATFORM), solaris)
 	$(CP) $(OUTDIR)/reorder_java_zip-$(ARCH) ../../java/zip/reorder-$(ARCH)
-	$(CP) $(OUTDIR)/reorder_java_hpi_native-$(ARCH) ../../java/hpi/native/reorder-$(ARCH)
 	$(CP) $(OUTDIR)/reorder_java_java-$(ARCH) ../../java/java/reorder-$(ARCH)
 	$(CP) $(OUTDIR)/reorder_sun_font-$(ARCH) ../../sun/font/reorder-$(ARCH)
 	$(CP) $(OUTDIR)/reorder_sun_jpeg-$(ARCH) ../../sun/jpeg/reorder-$(ARCH)
--- a/src/share/back/debugInit.c	Thu Feb 10 21:36:18 2011 +0300
+++ b/src/share/back/debugInit.c	Fri Feb 11 12:14:38 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
  * 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,27 +133,60 @@
     return error;
 }
 
+typedef struct {
+    int major;
+    int minor;
+} version_type;
+
+typedef struct {
+    version_type runtime;
+    version_type compiletime;
+} compatible_versions_type;
+
+/*
+ * List of explicitly compatible JVMTI versions, specified as
+ * { runtime version, compile-time version } pairs. -1 is a wildcard.
+ */
+static int nof_compatible_versions = 3;
+static compatible_versions_type compatible_versions_list[] = {
+    /*
+     * FIXUP: Allow version 0 to be compatible with anything
+     * Special check for FCS of 1.0.
+     */
+    { {  0, -1 }, { -1, -1 } },
+    { { -1, -1 }, {  0, -1 } },
+    /*
+     * 1.2 is runtime compatible with 1.1 -- just make sure to check the
+     * version before using any new 1.2 features
+     */
+    { {  1,  1 }, {  1,  2 } }
+};
+
+
 /* Logic to determine JVMTI version compatibility */
 static jboolean
 compatible_versions(jint major_runtime,     jint minor_runtime,
                     jint major_compiletime, jint minor_compiletime)
 {
-#if 1 /* FIXUP: We allow version 0 to be compatible with anything */
-    /* Special check for FCS of 1.0. */
-    if ( major_runtime == 0 || major_compiletime == 0 ) {
-        return JNI_TRUE;
+    /*
+     * First check to see if versions are explicitly compatible via the
+     * list specified above.
+     */
+    int i;
+    for (i = 0; i < nof_compatible_versions; ++i) {
+        version_type runtime = compatible_versions_list[i].runtime;
+        version_type comptime = compatible_versions_list[i].compiletime;
+
+        if ((major_runtime     == runtime.major  || runtime.major  == -1) &&
+            (minor_runtime     == runtime.minor  || runtime.minor  == -1) &&
+            (major_compiletime == comptime.major || comptime.major == -1) &&
+            (minor_compiletime == comptime.minor || comptime.minor == -1)) {
+            return JNI_TRUE;
+        }
     }
-#endif
-    /* Runtime major version must match. */
-    if ( major_runtime != major_compiletime ) {
-        return JNI_FALSE;
-    }
-    /* Runtime minor version must be >= the version compiled with. */
-    if ( minor_runtime < minor_compiletime ) {
-        return JNI_FALSE;
-    }
-    /* Assumed compatible */
-    return JNI_TRUE;
+
+    return major_runtime == major_compiletime &&
+           minor_runtime >= minor_compiletime;
 }
 
 /* OnLoad startup:
--- a/src/share/back/eventFilter.c	Thu Feb 10 21:36:18 2011 +0300
+++ b/src/share/back/eventFilter.c	Fri Feb 11 12:14:38 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
  * 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,6 +39,7 @@
 #include "stepControl.h"
 #include "threadControl.h"
 #include "SDE.h"
+#include "jvmti.h"
 
 typedef struct ClassFilter {
     jclass clazz;
@@ -275,6 +276,24 @@
     }
 }
 
+static jboolean isVersionGte12x() {
+    jint version;
+    jvmtiError err =
+        JVMTI_FUNC_PTR(gdata->jvmti,GetVersionNumber)(gdata->jvmti, &version);
+
+    if (err == JVMTI_ERROR_NONE) {
+        jint major, minor;
+
+        major = (version & JVMTI_VERSION_MASK_MAJOR)
+                    >> JVMTI_VERSION_SHIFT_MAJOR;
+        minor = (version & JVMTI_VERSION_MASK_MINOR)
+                    >> JVMTI_VERSION_SHIFT_MINOR;
+        return (major > 1 || major == 1 && minor >= 2);
+    } else {
+        return JNI_FALSE;
+    }
+}
+
 /* Return the object instance in which the event occurred */
 /* Return NULL if static or if an error occurs */
 static jobject
@@ -286,6 +305,14 @@
     jint        modifiers       = 0;
     jvmtiError  error;
 
+    static jboolean got_version = JNI_FALSE;
+    static jboolean is_version_gte_12x = JNI_FALSE;
+
+    if (!got_version) {
+        is_version_gte_12x = isVersionGte12x();
+        got_version = JNI_TRUE;
+    }
+
     switch (evinfo->ei) {
         case EI_SINGLE_STEP:
         case EI_BREAKPOINT:
@@ -314,11 +341,18 @@
     /* fail if error or static (0x8) */
     if (error == JVMTI_ERROR_NONE && thread!=NULL && (modifiers & 0x8) == 0) {
         FrameNumber fnum            = 0;
-        /* get slot zero object "this" */
-        error = JVMTI_FUNC_PTR(gdata->jvmti,GetLocalObject)
-                    (gdata->jvmti, thread, fnum, 0, &object);
-        if (error != JVMTI_ERROR_NONE)
+        if (is_version_gte_12x) {
+            /* Use new 1.2.x function, GetLocalInstance */
+            error = JVMTI_FUNC_PTR(gdata->jvmti,GetLocalInstance)
+                        (gdata->jvmti, thread, fnum, &object);
+        } else {
+            /* get slot zero object "this" */
+            error = JVMTI_FUNC_PTR(gdata->jvmti,GetLocalObject)
+                        (gdata->jvmti, thread, fnum, 0, &object);
+        }
+        if (error != JVMTI_ERROR_NONE) {
             object = NULL;
+        }
     }
 
     return object;
--- a/src/share/bin/java.c	Thu Feb 10 21:36:18 2011 +0300
+++ b/src/share/bin/java.c	Fri Feb 11 12:14:38 2011 -0800
@@ -94,15 +94,15 @@
  * Prototypes for functions internal to launcher.
  */
 static void SetClassPath(const char *s);
-static void SetModulesBootClassPath(const char *s);
 static void SelectVersion(int argc, char **argv, char **main_class);
-static jboolean ParseArguments(int *pargc, char ***pargv, char **pjarfile,
-                               char **pclassname, int *pret, const char *jvmpath);
+static jboolean ParseArguments(int *pargc, char ***pargv,
+                               int *pmode, char **pwhat,
+                               int *pret, const char *jrepath);
 static jboolean InitializeJVM(JavaVM **pvm, JNIEnv **penv,
                               InvocationFunctions *ifn);
 static jstring NewPlatformString(JNIEnv *env, char *s);
 static jobjectArray NewPlatformStringArray(JNIEnv *env, char **strv, int strc);
-static jclass LoadMainClass(JNIEnv *env, jboolean isJar, char *name);
+static jclass LoadMainClass(JNIEnv *env, int mode, char *name);
 
 static void TranslateApplicationArgs(int jargc, const char **jargv, int *pargc, char ***pargv);
 static jboolean AddApplicationOptions(int cpathc, const char **cpathv);
@@ -158,18 +158,27 @@
  * Running Java code in primordial thread caused many problems. We will
  * create a new thread to invoke JVM. See 6316197 for more information.
  */
-static jlong threadStackSize    = 0;  /* stack size of the new thread */
+static jlong threadStackSize = 0;  /* stack size of the new thread */
 static jlong maxHeapSize        = 0;  /* max heap size */
 static jlong initialHeapSize    = 0;  /* inital heap size */
 
 int JNICALL JavaMain(void * args); /* entry point                  */
 
+enum LaunchMode {               // cf. sun.launcher.LauncherHelper
+    LM_UNKNOWN = 0,
+    LM_CLASS,
+    LM_JAR
+};
+
+static const char *launchModeNames[]
+    = { "Unknown", "Main class", "JAR file" };
+
 typedef struct {
-  int     argc;
-  char ** argv;
-  char *  jarfile;
-  char *  classname;
-  InvocationFunctions ifn;
+    int    argc;
+    char **argv;
+    int    mode;
+    char  *what;
+    InvocationFunctions ifn;
 } JavaMainArgs;
 
 /*
@@ -189,8 +198,8 @@
         jint ergo                               /* ergonomics class policy */
 )
 {
-    char *jarfile = 0;
-    char *classname = 0;
+    int mode = LM_UNKNOWN;
+    char *what = NULL;
     char *cpath = 0;
     char *main_class = NULL;
     int ret;
@@ -277,24 +286,21 @@
         SetClassPath(cpath);
     }
 
-    /*
-     *  Parse command line options; if the return value of
-     *  ParseArguments is false, the program should exit.
+    /* Parse command line options; if the return value of
+     * ParseArguments is false, the program should exit.
      */
-    if (!ParseArguments(&argc, &argv, &jarfile, &classname, &ret, jvmpath)) {
+    if (!ParseArguments(&argc, &argv, &mode, &what, &ret, jrepath))
+    {
         return(ret);
     }
 
-    /* Set bootclasspath for modules */
-    SetModulesBootClassPath(jrepath);
-
     /* Override class path if -jar flag was specified */
-    if (jarfile != 0) {
-        SetClassPath(jarfile);
+    if (mode == LM_JAR) {
+        SetClassPath(what);     /* Override class path */
     }
 
     /* set the -Dsun.java.command pseudo property */
-    SetJavaCommandLineProp(classname, jarfile, argc, argv);
+    SetJavaCommandLineProp(what, argc, argv);
 
     /* Set the -Dsun.java.launcher pseudo property */
     SetJavaLauncherProp();
@@ -305,7 +311,7 @@
     /* Show the splash screen if needed */
     ShowSplashScreen();
 
-    return ContinueInNewThread(&ifn, argc, argv, jarfile, classname, ret);
+    return ContinueInNewThread(&ifn, argc, argv, mode, what, ret);
 
 }
 /*
@@ -353,13 +359,13 @@
     JavaMainArgs *args = (JavaMainArgs *)_args;
     int argc = args->argc;
     char **argv = args->argv;
-    char *jarfile = args->jarfile;
-    char *classname = args->classname;
+    int mode = args->mode;
+    char *what = args->what;
     InvocationFunctions ifn = args->ifn;
 
     JavaVM *vm = 0;
     JNIEnv *env = 0;
-    jclass mainClass;
+    jclass mainClass = NULL;
     jmethodID mainID;
     jobjectArray mainArgs;
     int ret = 0;
@@ -385,7 +391,7 @@
         CHECK_EXCEPTION_LEAVE(1);
     }
     /* If the user specified neither a class name nor a JAR file */
-    if (printXUsage || printUsage || (jarfile == 0 && classname == 0)) {
+    if (printXUsage || printUsage || what == 0 || mode == LM_UNKNOWN) {
         PrintUsage(env, printXUsage);
         CHECK_EXCEPTION_LEAVE(1);
         LEAVE();
@@ -399,11 +405,11 @@
                (long)(jint)Counter2Micros(end-start));
     }
 
-    /* At this stage, argc/argv have the applications' arguments */
+    /* At this stage, argc/argv have the application's arguments */
     if (JLI_IsTraceLauncher()){
         int i;
-        printf("Main-Class is '%s'\n", classname ? classname : "");
-        printf("Apps' argc is %d\n", argc);
+        printf("%s is '%s'\n", launchModeNames[mode], what);
+        printf("App's argc is %d\n", argc);
         for (i=0; i < argc; i++) {
             printf("    argv[%2d] = '%s'\n", i, argv[i]);
         }
@@ -431,11 +437,7 @@
      *     2)   Remove the vestages of maintaining main_class through
      *          the environment (and remove these comments).
      */
-    if (jarfile != 0) {
-        mainClass = LoadMainClass(env, JNI_TRUE, jarfile);
-    } else {
-        mainClass = LoadMainClass(env, JNI_FALSE, classname);
-    }
+    mainClass = LoadMainClass(env, mode, what);
     CHECK_EXCEPTION_NULL_LEAVE(mainClass);
 
     /*
@@ -697,7 +699,7 @@
     if (JLI_StrCCmp(str, "-Xms") == 0) {
         jlong tmp;
         if (parse_size(str + 4, &tmp)) {
-            initialHeapSize = tmp;
+           initialHeapSize = tmp;
         }
     }
 }
@@ -719,44 +721,6 @@
 }
 
 /*
- * Set the bootclasspath for modules.
- * A temporary workaround until jigsaw is integrated into JDK 7.
- */
-static void
-SetModulesBootClassPath(const char *jrepath)
-{
-    char *def, *s;
-    char pathname[MAXPATHLEN];
-    const char separator[] = { FILE_SEPARATOR, '\0' };
-    const char *orig = jrepath;
-    static const char format[] = "-Xbootclasspath/p:%s";
-    struct stat statbuf;
-
-    /* return if jre/lib/rt.jar exists */
-    JLI_Snprintf(pathname, sizeof(pathname), "%s%slib%srt.jar", jrepath, separator, separator);
-    if (stat(pathname, &statbuf) == 0) {
-        return;
-    }
-
-    /* return if jre/classes exists */
-    JLI_Snprintf(pathname, sizeof(pathname), "%s%sclasses", jrepath, separator);
-    if (stat(pathname, &statbuf) == 0) {
-        return;
-    }
-
-    /* modularized jre */
-    JLI_Snprintf(pathname, sizeof(pathname), "%s%slib%s*", jrepath, separator, separator);
-    s = (char *) JLI_WildcardExpandClasspath(pathname);
-    def = JLI_MemAlloc(sizeof(format)
-                       - 2 /* strlen("%s") */
-                       + JLI_StrLen(s));
-    sprintf(def, format, s);
-    AddOption(def, NULL);
-    if (s != orig)
-        JLI_MemFree((char *) s);
-}
-
-/*
  * The SelectVersion() routine ensures that an appropriate version of
  * the JRE is running.  The specification for the appropriate version
  * is obtained from either the manifest of a jar file (preferred) or
@@ -1000,16 +964,17 @@
 /*
  * Parses command line arguments.  Returns JNI_FALSE if launcher
  * should exit without starting vm, returns JNI_TRUE if vm needs
- * to be started to process  given options. *pret (the launcher
+ * to be started to process given options.  *pret (the launcher
  * process return value) is set to 0 for a normal exit.
  */
 static jboolean
-ParseArguments(int *pargc, char ***pargv, char **pjarfile,
-                       char **pclassname, int *pret, const char *jvmpath)
+ParseArguments(int *pargc, char ***pargv,
+               int *pmode, char **pwhat,
+               int *pret, const char *jrepath)
 {
     int argc = *pargc;
     char **argv = *pargv;
-    jboolean jarflag = JNI_FALSE;
+    int mode = LM_UNKNOWN;
     char *arg;
 
     *pret = 0;
@@ -1019,10 +984,11 @@
         if (JLI_StrCmp(arg, "-classpath") == 0 || JLI_StrCmp(arg, "-cp") == 0) {
             ARG_CHECK (argc, ARG_ERROR1, arg);
             SetClassPath(*argv);
+            mode = LM_CLASS;
             argv++; --argc;
         } else if (JLI_StrCmp(arg, "-jar") == 0) {
             ARG_CHECK (argc, ARG_ERROR2, arg);
-            jarflag = JNI_TRUE;
+            mode = LM_JAR;
         } else if (JLI_StrCmp(arg, "-help") == 0 ||
                    JLI_StrCmp(arg, "-h") == 0 ||
                    JLI_StrCmp(arg, "-?") == 0) {
@@ -1102,19 +1068,24 @@
     }
 
     if (--argc >= 0) {
-        if (jarflag) {
-            *pjarfile = *argv++;
-            *pclassname = NULL;
-        } else {
-            *pjarfile = NULL;
-            *pclassname = *argv++;
-        }
+        *pwhat = *argv++;
+    }
+
+    if (*pwhat == NULL) {
+        *pret = 1;
+    } else if (mode == LM_UNKNOWN) {
+        /* default to LM_CLASS if -jar and -cp option are
+         * not specified */
+        mode = LM_CLASS;
+    }
+
+    if (argc >= 0) {
         *pargc = argc;
         *pargv = argv;
     }
-    if (*pjarfile == NULL && *pclassname == NULL) {
-        *pret = 1;
-    }
+
+    *pmode = mode;
+
     return JNI_TRUE;
 }
 
@@ -1263,7 +1234,7 @@
  * call it for more details refer to the java implementation.
  */
 static jclass
-LoadMainClass(JNIEnv *env, jboolean isJar, char *name)
+LoadMainClass(JNIEnv *env, int mode, char *name)
 {
     jclass cls;
     jmethodID mid;
@@ -1276,9 +1247,9 @@
     }
     NULL_CHECK0(cls = FindBootStrapClass(env, "sun/launcher/LauncherHelper"));
     NULL_CHECK0(mid = (*env)->GetStaticMethodID(env, cls, "checkAndLoadMain",
-                                          "(ZZLjava/lang/String;)Ljava/lang/Object;"));
+                                          "(ZILjava/lang/String;)Ljava/lang/Class;"));
     str = (*env)->NewStringUTF(env, name);
-    result = (*env)->CallStaticObjectMethod(env, cls, mid, JNI_TRUE, isJar, str);
+    result = (*env)->CallStaticObjectMethod(env, cls, mid, JNI_TRUE, mode, str);
 
     if (JLI_IsTraceLauncher()) {
         end   = CounterGet();
@@ -1424,8 +1395,7 @@
  * property is not exported by HotSpot to the Java layer.
  */
 void
-SetJavaCommandLineProp(char *classname, char *jarfile,
-                       int argc, char **argv)
+SetJavaCommandLineProp(char *what, int argc, char **argv)
 {
 
     int i = 0;
@@ -1433,22 +1403,17 @@
     char* javaCommand = NULL;
     char* dashDstr = "-Dsun.java.command=";
 
-    if (classname == NULL && jarfile == NULL) {
+    if (what == NULL) {
         /* unexpected, one of these should be set. just return without
          * setting the property
          */
         return;
     }
 
-    /* if the class name is not set, then use the jarfile name */
-    if (classname == NULL) {
-        classname = jarfile;
-    }
-
     /* determine the amount of memory to allocate assuming
      * the individual components will be space separated
      */
-    len = JLI_StrLen(classname);
+    len = JLI_StrLen(what);
     for (i = 0; i < argc; i++) {
         len += JLI_StrLen(argv[i]) + 1;
     }
@@ -1459,7 +1424,7 @@
     /* build the -D string */
     *javaCommand = '\0';
     JLI_StrCat(javaCommand, dashDstr);
-    JLI_StrCat(javaCommand, classname);
+    JLI_StrCat(javaCommand, what);
 
     for (i = 0; i < argc; i++) {
         /* the components of the string are space separated. In
@@ -1479,7 +1444,8 @@
  * JVM would like to know if it's created by a standard Sun launcher, or by
  * user native application, the following property indicates the former.
  */
-void SetJavaLauncherProp() {
+void
+SetJavaLauncherProp() {
   AddOption("-Dsun.java.launcher=SUN_STANDARD", NULL);
 }
 
@@ -1913,8 +1879,8 @@
 }
 
 static int
-ContinueInNewThread(InvocationFunctions* ifn, int argc,
-                     char **argv, char *jarfile, char *classname, int ret)
+ContinueInNewThread(InvocationFunctions* ifn, int argc, char **argv,
+                    int mode, char *what, int ret)
 {
 
     /*
@@ -1938,8 +1904,8 @@
 
       args.argc = argc;
       args.argv = argv;
-      args.jarfile = jarfile;
-      args.classname = classname;
+      args.mode = mode;
+      args.what = what;
       args.ifn = *ifn;
 
       rslt = ContinueInNewThread0(JavaMain, threadStackSize, (void*)&args);
--- a/src/share/bin/java.h	Thu Feb 10 21:36:18 2011 +0300
+++ b/src/share/bin/java.h	Fri Feb 11 12:14:38 2011 -0800
@@ -153,7 +153,7 @@
 
 /* sun.java.launcher.* platform properties. */
 void SetJavaLauncherPlatformProps(void);
-void SetJavaCommandLineProp(char* classname, char* jarfile, int argc, char** argv);
+void SetJavaCommandLineProp(char* what, int argc, char** argv);
 void SetJavaLauncherProp(void);
 
 /*
@@ -178,8 +178,9 @@
 
 jboolean ServerClassMachine();
 
-static int ContinueInNewThread(InvocationFunctions* ifn, int argc, char** argv,
-                        char* jarfile, char* classname, int ret);
+static int ContinueInNewThread(InvocationFunctions* ifn,
+                               int argc, char** argv,
+                               int mode, char *what, int ret);
 
 /*
  * Initialize platform specific settings
--- a/src/share/classes/com/sun/java/util/jar/pack/BandStructure.java	Thu Feb 10 21:36:18 2011 +0300
+++ b/src/share/classes/com/sun/java/util/jar/pack/BandStructure.java	Fri Feb 11 12:14:38 2011 -0800
@@ -1704,7 +1704,7 @@
         for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) {
             assert(attrIndexLimit[i] == 0);
             attrIndexLimit[i] = 32;  // just for the sake of predefs.
-            attrDefs.set(i, new ArrayList<>(Collections.nCopies(
+            attrDefs.set(i, new ArrayList<Attribute.Layout>(Collections.nCopies(
                     attrIndexLimit[i], (Attribute.Layout)null)));
 
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/management/ThreadMXBean.java	Fri Feb 11 12:14:38 2011 -0800
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 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.  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.management;
+
+import java.util.Map;
+
+/**
+ * Platform-specific management interface for the thread system
+ * of the Java virtual machine.
+ * <p>
+ * This platform extension is only available to a thread
+ * implementation that supports this extension.
+ *
+ * @author  Paul Hohensee
+ * @since   6u25
+ */
+
+public interface ThreadMXBean extends java.lang.management.ThreadMXBean {
+    /**
+     * Returns the total CPU time for each thread whose ID is
+     * in the input array {@code ids} in nanoseconds.
+     * The returned values are of nanoseconds precision but
+     * not necessarily nanoseconds accuracy.
+     * <p>
+     * This method is equivalent to calling the
+     * {@link ThreadMXBean#getThreadCpuTime(long)}
+     * method for each thread ID in the input array {@code ids} and setting the
+     * returned value in the corresponding element of the returned array.
+     *
+     * @param ids an array of thread IDs.
+     * @return an array of long values, each of which is the amount of CPU
+     * time the thread whose ID is in the corresponding element of the input
+     * array of IDs has used,
+     * if the thread of a specified ID exists, the thread is alive,
+     * and CPU time measurement is enabled;
+     * {@code -1} otherwise.
+     *
+     * @throws NullPointerException if {@code ids} is {@code null}
+     * @throws IllegalArgumentException if any element in the input array
+     *         {@code ids} is {@code <=} {@code 0}.
+     * @throws java.lang.UnsupportedOperationException if the Java
+     *         virtual machine implementation does not support CPU time
+     *         measurement.
+     *
+     * @see ThreadMXBean#getThreadCpuTime(long)
+     * @see #getThreadUserTime
+     * @see ThreadMXBean#isThreadCpuTimeSupported
+     * @see ThreadMXBean#isThreadCpuTimeEnabled
+     * @see ThreadMXBean#setThreadCpuTimeEnabled
+     */
+    public long[] getThreadCpuTime(long[] ids);
+
+    /**
+     * Returns the CPU time that each thread whose ID is in the input array
+     * {@code ids} has executed in user mode in nanoseconds.
+     * The returned values are of nanoseconds precision but
+     * not necessarily nanoseconds accuracy.
+     * <p>
+     * This method is equivalent to calling the
+     * {@link ThreadMXBean#getThreadUserTime(long)}
+     * method for each thread ID in the input array {@code ids} and setting the
+     * returned value in the corresponding element of the returned array.
+     *
+     * @param ids an array of thread IDs.
+     * @return an array of long values, each of which is the amount of user
+     * mode CPU time the thread whose ID is in the corresponding element of
+     * the input array of IDs has used,
+     * if the thread of a specified ID exists, the thread is alive,
+     * and CPU time measurement is enabled;
+     * {@code -1} otherwise.
+     *
+     * @throws NullPointerException if {@code ids} is {@code null}
+     * @throws IllegalArgumentException if any element in the input array
+     *         {@code ids} is {@code <=} {@code 0}.
+     * @throws java.lang.UnsupportedOperationException if the Java
+     *         virtual machine implementation does not support CPU time
+     *         measurement.
+     *
+     * @see ThreadMXBean#getThreadUserTime(long)
+     * @see #getThreadCpuTime
+     * @see ThreadMXBean#isThreadCpuTimeSupported
+     * @see ThreadMXBean#isThreadCpuTimeEnabled
+     * @see ThreadMXBean#setThreadCpuTimeEnabled
+     */
+    public long[] getThreadUserTime(long[] ids);
+
+    /**
+     * Returns an approximation of the total amount of memory, in bytes,
+     * allocated in heap memory for the thread of the specified ID.
+     * The returned value is an approximation because some Java virtual machine
+     * implementations may use object allocation mechanisms that result in a
+     * delay between the time an object is allocated and the time its size is
+     * recorded.
+     * <p>
+     * If the thread of the specified ID is not alive or does not exist,
+     * this method returns {@code -1}. If thread memory allocation measurement
+     * is disabled, this method returns {@code -1}.
+     * A thread is alive if it has been started and has not yet died.
+     * <p>
+     * If thread memory allocation measurement is enabled after the thread has
+     * started, the Java virtual machine implementation may choose any time up
+     * to and including the time that the capability is enabled as the point
+     * where thread memory allocation measurement starts.
+     *
+     * @param id the thread ID of a thread
+     * @return an approximation of the total memory allocated, in bytes, in
+     * heap memory for a thread of the specified ID
+     * if the thread of the specified ID exists, the thread is alive,
+     * and thread memory allocation measurement is enabled;
+     * {@code -1} otherwise.
+     *
+     * @throws IllegalArgumentException if {@code id} {@code <=} {@code 0}.
+     * @throws java.lang.UnsupportedOperationException if the Java virtual
+     *         machine implementation does not support thread memory allocation
+     *         measurement.
+     *
+     * @see #isThreadAllocatedMemorySupported
+     * @see #isThreadAllocatedMemoryEnabled
+     * @see #setThreadAllocatedMemoryEnabled
+     */
+    public long getThreadAllocatedBytes(long id);
+
+    /**
+     * Returns an approximation of the total amount of memory, in bytes,
+     * allocated in heap memory for each thread whose ID is in the input
+     * array {@code ids}.
+     * The returned values are approximations because some Java virtual machine
+     * implementations may use object allocation mechanisms that result in a
+     * delay between the time an object is allocated and the time its size is
+     * recorded.
+     * <p>
+     * This method is equivalent to calling the
+     * {@link #getThreadAllocatedBytes(long)}
+     * method for each thread ID in the input array {@code ids} and setting the
+     * returned value in the corresponding element of the returned array.
+     *
+     * @param ids an array of thread IDs.
+     * @return an array of long values, each of which is an approximation of
+     * the total memory allocated, in bytes, in heap memory for the thread
+     * whose ID is in the corresponding element of the input array of IDs.
+     *
+     * @throws NullPointerException if {@code ids} is {@code null}
+     * @throws IllegalArgumentException if any element in the input array
+     *         {@code ids} is {@code <=} {@code 0}.
+     * @throws java.lang.UnsupportedOperationException if the Java virtual
+     *         machine implementation does not support thread memory allocation
+     *         measurement.
+     *
+     * @see #getThreadAllocatedBytes(long)
+     * @see #isThreadAllocatedMemorySupported
+     * @see #isThreadAllocatedMemoryEnabled
+     * @see #setThreadAllocatedMemoryEnabled
+     */
+    public long[] getThreadAllocatedBytes(long[] ids);
+
+    /**
+     * Tests if the Java virtual machine implementation supports thread memory
+     * allocation measurement.
+     *
+     * @return
+     *   {@code true}
+     *     if the Java virtual machine implementation supports thread memory
+     *     allocation measurement;
+     *   {@code false} otherwise.
+     */
+    public boolean isThreadAllocatedMemorySupported();
+
+    /**
+     * Tests if thread memory allocation measurement is enabled.
+     *
+     * @return {@code true} if thread memory allocation measurement is enabled;
+     *         {@code false} otherwise.
+     *
+     * @throws java.lang.UnsupportedOperationException if the Java virtual
+     *         machine does not support thread memory allocation measurement.
+     *
+     * @see #isThreadAllocatedMemorySupported
+     */
+    public boolean isThreadAllocatedMemoryEnabled();
+
+    /**
+     * Enables or disables thread memory allocation measurement.  The default
+     * is platform dependent.
+     *
+     * @param enable {@code true} to enable;
+     *               {@code false} to disable.
+     *
+     * @throws java.lang.UnsupportedOperationException if the Java virtual
+     *         machine does not support thread memory allocation measurement.
+     *
+     * @throws java.lang.SecurityException if a security manager
+     *         exists and the caller does not have
+     *         ManagementPermission("control").
+     *
+     * @see #isThreadAllocatedMemorySupported
+     */
+    public void setThreadAllocatedMemoryEnabled(boolean enable);
+}
--- a/src/share/classes/com/sun/script/javascript/RhinoScriptEngine.java	Thu Feb 10 21:36:18 2011 +0300
+++ b/src/share/classes/com/sun/script/javascript/RhinoScriptEngine.java	Fri Feb 11 12:14:38 2011 -0800
@@ -223,7 +223,9 @@
         } catch (RhinoException re) {
             if (DEBUG) re.printStackTrace();
             int line = (line = re.lineNumber()) == 0 ? -1 : line;
-            throw new ScriptException(re.toString(), re.sourceName(), line);
+            ScriptException se = new ScriptException(re.toString(), re.sourceName(), line);
+            se.initCause(re);
+            throw se;
         } finally {
             cx.exit();
         }
@@ -257,6 +259,8 @@
             "        str = 'null';                         \n" +
             "    }                                         \n" +
             "    var out = context.getWriter();            \n" +
+            "    if (!(out instanceof java.io.PrintWriter))\n" +
+            "        out = new java.io.PrintWriter(out);   \n" +
             "    out.print(String(str));                   \n" +
             "    if (newline) out.print('\\n');            \n" +
             "    out.flush();                              \n" +
--- a/src/share/classes/com/sun/security/auth/PolicyFile.java	Thu Feb 10 21:36:18 2011 +0300
+++ b/src/share/classes/com/sun/security/auth/PolicyFile.java	Fri Feb 11 12:14:38 2011 -0800
@@ -1180,7 +1180,7 @@
             // Done
             return certs;
 
-        ArrayList<Certificate> userCertList = new ArrayList<Certificate>();
+        ArrayList<Certificate> userCertList = new ArrayList<>();
         i = 0;
         while (i < certs.length) {
             userCertList.add(certs[i]);
--- a/src/share/classes/com/sun/security/auth/callback/DialogCallbackHandler.java	Thu Feb 10 21:36:18 2011 +0300
+++ b/src/share/classes/com/sun/security/auth/callback/DialogCallbackHandler.java	Fri Feb 11 12:14:38 2011 -0800
@@ -99,10 +99,10 @@
         throws UnsupportedCallbackException
     {
         /* Collect messages to display in the dialog */
-        final List<Object> messages = new ArrayList<Object>(3);
+        final List<Object> messages = new ArrayList<>(3);
 
         /* Collection actions to perform if the user clicks OK */
-        final List<Action> okActions = new ArrayList<Action>(2);
+        final List<Action> okActions = new ArrayList<>(2);
 
         ConfirmationInfo confirmation = new ConfirmationInfo();
 
--- a/src/share/classes/com/sun/security/auth/login/ConfigFile.java	Thu Feb 10 21:36:18 2011 +0300
+++ b/src/share/classes/com/sun/security/auth/login/ConfigFile.java	Fri Feb 11 12:14:38 2011 -0800
@@ -152,7 +152,7 @@
 
         // new configuration
         HashMap<String, LinkedList<AppConfigurationEntry>> newConfig =
-                new HashMap<String, LinkedList<AppConfigurationEntry>>();
+                new HashMap<>();
 
         if (url != null) {
 
@@ -392,8 +392,7 @@
         String moduleClass;
         String sflag;
         AppConfigurationEntry.LoginModuleControlFlag controlFlag;
-        LinkedList<AppConfigurationEntry> configEntries =
-                                new LinkedList<AppConfigurationEntry>();
+        LinkedList<AppConfigurationEntry> configEntries = new LinkedList<>();
 
         // application name
         appName = st.sval;
@@ -433,7 +432,7 @@
             }
 
             // get the args
-            HashMap<String, String> options = new HashMap<String, String>();
+            HashMap<String, String> options = new HashMap<>();
             String key;
             String value;
             while (peek(";") == false) {
--- a/src/share/classes/com/sun/security/auth/module/JndiLoginModule.java	Thu Feb 10 21:36:18 2011 +0300
+++ b/src/share/classes/com/sun/security/auth/module/JndiLoginModule.java	Fri Feb 11 12:14:38 2011 -0800
@@ -184,7 +184,7 @@
     private UnixNumericUserPrincipal UIDPrincipal;
     private UnixNumericGroupPrincipal GIDPrincipal;
     private LinkedList<UnixNumericGroupPrincipal> supplementaryGroups =
-                                new LinkedList<UnixNumericGroupPrincipal>();
+                                new LinkedList<>();
 
     // initial state
     private Subject subject;
--- a/src/share/classes/com/sun/security/auth/module/KeyStoreLoginModule.java	Thu Feb 10 21:36:18 2011 +0300
+++ b/src/share/classes/com/sun/security/auth/module/KeyStoreLoginModule.java	Fri Feb 11 12:14:38 2011 -0800
@@ -658,8 +658,7 @@
                 throw new FailedLoginException(
                     "Unable to find X.509 certificate chain in keystore");
             } else {
-                LinkedList<Certificate> certList =
-                                new LinkedList<Certificate>();
+                LinkedList<Certificate> certList = new LinkedList<>();
                 for (int i=0; i < fromKeyStore.length; i++) {
                     certList.add(fromKeyStore[i]);
                 }
--- a/src/share/classes/com/sun/security/auth/module/SolarisLoginModule.java	Thu Feb 10 21:36:18 2011 +0300
+++ b/src/share/classes/com/sun/security/auth/module/SolarisLoginModule.java	Fri Feb 11 12:14:38 2011 -0800
@@ -76,7 +76,7 @@
     private SolarisNumericUserPrincipal UIDPrincipal;
     private SolarisNumericGroupPrincipal GIDPrincipal;
     private LinkedList<SolarisNumericGroupPrincipal> supplementaryGroups =
-                new LinkedList<SolarisNumericGroupPrincipal>();
+                new LinkedList<>();
 
     /**
      * Initialize this <code>LoginModule</code>.
--- a/src/share/classes/com/sun/security/auth/module/UnixLoginModule.java	Thu Feb 10 21:36:18 2011 +0300
+++ b/src/share/classes/com/sun/security/auth/module/UnixLoginModule.java	Fri Feb 11 12:14:38 2011 -0800
@@ -70,7 +70,7 @@
     private UnixNumericUserPrincipal UIDPrincipal;
     private UnixNumericGroupPrincipal GIDPrincipal;
     private LinkedList<UnixNumericGroupPrincipal> supplementaryGroups =
-                new LinkedList<UnixNumericGroupPrincipal>();
+                new LinkedList<>();
 
     /**
      * Initialize this <code>LoginModule</code>.
--- a/src/share/classes/java/awt/geom/CubicCurve2D.java	Thu Feb 10 21:36:18 2011 +0300
+++ b/src/share/classes/java/awt/geom/CubicCurve2D.java	Fri Feb 11 12:14:38 2011 -0800
@@ -1387,203 +1387,13 @@
             return false;
         }
 
-        // Trivially accept if either endpoint is inside the rectangle
-        // (not on its border since it may end there and not go inside)
-        // Record where they lie with respect to the rectangle.
-        //     -1 => left, 0 => inside, 1 => right
-        double x1 = getX1();
-        double y1 = getY1();
-        int x1tag = getTag(x1, x, x+w);
-        int y1tag = getTag(y1, y, y+h);
-        if (x1tag == INSIDE && y1tag == INSIDE) {
-            return true;
-        }
-        double x2 = getX2();
-        double y2 = getY2();
-        int x2tag = getTag(x2, x, x+w);
-        int y2tag = getTag(y2, y, y+h);
-        if (x2tag == INSIDE && y2tag == INSIDE) {
-            return true;
-        }
-
-        double ctrlx1 = getCtrlX1();
-        double ctrly1 = getCtrlY1();
-        double ctrlx2 = getCtrlX2();
-        double ctrly2 = getCtrlY2();
-        int ctrlx1tag = getTag(ctrlx1, x, x+w);
-        int ctrly1tag = getTag(ctrly1, y, y+h);
-        int ctrlx2tag = getTag(ctrlx2, x, x+w);
-        int ctrly2tag = getTag(ctrly2, y, y+h);
-
-        // Trivially reject if all points are entirely to one side of
-        // the rectangle.
-        if (x1tag < INSIDE && x2tag < INSIDE &&
-            ctrlx1tag < INSIDE && ctrlx2tag < INSIDE)
-        {
-            return false;       // All points left
-        }
-        if (y1tag < INSIDE && y2tag < INSIDE &&
-            ctrly1tag < INSIDE && ctrly2tag < INSIDE)
-        {
-            return false;       // All points above
-        }
-        if (x1tag > INSIDE && x2tag > INSIDE &&
-            ctrlx1tag > INSIDE && ctrlx2tag > INSIDE)
-        {
-            return false;       // All points right
-        }
-        if (y1tag > INSIDE && y2tag > INSIDE &&
-            ctrly1tag > INSIDE && ctrly2tag > INSIDE)
-        {
-            return false;       // All points below
-        }
-
-        // Test for endpoints on the edge where either the segment
-        // or the curve is headed "inwards" from them
-        // Note: These tests are a superset of the fast endpoint tests
-        //       above and thus repeat those tests, but take more time
-        //       and cover more cases
-        if (inwards(x1tag, x2tag, ctrlx1tag) &&
-            inwards(y1tag, y2tag, ctrly1tag))
-        {
-            // First endpoint on border with either edge moving inside
-            return true;
-        }
-        if (inwards(x2tag, x1tag, ctrlx2tag) &&
-            inwards(y2tag, y1tag, ctrly2tag))
-        {
-            // Second endpoint on border with either edge moving inside
-            return true;
-        }
-
-        // Trivially accept if endpoints span directly across the rectangle
-        boolean xoverlap = (x1tag * x2tag <= 0);
-        boolean yoverlap = (y1tag * y2tag <= 0);
-        if (x1tag == INSIDE && x2tag == INSIDE && yoverlap) {
-            return true;
-        }
-        if (y1tag == INSIDE && y2tag == INSIDE && xoverlap) {
-            return true;
-        }
-
-        // We now know that both endpoints are outside the rectangle
-        // but the 4 points are not all on one side of the rectangle.
-        // Therefore the curve cannot be contained inside the rectangle,
-        // but the rectangle might be contained inside the curve, or
-        // the curve might intersect the boundary of the rectangle.
-
-        double[] eqn = new double[4];
-        double[] res = new double[4];
-        if (!yoverlap) {
-            // Both y coordinates for the closing segment are above or
-            // below the rectangle which means that we can only intersect
-            // if the curve crosses the top (or bottom) of the rectangle
-            // in more than one place and if those crossing locations
-            // span the horizontal range of the rectangle.
-            fillEqn(eqn, (y1tag < INSIDE ? y : y+h), y1, ctrly1, ctrly2, y2);
-            int num = solveCubic(eqn, res);
-            num = evalCubic(res, num, true, true, null,
-                            x1, ctrlx1, ctrlx2, x2);
-            // odd counts imply the crossing was out of [0,1] bounds
-            // otherwise there is no way for that part of the curve to
-            // "return" to meet its endpoint
-            return (num == 2 &&
-                    getTag(res[0], x, x+w) * getTag(res[1], x, x+w) <= 0);
-        }
-
-        // Y ranges overlap.  Now we examine the X ranges
-        if (!xoverlap) {
-            // Both x coordinates for the closing segment are left of
-            // or right of the rectangle which means that we can only
-            // intersect if the curve crosses the left (or right) edge
-            // of the rectangle in more than one place and if those
-            // crossing locations span the vertical range of the rectangle.
-            fillEqn(eqn, (x1tag < INSIDE ? x : x+w), x1, ctrlx1, ctrlx2, x2);
-            int num = solveCubic(eqn, res);
-            num = evalCubic(res, num, true, true, null,
-                            y1, ctrly1, ctrly2, y2);
-            // odd counts imply the crossing was out of [0,1] bounds
-            // otherwise there is no way for that part of the curve to
-            // "return" to meet its endpoint
-            return (num == 2 &&
-                    getTag(res[0], y, y+h) * getTag(res[1], y, y+h) <= 0);
-        }
-
-        // The X and Y ranges of the endpoints overlap the X and Y
-        // ranges of the rectangle, now find out how the endpoint
-        // line segment intersects the Y range of the rectangle
-        double dx = x2 - x1;
-        double dy = y2 - y1;
-        double k = y2 * x1 - x2 * y1;
-        int c1tag, c2tag;
-        if (y1tag == INSIDE) {
-            c1tag = x1tag;
-        } else {
-            c1tag = getTag((k + dx * (y1tag < INSIDE ? y : y+h)) / dy, x, x+w);
-        }
-        if (y2tag == INSIDE) {
-            c2tag = x2tag;
-        } else {
-            c2tag = getTag((k + dx * (y2tag < INSIDE ? y : y+h)) / dy, x, x+w);
-        }
-        // If the part of the line segment that intersects the Y range
-        // of the rectangle crosses it horizontally - trivially accept
-        if (c1tag * c2tag <= 0) {
-            return true;
-        }
-
-        // Now we know that both the X and Y ranges intersect and that
-        // the endpoint line segment does not directly cross the rectangle.
-        //
-        // We can almost treat this case like one of the cases above
-        // where both endpoints are to one side, except that we may
-        // get one or three intersections of the curve with the vertical
-        // side of the rectangle.  This is because the endpoint segment
-        // accounts for the other intersection in an even pairing.  Thus,
-        // with the endpoint crossing we end up with 2 or 4 total crossings.
-        //
-        // (Remember there is overlap in both the X and Y ranges which
-        //  means that the segment itself must cross at least one vertical
-        //  edge of the rectangle - in particular, the "near vertical side"
-        //  - leaving an odd number of intersections for the curve.)
-        //
-        // Now we calculate the y tags of all the intersections on the
-        // "near vertical side" of the rectangle.  We will have one with
-        // the endpoint segment, and one or three with the curve.  If
-        // any pair of those vertical intersections overlap the Y range
-        // of the rectangle, we have an intersection.  Otherwise, we don't.
-
-        // c1tag = vertical intersection class of the endpoint segment
-        //
-        // Choose the y tag of the endpoint that was not on the same
-        // side of the rectangle as the subsegment calculated above.
-        // Note that we can "steal" the existing Y tag of that endpoint
-        // since it will be provably the same as the vertical intersection.
-        c1tag = ((c1tag * x1tag <= 0) ? y1tag : y2tag);
-
-        // Now we have to calculate an array of solutions of the curve
-        // with the "near vertical side" of the rectangle.  Then we
-        // need to sort the tags and do a pairwise range test to see
-        // if either of the pairs of crossings spans the Y range of
-        // the rectangle.
-        //
-        // Note that the c2tag can still tell us which vertical edge
-        // to test against.
-        fillEqn(eqn, (c2tag < INSIDE ? x : x+w), x1, ctrlx1, ctrlx2, x2);
-        int num = solveCubic(eqn, res);
-        num = evalCubic(res, num, true, true, null, y1, ctrly1, ctrly2, y2);
-
-        // Now put all of the tags into a bucket and sort them.  There
-        // is an intersection iff one of the pairs of tags "spans" the
-        // Y range of the rectangle.
-        int tags[] = new int[num+1];
-        for (int i = 0; i < num; i++) {
-            tags[i] = getTag(res[i], y, y+h);
-        }
-        tags[num] = c1tag;
-        Arrays.sort(tags);
-        return ((num >= 1 && tags[0] * tags[1] <= 0) ||
-                (num >= 3 && tags[2] * tags[3] <= 0));
+        int numCrossings = rectCrossings(x, y, w, h);
+        // the intended return value is
+        // numCrossings != 0 || numCrossings == Curve.RECT_INTERSECTS
+        // but if (numCrossings != 0) numCrossings == INTERSECTS won't matter
+        // and if !(numCrossings != 0) then numCrossings == 0, so
+        // numCrossings != RECT_INTERSECT
+        return numCrossings != 0;
     }
 
     /**
@@ -1602,20 +1412,32 @@
         if (w <= 0 || h <= 0) {
             return false;
         }
-        // Assertion: Cubic curves closed by connecting their
-        // endpoints form either one or two convex halves with
-        // the closing line segment as an edge of both sides.
-        if (!(contains(x, y) &&
-              contains(x + w, y) &&
-              contains(x + w, y + h) &&
-              contains(x, y + h))) {
-            return false;
+
+        int numCrossings = rectCrossings(x, y, w, h);
+        return !(numCrossings == 0 || numCrossings == Curve.RECT_INTERSECTS);
+    }
+
+    private int rectCrossings(double x, double y, double w, double h) {
+        int crossings = 0;
+        if (!(getX1() == getX2() && getY1() == getY2())) {
+            crossings = Curve.rectCrossingsForLine(crossings,
+                                                   x, y,
+                                                   x+w, y+h,
+                                                   getX1(), getY1(),
+                                                   getX2(), getY2());
+            if (crossings == Curve.RECT_INTERSECTS) {
+                return crossings;
+            }
         }
-        // Either the rectangle is entirely inside one of the convex
-        // halves or it crosses from one to the other, in which case
-        // it must intersect the closing line segment.
-        Rectangle2D rect = new Rectangle2D.Double(x, y, w, h);
-        return !rect.intersectsLine(getX1(), getY1(), getX2(), getY2());
+        // we call this with the curve's direction reversed, because we wanted
+        // to call rectCrossingsForLine first, because it's cheaper.
+        return Curve.rectCrossingsForCubic(crossings,
+                                           x, y,
+                                           x+w, y+h,
+                                           getX2(), getY2(),
+                                           getCtrlX2(), getCtrlY2(),
+                                           getCtrlX1(), getCtrlY1(),
+                                           getX1(), getY1(), 0);
     }
 
     /**
--- a/src/share/classes/java/io/ObjectStreamClass.java	Thu Feb 10 21:36:18 2011 +0300
+++ b/src/share/classes/java/io/ObjectStreamClass.java	Fri Feb 11 12:14:38 2011 -0800
@@ -329,7 +329,7 @@
                 entry = th;
             }
             if (future.set(entry)) {
-                Caches.localDescs.put(key, new SoftReference<>(entry));
+                Caches.localDescs.put(key, new SoftReference<Object>(entry));
             } else {
                 // nested lookup call already set future
                 entry = future.get();
@@ -2118,7 +2118,7 @@
                 entry = th;
             }
             future.set(entry);
-            Caches.reflectors.put(key, new SoftReference<>(entry));
+            Caches.reflectors.put(key, new SoftReference<Object>(entry));
         }
 
         if (entry instanceof FieldReflector) {
--- a/src/share/classes/java/io/PrintStream.java	Thu Feb 10 21:36:18 2011 +0300
+++ b/src/share/classes/java/io/PrintStream.java	Fri Feb 11 12:14:38 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -27,7 +27,9 @@
 
 import java.util.Formatter;
 import java.util.Locale;
-
+import java.nio.charset.Charset;
+import java.nio.charset.IllegalCharsetNameException;
+import java.nio.charset.UnsupportedCharsetException;
 
 /**
  * A <code>PrintStream</code> adds functionality to another output stream,
@@ -56,7 +58,7 @@
     implements Appendable, Closeable
 {
 
-    private boolean autoFlush = false;
+    private final boolean autoFlush;
     private boolean trouble = false;
     private Formatter formatter;
 
@@ -68,6 +70,60 @@
     private OutputStreamWriter charOut;
 
     /**
+     * nonNull is explicitly declared here so as not to create an extra
+     * dependency on java.util.Objects.nonNull. PrintStream is loaded
+     * early during system initialization.
+     */
+    private static <T> T nonNull(T obj, String message) {
+        if (obj == null)
+            throw new NullPointerException(message);
+        return obj;
+    }
+
+    /**
+     * Returns a charset object for the given charset name.
+     * @throws NullPointerException          is csn is null
+     * @throws UnsupportedEncodingException  if the charset is not supported
+     */
+    private static Charset toCharset(String csn)
+        throws UnsupportedEncodingException
+    {
+        nonNull(csn, "charsetName");
+        try {
+            return Charset.forName(csn);
+        } catch (IllegalCharsetNameException|UnsupportedCharsetException unused) {
+            // UnsupportedEncodingException should be thrown
+            throw new UnsupportedEncodingException(csn);
+        }
+    }
+
+    /* Private constructors */
+    private PrintStream(boolean autoFlush, OutputStream out) {
+        super(out);
+        this.autoFlush = autoFlush;
+        this.charOut = new OutputStreamWriter(this);
+        this.textOut = new BufferedWriter(charOut);
+    }
+
+    private PrintStream(boolean autoFlush, OutputStream out, Charset charset) {
+        super(out);
+        this.autoFlush = autoFlush;
+        this.charOut = new OutputStreamWriter(this, charset);
+        this.textOut = new BufferedWriter(charOut);
+    }
+
+    /* Variant of the private constructor so that the given charset name
+     * can be verified before evaluating the OutputStream argument. Used
+     * by constructors creating a FileOutputStream that also take a
+     * charset name.
+     */
+    private PrintStream(boolean autoFlush, Charset charset, OutputStream out)
+        throws UnsupportedEncodingException
+    {
+        this(autoFlush, out, charset);
+    }
+
+    /**
      * Creates a new print stream.  This stream will not flush automatically.
      *
      * @param  out        The output stream to which values and objects will be
@@ -79,27 +135,6 @@
         this(out, false);
     }
 
-    /* Initialization is factored into a private constructor (note the swapped
-     * parameters so that this one isn't confused with the public one) and a
-     * separate init method so that the following two public constructors can
-     * share code.  We use a separate init method so that the constructor that
-     * takes an encoding will throw an NPE for a null stream before it throws
-     * an UnsupportedEncodingException for an unsupported encoding.
-     */
-
-    private PrintStream(boolean autoFlush, OutputStream out)
-    {
-        super(out);
-        if (out == null)
-            throw new NullPointerException("Null output stream");
-        this.autoFlush = autoFlush;
-    }
-
-    private void init(OutputStreamWriter osw) {
-        this.charOut = osw;
-        this.textOut = new BufferedWriter(osw);
-    }
-
     /**
      * Creates a new print stream.
      *
@@ -113,8 +148,7 @@
      * @see java.io.PrintWriter#PrintWriter(java.io.OutputStream, boolean)
      */
     public PrintStream(OutputStream out, boolean autoFlush) {
-        this(autoFlush, out);
-        init(new OutputStreamWriter(this));
+        this(autoFlush, nonNull(out, "Null output stream"));
     }
 
     /**
@@ -138,8 +172,9 @@
     public PrintStream(OutputStream out, boolean autoFlush, String encoding)
         throws UnsupportedEncodingException
     {
-        this(autoFlush, out);
-        init(new OutputStreamWriter(this, encoding));
+        this(autoFlush,
+             nonNull(out, "Null output stream"),
+             toCharset(encoding));
     }
 
     /**
@@ -171,7 +206,6 @@
      */
     public PrintStream(String fileName) throws FileNotFoundException {
         this(false, new FileOutputStream(fileName));
-        init(new OutputStreamWriter(this));
     }
 
     /**
@@ -210,8 +244,8 @@
     public PrintStream(String fileName, String csn)
         throws FileNotFoundException, UnsupportedEncodingException
     {
-        this(false, new FileOutputStream(fileName));
-        init(new OutputStreamWriter(this, csn));
+        // ensure charset is checked before the file is opened
+        this(false, toCharset(csn), new FileOutputStream(fileName));
     }
 
     /**
@@ -243,7 +277,6 @@
      */
     public PrintStream(File file) throws FileNotFoundException {
         this(false, new FileOutputStream(file));
-        init(new OutputStreamWriter(this));
     }
 
     /**
@@ -282,8 +315,8 @@
     public PrintStream(File file, String csn)
         throws FileNotFoundException, UnsupportedEncodingException
     {
-        this(false, new FileOutputStream(file));
-        init(new OutputStreamWriter(this, csn));
+        // ensure charset is checked before the file is opened
+        this(false, toCharset(csn), new FileOutputStream(file));
     }
 
     /** Check to make sure that the stream has not been closed */
--- a/src/share/classes/java/io/PrintWriter.java	Thu Feb 10 21:36:18 2011 +0300
+++ b/src/share/classes/java/io/PrintWriter.java	Fri Feb 11 12:14:38 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -25,8 +25,12 @@
 
 package java.io;
 
+import java.util.Objects;
 import java.util.Formatter;
 import java.util.Locale;
+import java.nio.charset.Charset;
+import java.nio.charset.IllegalCharsetNameException;
+import java.nio.charset.UnsupportedCharsetException;
 
 /**
  * Prints formatted representations of objects to a text-output stream.  This
@@ -59,7 +63,7 @@
      */
     protected Writer out;
 
-    private boolean autoFlush = false;
+    private final boolean autoFlush;
     private boolean trouble = false;
     private Formatter formatter;
     private PrintStream psOut = null;
@@ -68,7 +72,24 @@
      * Line separator string.  This is the value of the line.separator
      * property at the moment that the stream was created.
      */
-    private String lineSeparator;
+    private final String lineSeparator;
+
+    /**
+     * Returns a charset object for the given charset name.
+     * @throws NullPointerException          is csn is null
+     * @throws UnsupportedEncodingException  if the charset is not supported
+     */
+    private static Charset toCharset(String csn)
+        throws UnsupportedEncodingException
+    {
+        Objects.nonNull(csn, "charsetName");
+        try {
+            return Charset.forName(csn);
+        } catch (IllegalCharsetNameException|UnsupportedCharsetException unused) {
+            // UnsupportedEncodingException should be thrown
+            throw new UnsupportedEncodingException(csn);
+        }
+    }
 
     /**
      * Creates a new PrintWriter, without automatic line flushing.
@@ -164,6 +185,14 @@
              false);
     }
 
+    /* Private constructor */
+    private PrintWriter(Charset charset, File file)
+        throws FileNotFoundException
+    {
+        this(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), charset)),
+             false);
+    }
+
     /**
      * Creates a new PrintWriter, without automatic line flushing, with the
      * specified file name and charset.  This convenience constructor creates
@@ -200,8 +229,7 @@
     public PrintWriter(String fileName, String csn)
         throws FileNotFoundException, UnsupportedEncodingException
     {
-        this(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileName), csn)),
-             false);
+        this(toCharset(csn), new File(fileName));
     }
 
     /**
@@ -272,8 +300,7 @@
     public PrintWriter(File file, String csn)
         throws FileNotFoundException, UnsupportedEncodingException
     {
-        this(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), csn)),
-             false);
+        this(toCharset(csn), file);
     }
 
     /** Checks to make sure that the stream has not been closed */
--- a/src/share/classes/java/lang/AutoCloseable.java	Thu Feb 10 21:36:18 2011 +0300
+++ b/src/share/classes/java/lang/AutoCloseable.java	Fri Feb 11 12:14:38 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 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
@@ -33,7 +33,7 @@
  */
 public interface AutoCloseable {
     /**
-     * Close this resource, relinquishing any underlying resources.
+     * Closes this resource, relinquishing any underlying resources.
      * This method is invoked automatically by the {@code
      * try}-with-resources statement.
      *
@@ -48,6 +48,10 @@
      * visible side effect, unlike {@code Closeable.close} which is
      * required to have no effect if called more than once.
      *
+     * However, while not required to be idempotent, implementers of
+     * this interface are strongly encouraged to make their {@code
+     * close} methods idempotent.
+     *
      * @throws Exception if this resource cannot be closed
      */
     void close() throws Exception;
--- a/src/share/classes/java/lang/StringCoding.java	Thu Feb 10 21:36:18 2011 +0300
+++ b/src/share/classes/java/lang/StringCoding.java	Fri Feb 11 12:14:38 2011 -0800
@@ -67,7 +67,7 @@
     }
 
     private static <T> void set(ThreadLocal<SoftReference<T>> tl, T ob) {
-        tl.set(new SoftReference<>(ob));
+        tl.set(new SoftReference<T>(ob));
     }
 
     // Trim the given byte array to the given length
--- a/src/share/classes/java/lang/Throwable.java	Thu Feb 10 21:36:18 2011 +0300
+++ b/src/share/classes/java/lang/Throwable.java	Fri Feb 11 12:14:38 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 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
@@ -809,7 +809,7 @@
     native StackTraceElement getStackTraceElement(int index);
 
     /**
-     * Read a {@code Throwable} from a stream, enforcing
+     * Reads a {@code Throwable} from a stream, enforcing
      * well-formedness constraints on fields.  Null entries and
      * self-pointers are not allowed in the list of {@code
      * suppressedExceptions}.  Null entries are not allowed for stack
@@ -865,9 +865,10 @@
     }
 
     /**
-     * Adds the specified exception to the list of exceptions that
-     * were suppressed, typically by the {@code try}-with-resources
-     * statement, in order to deliver this exception.
+     * Appends the specified exception to the exceptions that were
+     * suppressed in order to deliver this exception. This method is
+     * typically called (automatically and implicitly) by the {@code
+     * try}-with-resources statement.
      *
      * If the first exception to be suppressed is {@code null}, that
      * indicates suppressed exception information will <em>not</em> be
--- a/src/share/classes/java/net/InetAddress.java	Thu Feb 10 21:36:18 2011 +0300
+++ b/src/share/classes/java/net/InetAddress.java	Fri Feb 11 12:14:38 2011 -0800
@@ -677,8 +677,7 @@
 
     static InetAddressImpl  impl;
 
-    private static HashMap<String, InetAddress[]> lookupTable
-        = new HashMap<String, InetAddress[]>();
+    private static final HashMap<String, Void> lookupTable = new HashMap<>();
 
     /**
      * Represents a cache entry
@@ -737,7 +736,7 @@
 
                 // As we iterate in insertion order we can
                 // terminate when a non-expired entry is found.
-                LinkedList<String> expired = new LinkedList<String>();
+                LinkedList<String> expired = new LinkedList<>();
                 long now = System.currentTimeMillis();
                 for (String key : cache.keySet()) {
                     CacheEntry entry = cache.get(key);
@@ -1227,43 +1226,45 @@
         //         lookupTable and return null so the
         //         following code would do  a lookup itself.
         if ((addresses = checkLookupTable(host)) == null) {
-            // This is the first thread which looks up the addresses
-            // this host or the cache entry for this host has been
-            // expired so this thread should do the lookup.
-            for (NameService nameService : nameServices) {
-                try {
-                    /*
-                     * Do not put the call to lookup() inside the
-                     * constructor.  if you do you will still be
-                     * allocating space when the lookup fails.
-                     */
+            try {
+                // This is the first thread which looks up the addresses
+                // this host or the cache entry for this host has been
+                // expired so this thread should do the lookup.
+                for (NameService nameService : nameServices) {
+                    try {
+                        /*
+                         * Do not put the call to lookup() inside the
+                         * constructor.  if you do you will still be
+                         * allocating space when the lookup fails.
+                         */
 
-                    addresses = nameService.lookupAllHostAddr(host);
-                    success = true;
-                    break;
-                } catch (UnknownHostException uhe) {
-                    if (host.equalsIgnoreCase("localhost")) {
-                        InetAddress[] local = new InetAddress[] { impl.loopbackAddress() };
-                        addresses = local;
+                        addresses = nameService.lookupAllHostAddr(host);
                         success = true;
                         break;
-                    }
-                    else {
-                        addresses = unknown_array;
-                        success = false;
-                        ex = uhe;
+                    } catch (UnknownHostException uhe) {
+                        if (host.equalsIgnoreCase("localhost")) {
+                            InetAddress[] local = new InetAddress[] { impl.loopbackAddress() };
+                            addresses = local;
+                            success = true;
+                            break;
+                        }
+                        else {
+                            addresses = unknown_array;
+                            success = false;
+                            ex = uhe;
+                        }
                     }
                 }
+
+                // Cache the addresses.
+                cacheAddresses(host, addresses, success);
+                if (!success && ex != null)
+                    throw ex;
+            } finally {
+                // Delete host from the lookupTable and notify
+                // all threads waiting on the lookupTable monitor.
+                updateLookupTable(host);
             }
-
-            // Cache the addresses.
-            cacheAddresses(host, addresses, success);
-            // Delete the host from the lookupTable, and
-            // notify all threads waiting for the monitor
-            // for lookupTable.
-            updateLookupTable(host);
-            if (!success && ex != null)
-                throw ex;
         }
 
         return addresses;
@@ -1271,16 +1272,13 @@
 
 
     private static InetAddress[] checkLookupTable(String host) {
-        // make sure addresses is null.
-        InetAddress[] addresses = null;
-
         synchronized (lookupTable) {
             // If the host isn't in the lookupTable, add it in the
             // lookuptable and return null. The caller should do
             // the lookup.
             if (lookupTable.containsKey(host) == false) {
                 lookupTable.put(host, null);
-                return addresses;
+                return null;
             }
 
             // If the host is in the lookupTable, it means that another
@@ -1298,10 +1296,11 @@
         // the host. This thread should retry to get the addresses
         // from the addressCache. If it doesn't get the addresses from
         // the cache, it will try to look up the addresses itself.
-        addresses = getCachedAddresses(host);
+        InetAddress[] addresses = getCachedAddresses(host);
         if (addresses == null) {
             synchronized (lookupTable) {
                 lookupTable.put(host, null);
+                return null;
             }
         }
 
--- a/src/share/classes/java/net/NetworkInterface.java	Thu Feb 10 21:36:18 2011 +0300
+++ b/src/share/classes/java/net/NetworkInterface.java	Fri Feb 11 12:14:38 2011 -0800
@@ -493,55 +493,44 @@
      * @see     java.net.InetAddress#getAddress()
      */
     public boolean equals(Object obj) {
-        if ((obj == null) || !(obj instanceof NetworkInterface)) {
+        if (!(obj instanceof NetworkInterface)) {
             return false;
         }
-        NetworkInterface netIF = (NetworkInterface)obj;
-        if (name != null ) {
-            if (netIF.getName() != null) {
-                if (!name.equals(netIF.getName())) {
-                    return false;
-                }
-            } else {
+        NetworkInterface that = (NetworkInterface)obj;
+        if (this.name != null ) {
+            if (!this.name.equals(that.name)) {
                 return false;
             }
         } else {
-            if (netIF.getName() != null) {
+            if (that.name != null) {
                 return false;
             }
         }
-        Enumeration newAddrs = netIF.getInetAddresses();
-        int i = 0;
-        for (i = 0; newAddrs.hasMoreElements();newAddrs.nextElement(), i++);
-        if (addrs == null) {
-            if (i != 0) {
-                return false;
-            }
-        } else {
-            /*
-             * Compare number of addresses (in the checked subset)
-             */
-            int count = 0;
-            Enumeration e = getInetAddresses();
-            for (; e.hasMoreElements(); count++) {
-                e.nextElement();
-            }
-            if (i != count) {
-                return false;
-            }
+
+        if (this.addrs == null) {
+            return that.addrs == null;
+        } else if (that.addrs == null) {
+            return false;
         }
-        newAddrs = netIF.getInetAddresses();
-        for (; newAddrs.hasMoreElements();) {
-            boolean equal = false;
-            Enumeration thisAddrs = getInetAddresses();
-            InetAddress newAddr = (InetAddress)newAddrs.nextElement();
-            for (; thisAddrs.hasMoreElements();) {
-                InetAddress thisAddr = (InetAddress)thisAddrs.nextElement();
-                if (thisAddr.equals(newAddr)) {
-                    equal = true;
+
+        /* Both addrs not null. Compare number of addresses */
+
+        if (this.addrs.length != that.addrs.length) {
+            return false;
+        }
+
+        InetAddress[] thatAddrs = that.addrs;
+        int count = thatAddrs.length;
+
+        for (int i=0; i<count; i++) {
+            boolean found = false;
+            for (int j=0; j<count; j++) {
+                if (addrs[i].equals(thatAddrs[j])) {
+                    found = true;
+                    break;
                 }
             }
-            if (!equal) {
+            if (!found) {
                 return false;
             }
         }
@@ -549,12 +538,7 @@
     }
 
     public int hashCode() {
-        int count = name == null? 0: name.hashCode();
-        Enumeration<InetAddress> addrs = getInetAddresses();
-        while (addrs.hasMoreElements()) {
-            count += addrs.nextElement().hashCode();
-        }
-        return count;
+        return name == null? 0: name.hashCode();
     }
 
     public String toString() {
--- a/src/share/classes/java/net/SocksSocketImpl.java	Thu Feb 10 21:36:18 2011 +0300
+++ b/src/share/classes/java/net/SocksSocketImpl.java	Fri Feb 11 12:14:38 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -29,6 +29,7 @@
 import java.io.BufferedOutputStream;
 import java.security.AccessController;
 import java.security.PrivilegedExceptionAction;
+import sun.net.SocksProxy;
 import sun.net.www.ParseUtil;
 /* import org.ietf.jgss.*; */
 
@@ -397,6 +398,11 @@
                 // Use getHostString() to avoid reverse lookups
                 server = ((InetSocketAddress) p.address()).getHostString();
                 serverPort = ((InetSocketAddress) p.address()).getPort();
+                if (p instanceof SocksProxy) {
+                    if (((SocksProxy)p).protocolVersion() == 4) {
+                        useV4 = true;
+                    }
+                }
 
                 // Connects to the SOCKS server
                 try {
@@ -700,6 +706,11 @@
                 // Use getHostString() to avoid reverse lookups
                 server = ((InetSocketAddress) p.address()).getHostString();
                 serverPort = ((InetSocketAddress) p.address()).getPort();
+                if (p instanceof SocksProxy) {
+                    if (((SocksProxy)p).protocolVersion() == 4) {
+                        useV4 = true;
+                    }
+                }
 
                 // Connects to the SOCKS server
                 try {
--- a/src/share/classes/java/net/URLClassLoader.java	Thu Feb 10 21:36:18 2011 +0300
+++ b/src/share/classes/java/net/URLClassLoader.java	Fri Feb 11 12:14:38 2011 -0800
@@ -27,19 +27,15 @@
 
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
-import java.io.File;
-import java.io.FilePermission;
-import java.io.InputStream;
-import java.io.IOException;
-import java.io.Closeable;
+import java.lang.ref.*;
+import java.io.*;
 import java.net.URL;
 import java.net.URLConnection;
 import java.net.URLStreamHandlerFactory;
 import java.util.Enumeration;
-import java.util.List;
-import java.util.NoSuchElementException;
-import java.util.StringTokenizer;
+import java.util.*;
 import java.util.jar.Manifest;
+import java.util.jar.JarFile;
 import java.util.jar.Attributes;
 import java.util.jar.Attributes.Name;
 import java.security.CodeSigner;
@@ -194,6 +190,65 @@
         acc = AccessController.getContext();
     }
 
+    /* A map (used as a set) to keep track of closeable local resources
+     * (either JarFiles or FileInputStreams). We don't care about
+     * Http resources since they don't need to be closed.
+     *
+     * If the resource is coming from a jar file
+     * we keep a (weak) reference to the JarFile object which can
+     * be closed if URLClassLoader.close() called. Due to jar file
+     * caching there will typically be only one JarFile object
+     * per underlying jar file.
+     *
+     * For file resources, which is probably a less common situation
+     * we have to keep a weak reference to each stream.
+     */
+
+    private WeakHashMap<Closeable,Void>
+        closeables = new WeakHashMap<>();
+
+    /**
+     * Returns an input stream for reading the specified resource.
+     * If this loader is closed, then any resources opened by this method
+     * will be closed.
+     *
+     * <p> The search order is described in the documentation for {@link
+     * #getResource(String)}.  </p>
+     *
+     * @param  name
+     *         The resource name
+     *
+     * @return  An input stream for reading the resource, or <tt>null</tt>
+     *          if the resource could not be found
+     *
+     * @since  1.7
+     */
+    public InputStream getResourceAsStream(String name) {
+        URL url = getResource(name);
+        try {
+            if (url == null) {
+                return null;
+            }
+            URLConnection urlc = url.openConnection();
+            InputStream is = urlc.getInputStream();
+            if (urlc instanceof JarURLConnection) {
+                JarURLConnection juc = (JarURLConnection)urlc;
+                JarFile jar = juc.getJarFile();
+                synchronized (closeables) {
+                    if (!closeables.containsKey(jar)) {
+                        closeables.put(jar, null);
+                    }
+                }
+            } else if (urlc instanceof sun.net.www.protocol.file.FileURLConnection) {
+                synchronized (closeables) {
+                    closeables.put(is, null);
+                }
+            }
+            return is;
+        } catch (IOException e) {
+            return null;
+        }
+    }
 
    /**
     * Closes this URLClassLoader, so that it can no longer be used to load
@@ -202,8 +257,8 @@
     * delegation hierarchy are still accessible. Also, any classes or resources
     * that are already loaded, are still accessible.
     * <p>
-    * In the case of jar: and file: URLs, it also closes any class files,
-    * or JAR files that were opened by it. If another thread is loading a
+    * In the case of jar: and file: URLs, it also closes any files
+    * that were opened by it. If another thread is loading a
     * class when the {@code close} method is invoked, then the result of
     * that load is undefined.
     * <p>
@@ -213,10 +268,10 @@
     * loader has no effect.
     * <p>
     * @throws IOException if closing any file opened by this class loader
-    * resulted in an IOException. Any such exceptions are caught, and a
-    * single IOException is thrown after the last file has been closed.
-    * If only one exception was thrown, it will be set as the <i>cause</i>
-    * of this IOException.
+    * resulted in an IOException. Any such exceptions are caught internally.
+    * If only one is caught, then it is re-thrown. If more than one exception
+    * is caught, then the second and following exceptions are added
+    * as suppressed exceptions of the first one caught, which is then re-thrown.
     *
     * @throws SecurityException if a security manager is set, and it denies
     *   {@link RuntimePermission}<tt>("closeClassLoader")</tt>
@@ -229,21 +284,33 @@
             security.checkPermission(new RuntimePermission("closeClassLoader"));
         }
         List<IOException> errors = ucp.closeLoaders();
+
+        // now close any remaining streams.
+
+        synchronized (closeables) {
+            Set<Closeable> keys = closeables.keySet();
+            for (Closeable c : keys) {
+                try {
+                    c.close();
+                } catch (IOException ioex) {
+                    errors.add(ioex);
+                }
+            }
+            closeables.clear();
+        }
+
         if (errors.isEmpty()) {
             return;
         }
-        if (errors.size() == 1) {
-            throw new IOException (
-                "Error closing URLClassLoader resource",
-                errors.get(0)
-            );
+
+        IOException firstex = errors.remove(0);
+
+        // Suppress any remaining exceptions
+
+        for (IOException error: errors) {
+            firstex.addSuppressed(error);
         }
-        // Several exceptions. So, just combine the error messages
-        String errormsg = "Error closing resources: ";
-        for (IOException error: errors) {
-            errormsg = errormsg + "[" + error.toString() + "] ";
-        }
-        throw new IOException (errormsg);
+        throw firstex;
     }
 
     /**
--- a/src/share/classes/java/net/doc-files/net-properties.html	Thu Feb 10 21:36:18 2011 +0300
+++ b/src/share/classes/java/net/doc-files/net-properties.html	Fri Feb 11 12:14:38 2011 -0800
@@ -127,10 +127,15 @@
 	are specified. If SOCKS is supported by a Java SE implementation, the
 	following properties will be used:</P>
 	<UL>
-		<LI><P><B>socksProxyHost</B> (default: &lt;non&gt;)<BR>
+		<LI><P><B>socksProxyHost</B> (default: &lt;none&gt;)<BR>
 	        The hostname, or address, of the proxy server.</P>
 		<LI><P><B>socksProxyPort</B> (default: 1080)<BR>
 	        The port number of the proxy server.</P>
+                <LI><P><B>socksProxyVersion</B> (default: 5)<BR>
+                The version of the SOCKS protocol supported by the server. The
+                default is <code>5</code> indicating SOCKS V5, alternatively
+                <code>4</code> can be specified for SOCKS V4. Setting the property
+                to values other than these leads to unspecified behavior.</P>
 		<LI><P><B>java.net.socks.username</B> (default: &lt;none&gt;)<BR>
 	        Username to use if the SOCKSv5 server asks for authentication
 	        and no java.net.Authenticator instance was found.</P>
--- a/src/share/classes/java/security/AccessControlContext.java	Thu Feb 10 21:36:18 2011 +0300
+++ b/src/share/classes/java/security/AccessControlContext.java	Fri Feb 11 12:14:38 2011 -0800
@@ -121,7 +121,7 @@
                 this.context = null;
             }
         } else {
-            List<ProtectionDomain> v = new ArrayList<ProtectionDomain>(context.length);
+            List<ProtectionDomain> v = new ArrayList<>(context.length);
             for (int i =0; i< context.length; i++) {
                 if ((context[i] != null) &&  (!v.contains(context[i])))
                     v.add(context[i]);
--- a/src/share/classes/java/security/BasicPermission.java	Thu Feb 10 21:36:18 2011 +0300
+++ b/src/share/classes/java/security/BasicPermission.java	Fri Feb 11 12:14:38 2011 -0800
@@ -515,7 +515,7 @@
 
         // Copy perms into a Hashtable
         Hashtable<String, Permission> permissions =
-                new Hashtable<String, Permission>(perms.size()*2);
+                new Hashtable<>(perms.size()*2);
 
         synchronized (this) {
             permissions.putAll(perms);
--- a/src/share/classes/java/security/CodeSource.java	Thu Feb 10 21:36:18 2011 +0300
+++ b/src/share/classes/java/security/CodeSource.java	Fri Feb 11 12:14:38 2011 -0800
@@ -188,7 +188,7 @@
         } else if (signers != null) {
             // Convert the code signers to certs
             ArrayList<java.security.cert.Certificate> certChains =
-                        new ArrayList<java.security.cert.Certificate>();
+                        new ArrayList<>();
             for (int i = 0; i < signers.length; i++) {
                 certChains.addAll(
                     signers[i].getSignerCertPath().getCertificates());
@@ -606,10 +606,10 @@
 
             // Iterate through all the certificates
             int i = 0;
-            List<CodeSigner> signers = new ArrayList<CodeSigner>();
+            List<CodeSigner> signers = new ArrayList<>();
             while (i < certs.length) {
                 List<java.security.cert.Certificate> certChain =
-                        new ArrayList<java.security.cert.Certificate>();
+                        new ArrayList<>();
                 certChain.add(certs[i++]); // first cert is an end-entity cert
                 int j = i;
 
--- a/src/share/classes/java/security/Permissions.java	Thu Feb 10 21:36:18 2011 +0300
+++ b/src/share/classes/java/security/Permissions.java	Fri Feb 11 12:14:38 2011 -0800
@@ -362,7 +362,7 @@
 
         // Copy perms into a Hashtable
         Hashtable<Class<?>, PermissionCollection> perms =
-            new Hashtable<Class<?>, PermissionCollection>(permsMap.size()*2); // no sync; estimate
+            new Hashtable<>(permsMap.size()*2); // no sync; estimate
         synchronized (this) {
             perms.putAll(permsMap);
         }
@@ -567,7 +567,7 @@
 
         // Copy perms into a Hashtable
         Hashtable<Permission, Permission> perms =
-                new Hashtable<Permission, Permission>(permsMap.size()*2);
+                new Hashtable<>(permsMap.size()*2);
         synchronized (this) {
             perms.putAll(permsMap);
         }
--- a/src/share/classes/java/security/ProtectionDomain.java	Thu Feb 10 21:36:18 2011 +0300
+++ b/src/share/classes/java/security/ProtectionDomain.java	Fri Feb 11 12:14:38 2011 -0800
@@ -336,8 +336,8 @@
         int swag = 32;
         int vcap = 8;
         Enumeration<Permission> e;
-        List<Permission> pdVector = new ArrayList<Permission>(vcap);
-        List<Permission> plVector = new ArrayList<Permission>(swag);
+        List<Permission> pdVector = new ArrayList<>(vcap);
+        List<Permission> plVector = new ArrayList<>(swag);
 
         //
         // Build a vector of domain permissions for subsequent merge
--- a/src/share/classes/java/security/Provider.java	Thu Feb 10 21:36:18 2011 +0300
+++ b/src/share/classes/java/security/Provider.java	Fri Feb 11 12:14:38 2011 -0800
@@ -437,7 +437,7 @@
 
     private void readObject(ObjectInputStream in)
                 throws IOException, ClassNotFoundException {
-        Map<Object,Object> copy = new HashMap<Object,Object>();
+        Map<Object,Object> copy = new HashMap<>();
         for (Map.Entry<Object,Object> entry : super.entrySet()) {
             copy.put(entry.getKey(), entry.getValue());
         }
@@ -719,7 +719,7 @@
         }
         if (serviceSet == null) {
             ensureLegacyParsed();
-            Set<Service> set = new LinkedHashSet<Service>();
+            Set<Service> set = new LinkedHashSet<>();
             if (serviceMap != null) {
                 set.addAll(serviceMap.values());
             }
@@ -1395,7 +1395,7 @@
                     if (s != null) {
                         String[] classNames = s.split("\\|");
                         List<Class> classList =
-                            new ArrayList<Class>(classNames.length);
+                            new ArrayList<>(classNames.length);
                         for (String className : classNames) {
                             Class clazz = getKeyClass(className);
                             if (clazz != null) {
--- a/src/share/classes/java/security/SecureClassLoader.java	Thu Feb 10 21:36:18 2011 +0300
+++ b/src/share/classes/java/security/SecureClassLoader.java	Fri Feb 11 12:14:38 2011 -0800
@@ -50,7 +50,7 @@
     // HashMap that maps CodeSource to ProtectionDomain
     // @GuardedBy("pdcache")
     private final HashMap<CodeSource, ProtectionDomain> pdcache =
-                        new HashMap<CodeSource, ProtectionDomain>(11);
+                        new HashMap<>(11);
 
     private static final Debug debug = Debug.getInstance("scl");
 
--- a/src/share/classes/java/security/Security.java	Thu Feb 10 21:36:18 2011 +0300
+++ b/src/share/classes/java/security/Security.java	Fri Feb 11 12:14:38 2011 -0800
@@ -545,8 +545,7 @@
             value = filter.substring(index + 1);
         }
 
-        Hashtable<String, String> hashtableFilter =
-                new Hashtable<String, String>(1);
+        Hashtable<String, String> hashtableFilter = new Hashtable<>(1);
         hashtableFilter.put(key, value);
 
         return (getProviders(hashtableFilter));
@@ -606,7 +605,7 @@
         // Then only return those providers who satisfy the selection criteria.
         Provider[] allProviders = Security.getProviders();
         Set<String> keySet = filter.keySet();
-        LinkedHashSet<Provider> candidates = new LinkedHashSet<Provider>(5);
+        LinkedHashSet<Provider> candidates = new LinkedHashSet<>(5);
 
         // Returns all installed providers
         // if the selection criteria is null.
@@ -660,8 +659,7 @@
     }
 
     // Map containing cached Spi Class objects of the specified type
-    private static final Map<String,Class> spiMap =
-                                new ConcurrentHashMap<String,Class>();
+    private static final Map<String, Class> spiMap = new ConcurrentHashMap<>();
 
     /**
      * Return the Class object for the given engine type
@@ -885,7 +883,7 @@
                                                 String attrName,
                                                 String filterValue,
                                                 Provider[] allProviders) {
-        LinkedHashSet<Provider> candidates = new LinkedHashSet<Provider>(5);
+        LinkedHashSet<Provider> candidates = new LinkedHashSet<>(5);
         for (int i = 0; i < allProviders.length; i++) {
             if (isCriterionSatisfied(allProviders[i], serviceName,
                                      algName,
@@ -1082,7 +1080,7 @@
             return Collections.EMPTY_SET;
         }
 
-        HashSet<String> result = new HashSet<String>();
+        HashSet<String> result = new HashSet<>();
         Provider[] providers = Security.getProviders();
 
         for (int i = 0; i < providers.length; i++) {
--- a/src/share/classes/java/security/UnresolvedPermission.java	Thu Feb 10 21:36:18 2011 +0300
+++ b/src/share/classes/java/security/UnresolvedPermission.java	Fri Feb 11 12:14:38 2011 -0800
@@ -198,7 +198,7 @@
                 if (this.certs == null) {
                     // extract the signer certs
                     ArrayList<java.security.cert.Certificate> signerCerts =
-                        new ArrayList<java.security.cert.Certificate>();
+                        new ArrayList<>();
                     i = 0;
                     while (i < certs.length) {
                         signerCerts.add(certs[i]);
--- a/src/share/classes/java/security/UnresolvedPermissionCollection.java	Thu Feb 10 21:36:18 2011 +0300
+++ b/src/share/classes/java/security/UnresolvedPermissionCollection.java	Fri Feb 11 12:14:38 2011 -0800
@@ -119,7 +119,7 @@
 
     public Enumeration<Permission> elements() {
         List<Permission> results =
-            new ArrayList<Permission>(); // where results are stored
+            new ArrayList<>(); // where results are stored
 
         // Get iterator of Map values (which are lists of permissions)
         synchronized (this) {
@@ -161,7 +161,7 @@
 
         // Copy perms into a Hashtable
         Hashtable<String, Vector<UnresolvedPermission>> permissions =
-            new Hashtable<String, Vector<UnresolvedPermission>>(perms.size()*2);
+            new Hashtable<>(perms.size()*2);
 
         // Convert each entry (List) into a Vector
         synchronized (this) {
@@ -169,8 +169,7 @@
             for (Map.Entry<String, List<UnresolvedPermission>> e : set) {
                 // Convert list into Vector
                 List<UnresolvedPermission> list = e.getValue();
-                Vector<UnresolvedPermission> vec =
-                        new Vector<UnresolvedPermission>(list.size());
+                Vector<UnresolvedPermission> vec = new Vector<>(list.size());
                 synchronized (list) {
                     vec.addAll(list);
                 }
@@ -207,8 +206,7 @@
         for (Map.Entry<String, Vector<UnresolvedPermission>> e : set) {
             // Convert Vector into ArrayList
             Vector<UnresolvedPermission> vec = e.getValue();
-            List<UnresolvedPermission> list =
-                        new ArrayList<UnresolvedPermission>(vec.size());
+            List<UnresolvedPermission> list = new ArrayList<>(vec.size());
             list.addAll(vec);
 
             // Add to Hashtable being serialized
--- a/src/share/classes/java/sql/Timestamp.java	Thu Feb 10 21:36:18 2011 +0300
+++ b/src/share/classes/java/sql/Timestamp.java	Fri Feb 11 12:14:38 2011 -0800
@@ -473,7 +473,9 @@
      * @since   1.4
      */
     public int compareTo(Timestamp ts) {
-        int i = super.compareTo(ts);
+        long thisTime = this.getTime();
+        long anotherTime = ts.getTime();
+        int i = (thisTime<anotherTime ? -1 :(thisTime==anotherTime?0 :1));
         if (i == 0) {
             if (nanos > ts.nanos) {
                     return 1;
--- a/src/share/classes/java/util/Collections.java	Thu Feb 10 21:36:18 2011 +0300
+++ b/src/share/classes/java/util/Collections.java	Fri Feb 11 12:14:38 2011 -0800
@@ -1452,10 +1452,10 @@
              * when o is a Map.Entry, and calls o.setValue.
              */
             public boolean containsAll(Collection<?> coll) {
-                Iterator<?> it = coll.iterator();
-                while (it.hasNext())
-                    if (!contains(it.next())) // Invokes safe contains() above
+                for (Object e : coll) {
+                    if (!contains(e)) // Invokes safe contains() above
                         return false;
+                }
                 return true;
             }
             public boolean equals(Object o) {
@@ -3713,45 +3713,91 @@
     }
 
     /**
-     * Returns <tt>true</tt> if the two specified collections have no
+     * Returns {@code true} if the two specified collections have no
      * elements in common.
      *
      * <p>Care must be exercised if this method is used on collections that
-     * do not comply with the general contract for <tt>Collection</tt>.
+     * do not comply with the general contract for {@code Collection}.
      * Implementations may elect to iterate over either collection and test
      * for containment in the other collection (or to perform any equivalent
      * computation).  If either collection uses a nonstandard equality test
-     * (as does a {@link SortedSet} whose ordering is not <i>compatible with
-     * equals</i>, or the key set of an {@link IdentityHashMap}), both
+     * (as does a {@link SortedSet} whose ordering is not <em>compatible with
+     * equals</em>, or the key set of an {@link IdentityHashMap}), both
      * collections must use the same nonstandard equality test, or the
      * result of this method is undefined.
      *
+     * <p>Care must also be exercised when using collections that have
+     * restrictions on the elements that they may contain. Collection
+     * implementations are allowed to throw exceptions for any operation
+     * involving elements they deem ineligible. For absolute safety the
+     * specified collections should contain only elements which are
+     * eligible elements for both collections.
+     *
      * <p>Note that it is permissible to pass the same collection in both
-     * parameters, in which case the method will return true if and only if
-     * the collection is empty.
+     * parameters, in which case the method will return {@code true} if and
+     * only if the collection is empty.
      *
      * @param c1 a collection
      * @param c2 a collection
-     * @throws NullPointerException if either collection is null
+     * @return {@code true} if the two specified collections have no
+     * elements in common.
+     * @throws NullPointerException if either collection is {@code null}.
+     * @throws NullPointerException if one collection contains a {@code null}
+     * element and {@code null} is not an eligible element for the other collection.
+     * (optional)
+     * @throws ClassCastException if one collection contains an element that is
+     * of a type which is ineligible for the other collection. (optional)
      * @since 1.5
      */
     public static boolean disjoint(Collection<?> c1, Collection<?> c2) {
-        /*
-         * We're going to iterate through c1 and test for inclusion in c2.
-         * If c1 is a Set and c2 isn't, swap the collections.  Otherwise,
-         * place the shorter collection in c1.  Hopefully this heuristic
-         * will minimize the cost of the operation.
-         */
-        if ((c1 instanceof Set) && !(c2 instanceof Set) ||
-            (c1.size() > c2.size())) {
-            Collection<?> tmp = c1;
-            c1 = c2;
-            c2 = tmp;
+        // The collection to be used for contains(). Preference is given to
+        // the collection who's contains() has lower O() complexity.
+        Collection<?> contains = c2;
+        // The collection to be iterated. If the collections' contains() impl
+        // are of different O() complexity, the collection with slower
+        // contains() will be used for iteration. For collections who's
+        // contains() are of the same complexity then best performance is
+        // achieved by iterating the smaller collection.
+        Collection<?> iterate = c1;
+
+        // Performance optimization cases. The heuristics:
+        //   1. Generally iterate over c1.
+        //   2. If c1 is a Set then iterate over c2.
+        //   3. If either collection is empty then result is always true.
+        //   4. Iterate over the smaller Collection.
+        if (c1 instanceof Set) {
+            // Use c1 for contains as a Set's contains() is expected to perform
+            // better than O(N/2)
+            iterate = c2;
+            contains = c1;
+        } else if (!(c2 instanceof Set)) {
+            // Both are mere Collections. Iterate over smaller collection.
+            // Example: If c1 contains 3 elements and c2 contains 50 elements and
+            // assuming contains() requires ceiling(N/2) comparisons then
+            // checking for all c1 elements in c2 would require 75 comparisons
+            // (3 * ceiling(50/2)) vs. checking all c2 elements in c1 requiring
+            // 100 comparisons (50 * ceiling(3/2)).
+            int c1size = c1.size();
+            int c2size = c2.size();
+            if (c1size == 0 || c2size == 0) {
+                // At least one collection is empty. Nothing will match.
+                return true;
+            }
+
+            if (c1size > c2size) {
+                iterate = c2;
+                contains = c1;
+            }
         }
 
-        for (Object e : c1)
-            if (c2.contains(e))
+        for (Object e : iterate) {
+            if (contains.contains(e)) {
+               // Found a common element. Collections are not disjoint.
                 return false;
+            }
+        }
+
+        // No common elements were found.
         return true;
     }
 
--- a/src/share/classes/java/util/Formatter.java	Thu Feb 10 21:36:18 2011 +0300
+++ b/src/share/classes/java/util/Formatter.java	Fri Feb 11 12:14:38 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -41,6 +41,8 @@
 import java.math.MathContext;
 import java.math.RoundingMode;
 import java.nio.charset.Charset;
+import java.nio.charset.IllegalCharsetNameException;
+import java.nio.charset.UnsupportedCharsetException;
 import java.text.DateFormatSymbols;
 import java.text.DecimalFormat;
 import java.text.DecimalFormatSymbols;
@@ -1838,22 +1840,53 @@
  */
 public final class Formatter implements Closeable, Flushable {
     private Appendable a;
-    private Locale l;
+    private final Locale l;
 
     private IOException lastException;
 
-    private char zero = '0';
+    private final char zero;
     private static double scaleUp;
 
     // 1 (sign) + 19 (max # sig digits) + 1 ('.') + 1 ('e') + 1 (sign)
     // + 3 (max # exp digits) + 4 (error) = 30
     private static final int MAX_FD_CHARS = 30;
 
-    // Initialize internal data.
-    private void init(Appendable a, Locale l) {
+    /**
+     * Returns a charset object for the given charset name.
+     * @throws NullPointerException          is csn is null
+     * @throws UnsupportedEncodingException  if the charset is not supported
+     */
+    private static Charset toCharset(String csn)
+        throws UnsupportedEncodingException
+    {
+        Objects.nonNull(csn, "charsetName");
+        try {
+            return Charset.forName(csn);
+        } catch (IllegalCharsetNameException|UnsupportedCharsetException unused) {
+            // UnsupportedEncodingException should be thrown
+            throw new UnsupportedEncodingException(csn);
+        }
+    }
+
+    private static final Appendable nonNullAppendable(Appendable a) {
+        if (a == null)
+            return new StringBuilder();
+
+        return a;
+    }
+
+    /* Private constructors */
+    private Formatter(Locale l, Appendable a) {
         this.a = a;
         this.l = l;
-        setZero();
+        this.zero = getZero(l);
+    }
+
+    private Formatter(Charset charset, Locale l, File file)
+        throws FileNotFoundException
+    {
+        this(l,
+             new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), charset)));
     }
 
     /**
@@ -1867,7 +1900,7 @@
      * virtual machine.
      */
     public Formatter() {
-        init(new StringBuilder(), Locale.getDefault(Locale.Category.FORMAT));
+        this(Locale.getDefault(Locale.Category.FORMAT), new StringBuilder());
     }
 
     /**
@@ -1881,9 +1914,7 @@
      *         {@code null} then a {@link StringBuilder} will be created.
      */
     public Formatter(Appendable a) {
-        if (a == null)
-            a = new StringBuilder();
-        init(a, Locale.getDefault(Locale.Category.FORMAT));
+        this(Locale.getDefault(Locale.Category.FORMAT), nonNullAppendable(a));
     }
 
     /**
@@ -1900,7 +1931,7 @@
      *         is applied.
      */
     public Formatter(Locale l) {
-        init(new StringBuilder(), l);
+        this(l, new StringBuilder());
     }
 
     /**
@@ -1916,9 +1947,7 @@
      *         is applied.
      */
     public Formatter(Appendable a, Locale l) {
-        if (a == null)
-            a = new StringBuilder();
-        init(a, l);
+        this(l, nonNullAppendable(a));
     }
 
     /**
@@ -1949,8 +1978,8 @@
      *          creating the file
      */
     public Formatter(String fileName) throws FileNotFoundException {
-        init(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileName))),
-             Locale.getDefault(Locale.Category.FORMAT));
+        this(Locale.getDefault(Locale.Category.FORMAT),
+             new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileName))));
     }
 
     /**
@@ -2025,8 +2054,7 @@
     public Formatter(String fileName, String csn, Locale l)
         throws FileNotFoundException, UnsupportedEncodingException
     {
-        init(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileName), csn)),
-             l);
+        this(toCharset(csn), l, new File(fileName));
     }
 
     /**
@@ -2057,8 +2085,8 @@
      *          creating the file
      */
     public Formatter(File file) throws FileNotFoundException {
-        init(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file))),
-             Locale.getDefault(Locale.Category.FORMAT));
+        this(Locale.getDefault(Locale.Category.FORMAT),
+             new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file))));
     }
 
     /**
@@ -2133,8 +2161,7 @@
     public Formatter(File file, String csn, Locale l)
         throws FileNotFoundException, UnsupportedEncodingException
     {
-        init(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), csn)),
-             l);
+        this(toCharset(csn), l, file);
     }
 
     /**
@@ -2151,9 +2178,8 @@
      *         The stream to use as the destination of this formatter.
      */
     public Formatter(PrintStream ps) {
-        if (ps == null)
-            throw new NullPointerException();
-        init((Appendable)ps, Locale.getDefault(Locale.Category.FORMAT));
+        this(Locale.getDefault(Locale.Category.FORMAT),
+             (Appendable)Objects.nonNull(ps));
     }
 
     /**
@@ -2171,8 +2197,8 @@
      *         The output will be buffered.
      */
     public Formatter(OutputStream os) {
-        init(new BufferedWriter(new OutputStreamWriter(os)),
-             Locale.getDefault(Locale.Category.FORMAT));
+        this(Locale.getDefault(Locale.Category.FORMAT),
+             new BufferedWriter(new OutputStreamWriter(os)));
     }
 
     /**
@@ -2222,13 +2248,15 @@
     public Formatter(OutputStream os, String csn, Locale l)
         throws UnsupportedEncodingException
     {
-        init(new BufferedWriter(new OutputStreamWriter(os, csn)), l);
+        this(l, new BufferedWriter(new OutputStreamWriter(os, csn)));
     }
 
-    private void setZero() {
+    private static char getZero(Locale l) {
         if ((l != null) && !l.equals(Locale.US)) {
             DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance(l);
-            zero = dfs.getZeroDigit();
+            return dfs.getZeroDigit();
+        } else {
+            return '0';
         }
     }
 
--- a/src/share/classes/java/util/LinkedList.java	Thu Feb 10 21:36:18 2011 +0300
+++ b/src/share/classes/java/util/LinkedList.java	Fri Feb 11 12:14:38 2011 -0800
@@ -26,9 +26,9 @@
 package java.util;
 
 /**
- * Linked list implementation of the {@link List} and {@link Deque} interfaces.
- * Implements all optional operations, and permits all elements (including
- * {@code null}).
+ * Doubly-linked list implementation of the {@code List} and {@code Deque}
+ * interfaces.  Implements all optional list operations, and permits all
+ * elements (including {@code null}).
  *
  * <p>All of the operations perform as could be expected for a doubly-linked
  * list.  Operations that index into the list will traverse the list from
@@ -249,7 +249,7 @@
      * @return the last element in this list
      * @throws NoSuchElementException if this list is empty
      */
-    public E getLast()  {
+    public E getLast() {
         final Node<E> l = last;
         if (l == null)
             throw new NoSuchElementException();
--- a/src/share/classes/java/util/Scanner.java	Thu Feb 10 21:36:18 2011 +0300
+++ b/src/share/classes/java/util/Scanner.java	Fri Feb 11 12:14:38 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -571,10 +571,8 @@
      * @return A scanner with the specified source and pattern
      */
     private Scanner(Readable source, Pattern pattern) {
-        if (source == null)
-            throw new NullPointerException("source");
-        if (pattern == null)
-            throw new NullPointerException("pattern");
+        assert source != null : "source should not be null";
+        assert pattern != null : "pattern should not be null";
         this.source = source;
         delimPattern = pattern;
         buf = CharBuffer.allocate(BUFFER_SIZE);
@@ -593,7 +591,7 @@
      *         interface
      */
     public Scanner(Readable source) {
-        this(source, WHITESPACE_PATTERN);
+        this(Objects.nonNull(source, "source"), WHITESPACE_PATTERN);
     }
 
     /**
@@ -620,23 +618,27 @@
      *         does not exist
      */
     public Scanner(InputStream source, String charsetName) {
-        this(makeReadable(source, charsetName), WHITESPACE_PATTERN);
+        this(makeReadable(Objects.nonNull(source, "source"), toCharset(charsetName)),
+             WHITESPACE_PATTERN);
     }
 
-    private static Readable makeReadable(InputStream source,
-                                         String charsetName)
-    {
-        if (source == null)
-            throw new NullPointerException("source");
-        InputStreamReader isr = null;
+    /**
+     * Returns a charset object for the given charset name.
+     * @throws NullPointerException          is csn is null
+     * @throws IllegalArgumentException      if the charset is not supported
+     */
+    private static Charset toCharset(String csn) {
+        Objects.nonNull(csn, "charsetName");
         try {
-            isr = new InputStreamReader(source, charsetName);
-        } catch (UnsupportedEncodingException uee) {
-            IllegalArgumentException iae = new IllegalArgumentException();
-            iae.initCause(uee);
-            throw iae;
+            return Charset.forName(csn);
+        } catch (IllegalCharsetNameException|UnsupportedCharsetException e) {
+            // IllegalArgumentException should be thrown
+            throw new IllegalArgumentException(e);
         }
-        return isr;
+    }
+
+    private static Readable makeReadable(InputStream source, Charset charset) {
+        return new InputStreamReader(source, charset);
     }
 
     /**
@@ -648,9 +650,7 @@
      * @param  source A file to be scanned
      * @throws FileNotFoundException if source is not found
      */
-    public Scanner(File source)
-        throws FileNotFoundException
-    {
+    public Scanner(File source) throws FileNotFoundException {
         this((ReadableByteChannel)(new FileInputStream(source).getChannel()));
     }
 
@@ -669,8 +669,27 @@
     public Scanner(File source, String charsetName)
         throws FileNotFoundException
     {
-        this((ReadableByteChannel)(new FileInputStream(source).getChannel()),
-             charsetName);
+        this(Objects.nonNull(source), toDecoder(charsetName));
+    }
+
+    private Scanner(File source, CharsetDecoder dec)
+        throws FileNotFoundException
+    {
+        this(makeReadable((ReadableByteChannel)(new FileInputStream(source).getChannel()), dec));
+    }
+
+    private static CharsetDecoder toDecoder(String charsetName) {
+        Objects.nonNull(charsetName, "charsetName");
+        try {
+            return Charset.forName(charsetName).newDecoder();
+        } catch (IllegalCharsetNameException|UnsupportedCharsetException unused) {
+            throw new IllegalArgumentException(charsetName);
+        }
+    }
+
+    private static Readable makeReadable(ReadableByteChannel source,
+                                         CharsetDecoder dec) {
+        return Channels.newReader(source, dec, -1);
     }
 
     /**
@@ -708,10 +727,12 @@
      *          if the specified encoding is not found
      * @since   1.7
      */
-    public Scanner(FileRef source, String charsetName)
-        throws IOException
-    {
-        this(source.newInputStream(), charsetName);
+    public Scanner(FileRef source, String charsetName) throws IOException {
+        this(Objects.nonNull(source), toCharset(charsetName));
+    }
+
+    private Scanner(FileRef source, Charset charset)  throws IOException {
+        this(makeReadable(source.newInputStream(), charset));
     }
 
     /**
@@ -733,16 +754,12 @@
      * @param  source A channel to scan
      */
     public Scanner(ReadableByteChannel source) {
-        this(makeReadable(source), WHITESPACE_PATTERN);
+        this(makeReadable(Objects.nonNull(source, "source")),
+             WHITESPACE_PATTERN);
     }
 
     private static Readable makeReadable(ReadableByteChannel source) {
-        if (source == null)
-            throw new NullPointerException("source");
-        String defaultCharsetName =
-            java.nio.charset.Charset.defaultCharset().name();
-        return Channels.newReader(source,
-                           java.nio.charset.Charset.defaultCharset().name());
+        return makeReadable(source, Charset.defaultCharset().newDecoder());
     }
 
     /**
@@ -757,17 +774,8 @@
      *         does not exist
      */
     public Scanner(ReadableByteChannel source, String charsetName) {
-        this(makeReadable(source, charsetName), WHITESPACE_PATTERN);
-    }
-
-    private static Readable makeReadable(ReadableByteChannel source,
-                                  String charsetName)
-    {
-        if (source == null)
-            throw new NullPointerException("source");
-        if (!Charset.isSupported(charsetName))
-            throw new IllegalArgumentException(charsetName);
-        return Channels.newReader(source, charsetName);
+        this(makeReadable(Objects.nonNull(source, "source"), toDecoder(charsetName)),
+             WHITESPACE_PATTERN);
     }
 
     // Private primitives used to support scanning
--- a/src/share/classes/java/util/concurrent/ArrayBlockingQueue.java	Thu Feb 10 21:36:18 2011 +0300
+++ b/src/share/classes/java/util/concurrent/ArrayBlockingQueue.java	Fri Feb 11 12:14:38 2011 -0800
@@ -49,14 +49,14 @@
  * <p>This is a classic &quot;bounded buffer&quot;, in which a
  * fixed-sized array holds elements inserted by producers and
  * extracted by consumers.  Once created, the capacity cannot be
- * increased.  Attempts to <tt>put</tt> an element into a full queue
- * will result in the operation blocking; attempts to <tt>take</tt> an
+ * changed.  Attempts to {@code put} an element into a full queue
+ * will result in the operation blocking; attempts to {@code take} an
  * element from an empty queue will similarly block.
  *
- * <p> This class supports an optional fairness policy for ordering
+ * <p>This class supports an optional fairness policy for ordering
  * waiting producer and consumer threads.  By default, this ordering
  * is not guaranteed. However, a queue constructed with fairness set
- * to <tt>true</tt> grants threads access in FIFO order. Fairness
+ * to {@code true} grants threads access in FIFO order. Fairness
  * generally decreases throughput but reduces variability and avoids
  * starvation.
  *
@@ -83,14 +83,17 @@
      */
     private static final long serialVersionUID = -817911632652898426L;
 
-    /** The queued items  */
-    private final E[] items;
-    /** items index for next take, poll or remove */
-    private int takeIndex;
-    /** items index for next put, offer, or add. */
-    private int putIndex;
-    /** Number of items in the queue */
-    private int count;
+    /** The queued items */
+    final Object[] items;
+
+    /** items index for next take, poll, peek or remove */
+    int takeIndex;
+
+    /** items index for next put, offer, or add */
+    int putIndex;
+
+    /** Number of elements in the queue */
+    int count;
 
     /*
      * Concurrency control uses the classic two-condition algorithm
@@ -98,7 +101,7 @@
      */
 
     /** Main lock guarding all access */
-    private final ReentrantLock lock;
+    final ReentrantLock lock;
     /** Condition for waiting takes */
     private final Condition notEmpty;
     /** Condition for waiting puts */
@@ -110,7 +113,36 @@
      * Circularly increment i.
      */
     final int inc(int i) {
-        return (++i == items.length)? 0 : i;
+        return (++i == items.length) ? 0 : i;
+    }
+
+    /**
+     * Circularly decrement i.
+     */
+    final int dec(int i) {
+        return ((i == 0) ? items.length : i) - 1;
+    }
+
+    @SuppressWarnings("unchecked")
+    static <E> E cast(Object item) {
+        return (E) item;
+    }
+
+    /**
+     * Returns item at index i.
+     */
+    final E itemAt(int i) {
+        return this.<E>cast(items[i]);
+    }
+
+    /**
+     * Throws NullPointerException if argument is null.
+     *
+     * @param v the element
+     */
+    private static void checkNotNull(Object v) {
+        if (v == null)
+            throw new NullPointerException();
     }
 
     /**
@@ -129,8 +161,8 @@
      * Call only when holding lock.
      */
     private E extract() {
-        final E[] items = this.items;
-        E x = items[takeIndex];
+        final Object[] items = this.items;
+        E x = this.<E>cast(items[takeIndex]);
         items[takeIndex] = null;
         takeIndex = inc(takeIndex);
         --count;
@@ -139,11 +171,12 @@
     }
 
     /**
-     * Utility for remove and iterator.remove: Delete item at position i.
+     * Deletes item at position i.
+     * Utility for remove and iterator.remove.
      * Call only when holding lock.
      */
     void removeAt(int i) {
-        final E[] items = this.items;
+        final Object[] items = this.items;
         // if removing front item, just advance
         if (i == takeIndex) {
             items[takeIndex] = null;
@@ -167,69 +200,82 @@
     }
 
     /**
-     * Creates an <tt>ArrayBlockingQueue</tt> with the given (fixed)
+     * Creates an {@code ArrayBlockingQueue} with the given (fixed)
      * capacity and default access policy.
      *
      * @param capacity the capacity of this queue
-     * @throws IllegalArgumentException if <tt>capacity</tt> is less than 1
+     * @throws IllegalArgumentException if {@code capacity < 1}
      */
     public ArrayBlockingQueue(int capacity) {
         this(capacity, false);
     }
 
     /**
-     * Creates an <tt>ArrayBlockingQueue</tt> with the given (fixed)
+     * Creates an {@code ArrayBlockingQueue} with the given (fixed)
      * capacity and the specified access policy.
      *
      * @param capacity the capacity of this queue
-     * @param fair if <tt>true</tt> then queue accesses for threads blocked
+     * @param fair if {@code true} then queue accesses for threads blocked
      *        on insertion or removal, are processed in FIFO order;
-     *        if <tt>false</tt> the access order is unspecified.
-     * @throws IllegalArgumentException if <tt>capacity</tt> is less than 1
+     *        if {@code false} the access order is unspecified.
+     * @throws IllegalArgumentException if {@code capacity < 1}
      */
     public ArrayBlockingQueue(int capacity, boolean fair) {
         if (capacity <= 0)
             throw new IllegalArgumentException();
-        this.items = (E[]) new Object[capacity];
+        this.items = new Object[capacity];
         lock = new ReentrantLock(fair);
         notEmpty = lock.newCondition();
         notFull =  lock.newCondition();
     }
 
     /**
-     * Creates an <tt>ArrayBlockingQueue</tt> with the given (fixed)
+     * Creates an {@code ArrayBlockingQueue} with the given (fixed)
      * capacity, the specified access policy and initially containing the
      * elements of the given collection,
      * added in traversal order of the collection's iterator.
      *
      * @param capacity the capacity of this queue
-     * @param fair if <tt>true</tt> then queue accesses for threads blocked
+     * @param fair if {@code true} then queue accesses for threads blocked
      *        on insertion or removal, are processed in FIFO order;
-     *        if <tt>false</tt> the access order is unspecified.
+     *        if {@code false} the access order is unspecified.
      * @param c the collection of elements to initially contain
-     * @throws IllegalArgumentException if <tt>capacity</tt> is less than
-     *         <tt>c.size()</tt>, or less than 1.
+     * @throws IllegalArgumentException if {@code capacity} is less than
+     *         {@code c.size()}, or less than 1.
      * @throws NullPointerException if the specified collection or any
      *         of its elements are null
      */
     public ArrayBlockingQueue(int capacity, boolean fair,
                               Collection<? extends E> c) {
         this(capacity, fair);
-        if (capacity < c.size())
-            throw new IllegalArgumentException();
 
-        for (E e : c)
-            add(e);
+        final ReentrantLock lock = this.lock;
+        lock.lock(); // Lock only for visibility, not mutual exclusion
+        try {
+            int i = 0;
+            try {
+                for (E e : c) {
+                    checkNotNull(e);
+                    items[i++] = e;
+                }
+            } catch (ArrayIndexOutOfBoundsException ex) {
+                throw new IllegalArgumentException();
+            }
+            count = i;
+            putIndex = (i == capacity) ? 0 : i;
+        } finally {
+            lock.unlock();
+        }
     }
 
     /**
      * Inserts the specified element at the tail of this queue if it is
      * possible to do so immediately without exceeding the queue's capacity,
-     * returning <tt>true</tt> upon success and throwing an
-     * <tt>IllegalStateException</tt> if this queue is full.
+     * returning {@code true} upon success and throwing an
+     * {@code IllegalStateException} if this queue is full.
      *
      * @param e the element to add
-     * @return <tt>true</tt> (as specified by {@link Collection#add})
+     * @return {@code true} (as specified by {@link Collection#add})
      * @throws IllegalStateException if this queue is full
      * @throws NullPointerException if the specified element is null
      */
@@ -240,14 +286,14 @@
     /**
      * Inserts the specified element at the tail of this queue if it is
      * possible to do so immediately without exceeding the queue's capacity,
-     * returning <tt>true</tt> upon success and <tt>false</tt> if this queue
+     * returning {@code true} upon success and {@code false} if this queue
      * is full.  This method is generally preferable to method {@link #add},
      * which can fail to insert an element only by throwing an exception.
      *
      * @throws NullPointerException if the specified element is null
      */
     public boolean offer(E e) {
-        if (e == null) throw new NullPointerException();
+        checkNotNull(e);
         final ReentrantLock lock = this.lock;
         lock.lock();
         try {
@@ -270,18 +316,12 @@
      * @throws NullPointerException {@inheritDoc}
      */
     public void put(E e) throws InterruptedException {
-        if (e == null) throw new NullPointerException();
-        final E[] items = this.items;
+        checkNotNull(e);
         final ReentrantLock lock = this.lock;
         lock.lockInterruptibly();
         try {
-            try {
-                while (count == items.length)
-                    notFull.await();
-            } catch (InterruptedException ie) {
-                notFull.signal(); // propagate to non-interrupted thread
-                throw ie;
-            }
+            while (count == items.length)
+                notFull.await();
             insert(e);
         } finally {
             lock.unlock();
@@ -299,25 +339,18 @@
     public boolean offer(E e, long timeout, TimeUnit unit)
         throws InterruptedException {
 
-        if (e == null) throw new NullPointerException();
+        checkNotNull(e);
         long nanos = unit.toNanos(timeout);
         final ReentrantLock lock = this.lock;
         lock.lockInterruptibly();
         try {
-            for (;;) {
-                if (count != items.length) {
-                    insert(e);
-                    return true;
-                }
+            while (count == items.length) {
                 if (nanos <= 0)
                     return false;
-                try {
-                    nanos = notFull.awaitNanos(nanos);
-                } catch (InterruptedException ie) {
-                    notFull.signal(); // propagate to non-interrupted thread
-                    throw ie;
-                }
+                nanos = notFull.awaitNanos(nanos);
             }
+            insert(e);
+            return true;
         } finally {
             lock.unlock();
         }
@@ -327,10 +360,7 @@
         final ReentrantLock lock = this.lock;
         lock.lock();
         try {
-            if (count == 0)
-                return null;
-            E x = extract();
-            return x;
+            return (count == 0) ? null : extract();
         } finally {
             lock.unlock();
         }
@@ -340,15 +370,9 @@
         final ReentrantLock lock = this.lock;
         lock.lockInterruptibly();
         try {
-            try {
-                while (count == 0)
-                    notEmpty.await();
-            } catch (InterruptedException ie) {
-                notEmpty.signal(); // propagate to non-interrupted thread
-                throw ie;
-            }
-            E x = extract();
-            return x;
+            while (count == 0)
+                notEmpty.await();
+            return extract();
         } finally {
             lock.unlock();
         }
@@ -359,21 +383,12 @@
         final ReentrantLock lock = this.lock;
         lock.lockInterruptibly();
         try {
-            for (;;) {
-                if (count != 0) {
-                    E x = extract();
-                    return x;
-                }
+            while (count == 0) {
                 if (nanos <= 0)
                     return null;
-                try {
-                    nanos = notEmpty.awaitNanos(nanos);
-                } catch (InterruptedException ie) {
-                    notEmpty.signal(); // propagate to non-interrupted thread
-                    throw ie;
-                }
-
+                nanos = notEmpty.awaitNanos(nanos);
             }
+            return extract();
         } finally {
             lock.unlock();
         }
@@ -383,7 +398,7 @@
         final ReentrantLock lock = this.lock;
         lock.lock();
         try {
-            return (count == 0) ? null : items[takeIndex];
+            return (count == 0) ? null : itemAt(takeIndex);
         } finally {
             lock.unlock();
         }
@@ -412,10 +427,10 @@
      * Returns the number of additional elements that this queue can ideally
      * (in the absence of memory or resource constraints) accept without
      * blocking. This is always equal to the initial capacity of this queue
-     * less the current <tt>size</tt> of this queue.
+     * less the current {@code size} of this queue.
      *
      * <p>Note that you <em>cannot</em> always tell if an attempt to insert
-     * an element will succeed by inspecting <tt>remainingCapacity</tt>
+     * an element will succeed by inspecting {@code remainingCapacity}
      * because it may be the case that another thread is about to
      * insert or remove an element.
      */
@@ -431,59 +446,56 @@
 
     /**
      * Removes a single instance of the specified element from this queue,
-     * if it is present.  More formally, removes an element <tt>e</tt> such
-     * that <tt>o.equals(e)</tt>, if this queue contains one or more such
+     * if it is present.  More formally, removes an element {@code e} such
+     * that {@code o.equals(e)}, if this queue contains one or more such
      * elements.
-     * Returns <tt>true</tt> if this queue contained the specified element
+     * Returns {@code true} if this queue contained the specified element
      * (or equivalently, if this queue changed as a result of the call).
      *
+     * <p>Removal of interior elements in circular array based queues
+     * is an intrinsically slow and disruptive operation, so should
+     * be undertaken only in exceptional circumstances, ideally
+     * only when the queue is known not to be accessible by other
+     * threads.
+     *
      * @param o element to be removed from this queue, if present
-     * @return <tt>true</tt> if this queue changed as a result of the call
+     * @return {@code true} if this queue changed as a result of the call
      */
     public boolean remove(Object o) {
         if (o == null) return false;
-        final E[] items = this.items;
+        final Object[] items = this.items;
         final ReentrantLock lock = this.lock;
         lock.lock();
         try {
-            int i = takeIndex;
-            int k = 0;
-            for (;;) {
-                if (k++ >= count)
-                    return false;
+            for (int i = takeIndex, k = count; k > 0; i = inc(i), k--) {
                 if (o.equals(items[i])) {
                     removeAt(i);
                     return true;
                 }
-                i = inc(i);
             }
-
+            return false;
         } finally {
             lock.unlock();
         }
     }
 
     /**
-     * Returns <tt>true</tt> if this queue contains the specified element.
-     * More formally, returns <tt>true</tt> if and only if this queue contains
-     * at least one element <tt>e</tt> such that <tt>o.equals(e)</tt>.
+     * Returns {@code true} if this queue contains the specified element.
+     * More formally, returns {@code true} if and only if this queue contains
+     * at least one element {@code e} such that {@code o.equals(e)}.
      *
      * @param o object to be checked for containment in this queue
-     * @return <tt>true</tt> if this queue contains the specified element
+     * @return {@code true} if this queue contains the specified element
      */
     public boolean contains(Object o) {
         if (o == null) return false;
-        final E[] items = this.items;
+        final Object[] items = this.items;
         final ReentrantLock lock = this.lock;
         lock.lock();
         try {
-            int i = takeIndex;
-            int k = 0;
-            while (k++ < count) {
+            for (int i = takeIndex, k = count; k > 0; i = inc(i), k--)
                 if (o.equals(items[i]))
                     return true;
-                i = inc(i);
-            }
             return false;
         } finally {
             lock.unlock();
@@ -504,17 +516,14 @@
      * @return an array containing all of the elements in this queue
      */
     public Object[] toArray() {
-        final E[] items = this.items;
+        final Object[] items = this.items;
         final ReentrantLock lock = this.lock;
         lock.lock();
         try {
+            final int count = this.count;
             Object[] a = new Object[count];
-            int k = 0;
-            int i = takeIndex;
-            while (k < count) {
-                a[k++] = items[i];
-                i = inc(i);
-            }
+            for (int i = takeIndex, k = 0; k < count; i = inc(i), k++)
+                a[k] = items[i];
             return a;
         } finally {
             lock.unlock();
@@ -531,22 +540,22 @@
      * <p>If this queue fits in the specified array with room to spare
      * (i.e., the array has more elements than this queue), the element in
      * the array immediately following the end of the queue is set to
-     * <tt>null</tt>.
+     * {@code null}.
      *
      * <p>Like the {@link #toArray()} method, this method acts as bridge between
      * array-based and collection-based APIs.  Further, this method allows
      * precise control over the runtime type of the output array, and may,
      * under certain circumstances, be used to save allocation costs.
      *
-     * <p>Suppose <tt>x</tt> is a queue known to contain only strings.
+     * <p>Suppose {@code x} is a queue known to contain only strings.
      * The following code can be used to dump the queue into a newly
-     * allocated array of <tt>String</tt>:
+     * allocated array of {@code String}:
      *
      * <pre>
      *     String[] y = x.toArray(new String[0]);</pre>
      *
-     * Note that <tt>toArray(new Object[0])</tt> is identical in function to
-     * <tt>toArray()</tt>.
+     * Note that {@code toArray(new Object[0])} is identical in function to
+     * {@code toArray()}.
      *
      * @param a the array into which the elements of the queue are to
      *          be stored, if it is big enough; otherwise, a new array of the
@@ -557,24 +566,20 @@
      *         this queue
      * @throws NullPointerException if the specified array is null
      */
+    @SuppressWarnings("unchecked")
     public <T> T[] toArray(T[] a) {
-        final E[] items = this.items;
+        final Object[] items = this.items;
         final ReentrantLock lock = this.lock;
         lock.lock();
         try {
-            if (a.length < count)
+            final int count = this.count;
+            final int len = a.length;
+            if (len < count)
                 a = (T[])java.lang.reflect.Array.newInstance(
-                    a.getClass().getComponentType(),
-                    count
-                    );
-
-            int k = 0;
-            int i = takeIndex;
-            while (k < count) {
-                a[k++] = (T)items[i];
-                i = inc(i);
-            }
-            if (a.length > count)
+                    a.getClass().getComponentType(), count);
+            for (int i = takeIndex, k = 0; k < count; i = inc(i), k++)
+                a[k] = (T) items[i];
+            if (len > count)
                 a[count] = null;
             return a;
         } finally {
@@ -586,7 +591,19 @@
         final ReentrantLock lock = this.lock;
         lock.lock();
         try {
-            return super.toString();
+            int k = count;
+            if (k == 0)
+                return "[]";
+
+            StringBuilder sb = new StringBuilder();
+            sb.append('[');
+            for (int i = takeIndex; ; i = inc(i)) {
+                Object e = items[i];
+                sb.append(e == this ? "(this Collection)" : e);
+                if (--k == 0)
+                    return sb.append(']').toString();
+                sb.append(',').append(' ');
+            }
         } finally {
             lock.unlock();
         }
@@ -597,16 +614,12 @@
      * The queue will be empty after this call returns.
      */
     public void clear() {
-        final E[] items = this.items;
+        final Object[] items = this.items;
         final ReentrantLock lock = this.lock;
         lock.lock();
         try {
-            int i = takeIndex;
-            int k = count;
-            while (k-- > 0) {
+            for (int i = takeIndex, k = count; k > 0; i = inc(i), k--)
                 items[i] = null;
-                i = inc(i);
-            }
             count = 0;
             putIndex = 0;
             takeIndex = 0;
@@ -623,11 +636,10 @@
      * @throws IllegalArgumentException      {@inheritDoc}
      */
     public int drainTo(Collection<? super E> c) {
-        if (c == null)
-            throw new NullPointerException();
+        checkNotNull(c);
         if (c == this)
             throw new IllegalArgumentException();
-        final E[] items = this.items;
+        final Object[] items = this.items;
         final ReentrantLock lock = this.lock;
         lock.lock();
         try {
@@ -635,7 +647,7 @@
             int n = 0;
             int max = count;
             while (n < max) {
-                c.add(items[i]);
+                c.add(this.<E>cast(items[i]));
                 items[i] = null;
                 i = inc(i);
                 ++n;
@@ -659,22 +671,20 @@
      * @throws IllegalArgumentException      {@inheritDoc}
      */
     public int drainTo(Collection<? super E> c, int maxElements) {
-        if (c == null)
-            throw new NullPointerException();
+        checkNotNull(c);
         if (c == this)
             throw new IllegalArgumentException();
         if (maxElements <= 0)
             return 0;
-        final E[] items = this.items;
+        final Object[] items = this.items;
         final ReentrantLock lock = this.lock;
         lock.lock();
         try {
             int i = takeIndex;
             int n = 0;
-            int sz = count;
-            int max = (maxElements < count)? maxElements : count;
+            int max = (maxElements < count) ? maxElements : count;
             while (n < max) {
-                c.add(items[i]);
+                c.add(this.<E>cast(items[i]));
                 items[i] = null;
                 i = inc(i);
                 ++n;
@@ -690,11 +700,13 @@
         }
     }
 
-
     /**
      * Returns an iterator over the elements in this queue in proper sequence.
-     * The returned <tt>Iterator</tt> is a "weakly consistent" iterator that
-     * will never throw {@link ConcurrentModificationException},
+     * The elements will be returned in order from first (head) to last (tail).
+     *
+     * <p>The returned {@code Iterator} is a "weakly consistent" iterator that
+     * will never throw {@link java.util.ConcurrentModificationException
+     * ConcurrentModificationException},
      * and guarantees to traverse elements as they existed upon
      * construction of the iterator, and may (but is not guaranteed to)
      * reflect any modifications subsequent to construction.
@@ -702,83 +714,65 @@
      * @return an iterator over the elements in this queue in proper sequence
      */
     public Iterator<E> iterator() {
-        final ReentrantLock lock = this.lock;
-        lock.lock();
-        try {
-            return new Itr();
-        } finally {
-            lock.unlock();
-        }
+        return new Itr();
     }
 
     /**
-     * Iterator for ArrayBlockingQueue
+     * Iterator for ArrayBlockingQueue. To maintain weak consistency
+     * with respect to puts and takes, we (1) read ahead one slot, so
+     * as to not report hasNext true but then not have an element to
+     * return -- however we later recheck this slot to use the most
+     * current value; (2) ensure that each array slot is traversed at
+     * most once (by tracking "remaining" elements); (3) skip over
+     * null slots, which can occur if takes race ahead of iterators.
+     * However, for circular array-based queues, we cannot rely on any
+     * well established definition of what it means to be weakly
+     * consistent with respect to interior removes since these may
+     * require slot overwrites in the process of sliding elements to
+     * cover gaps. So we settle for resiliency, operating on
+     * established apparent nexts, which may miss some elements that
+     * have moved between calls to next.
      */
     private class Itr implements Iterator<E> {
-        /**
-         * Index of element to be returned by next,
-         * or a negative number if no such.
-         */
-        private int nextIndex;
-
-        /**
-         * nextItem holds on to item fields because once we claim
-         * that an element exists in hasNext(), we must return it in
-         * the following next() call even if it was in the process of
-         * being removed when hasNext() was called.
-         */
-        private E nextItem;
-
-        /**
-         * Index of element returned by most recent call to next.
-         * Reset to -1 if this element is deleted by a call to remove.
-         */
-        private int lastRet;
+        private int remaining; // Number of elements yet to be returned
+        private int nextIndex; // Index of element to be returned by next
+        private E nextItem;    // Element to be returned by next call to next
+        private E lastItem;    // Element returned by last call to next
+        private int lastRet;   // Index of last element returned, or -1 if none
 
         Itr() {
-            lastRet = -1;
-            if (count == 0)
-                nextIndex = -1;
-            else {
-                nextIndex = takeIndex;
-                nextItem = items[takeIndex];
+            final ReentrantLock lock = ArrayBlockingQueue.this.lock;
+            lock.lock();
+            try {
+                lastRet = -1;
+                if ((remaining = count) > 0)
+                    nextItem = itemAt(nextIndex = takeIndex);
+            } finally {
+                lock.unlock();
             }
         }
 
         public boolean hasNext() {
-            /*
-             * No sync. We can return true by mistake here
-             * only if this iterator passed across threads,
-             * which we don't support anyway.
-             */
-            return nextIndex >= 0;
-        }
-
-        /**
-         * Checks whether nextIndex is valid; if so setting nextItem.
-         * Stops iterator when either hits putIndex or sees null item.
-         */
-        private void checkNext() {
-            if (nextIndex == putIndex) {
-                nextIndex = -1;
-                nextItem = null;
-            } else {
-                nextItem = items[nextIndex];
-                if (nextItem == null)
-                    nextIndex = -1;
-            }
+            return remaining > 0;
         }
 
         public E next() {
             final ReentrantLock lock = ArrayBlockingQueue.this.lock;
             lock.lock();
             try {
-                if (nextIndex < 0)
+                if (remaining <= 0)
                     throw new NoSuchElementException();
                 lastRet = nextIndex;
-                E x = nextItem;
-                nextIndex = inc(nextIndex);
-                checkNext();
+                E x = itemAt(nextIndex);  // check for fresher value
+                if (x == null) {
+                    x = nextItem;         // we are forced to report old value
+                    lastItem = null;      // but ensure remove fails
+                }
+                else
+                    lastItem = x;
+                while (--remaining > 0 && // skip over nulls
+                       (nextItem = itemAt(nextIndex = inc(nextIndex))) == null)
+                    ;
                 return x;
             } finally {
                 lock.unlock();
@@ -793,15 +787,19 @@
                 if (i == -1)
                     throw new IllegalStateException();
                 lastRet = -1;
-
-                int ti = takeIndex;
-                removeAt(i);
-                // back up cursor (reset to front if was first element)
-                nextIndex = (i == ti) ? takeIndex : i;
-                checkNext();
+                E x = lastItem;
+                lastItem = null;
+                // only remove if item still at index
+                if (x != null && x == items[i]) {
+                    boolean removingHead = (i == takeIndex);
+                    removeAt(i);
+                    if (!removingHead)
+                        nextIndex = dec(nextIndex);
+                }
             } finally {
                 lock.unlock();
             }
         }
     }
+
 }
--- a/src/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java	Thu Feb 10 21:36:18 2011 +0300
+++ b/src/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java	Fri Feb 11 12:14:38 2011 -0800
@@ -869,6 +869,8 @@
 
     /**
      * Inserts the specified element at the front of this deque.
+     * As the deque is unbounded, this method will never throw
+     * {@link IllegalStateException}.
      *
      * @throws NullPointerException if the specified element is null
      */
@@ -878,6 +880,8 @@
 
     /**
      * Inserts the specified element at the end of this deque.
+     * As the deque is unbounded, this method will never throw
+     * {@link IllegalStateException}.
      *
      * <p>This method is equivalent to {@link #add}.
      *
@@ -889,8 +893,9 @@
 
     /**
      * Inserts the specified element at the front of this deque.
+     * As the deque is unbounded, this method will never return {@code false}.
      *
-     * @return {@code true} always
+     * @return {@code true} (as specified by {@link Deque#offerFirst})
      * @throws NullPointerException if the specified element is null
      */
     public boolean offerFirst(E e) {
@@ -900,10 +905,11 @@
 
     /**
      * Inserts the specified element at the end of this deque.
+     * As the deque is unbounded, this method will never return {@code false}.
      *
      * <p>This method is equivalent to {@link #add}.
      *
-     * @return {@code true} always
+     * @return {@code true} (as specified by {@link Deque#offerLast})
      * @throws NullPointerException if the specified element is null
      */
     public boolean offerLast(E e) {
@@ -983,6 +989,7 @@
 
     /**
      * Inserts the specified element at the tail of this deque.
+     * As the deque is unbounded, this method will never return {@code false}.
      *
      * @return {@code true} (as specified by {@link Queue#offer})
      * @throws NullPointerException if the specified element is null
@@ -993,6 +1000,8 @@
 
     /**
      * Inserts the specified element at the tail of this deque.
+     * As the deque is unbounded, this method will never throw
+     * {@link IllegalStateException} or return {@code false}.
      *
      * @return {@code true} (as specified by {@link Collection#add})
      * @throws NullPointerException if the specified element is null
--- a/src/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java	Thu Feb 10 21:36:18 2011 +0300
+++ b/src/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java	Fri Feb 11 12:14:38 2011 -0800
@@ -269,6 +269,8 @@
 
     /**
      * Inserts the specified element at the tail of this queue.
+     * As the queue is unbounded, this method will never throw
+     * {@link IllegalStateException} or return {@code false}.
      *
      * @return {@code true} (as specified by {@link Collection#add})
      * @throws NullPointerException if the specified element is null
@@ -298,6 +300,7 @@
 
     /**
      * Inserts the specified element at the tail of this queue.
+     * As the queue is unbounded, this method will never return {@code false}.
      *
      * @return {@code true} (as specified by {@link Queue#offer})
      * @throws NullPointerException if the specified element is null
--- a/src/share/classes/java/util/concurrent/ConcurrentSkipListMap.java	Thu Feb 10 21:36:18 2011 +0300
+++ b/src/share/classes/java/util/concurrent/ConcurrentSkipListMap.java	Fri Feb 11 12:14:38 2011 -0800
@@ -374,17 +374,11 @@
                                   null, null, 1);
     }
 
-    /** Updater for casHead */
-    private static final
-        AtomicReferenceFieldUpdater<ConcurrentSkipListMap, HeadIndex>
-        headUpdater = AtomicReferenceFieldUpdater.newUpdater
-        (ConcurrentSkipListMap.class, HeadIndex.class, "head");
-
     /**
      * compareAndSet head node
      */
     private boolean casHead(HeadIndex<K,V> cmp, HeadIndex<K,V> val) {
-        return headUpdater.compareAndSet(this, cmp, val);
+        return UNSAFE.compareAndSwapObject(this, headOffset, cmp, val);
     }
 
     /* ---------------- Nodes -------------- */
@@ -423,28 +417,18 @@
             this.next = next;
         }
 
-        /** Updater for casNext */
-        static final AtomicReferenceFieldUpdater<Node, Node>
-            nextUpdater = AtomicReferenceFieldUpdater.newUpdater
-            (Node.class, Node.class, "next");
-
-        /** Updater for casValue */
-        static final AtomicReferenceFieldUpdater<Node, Object>
-            valueUpdater = AtomicReferenceFieldUpdater.newUpdater
-            (Node.class, Object.class, "value");
-
         /**
          * compareAndSet value field
          */
         boolean casValue(Object cmp, Object val) {
-            return valueUpdater.compareAndSet(this, cmp, val);
+            return UNSAFE.compareAndSwapObject(this, valueOffset, cmp, val);
         }
 
         /**
          * compareAndSet next field
          */
         boolean casNext(Node<K,V> cmp, Node<K,V> val) {
-            return nextUpdater.compareAndSet(this, cmp, val);
+            return UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val);
         }
 
         /**
@@ -522,6 +506,14 @@
                 return null;
             return new AbstractMap.SimpleImmutableEntry<K,V>(key, v);
         }
+
+        // Unsafe mechanics
+        private static final sun.misc.Unsafe UNSAFE = sun.misc.Unsafe.getUnsafe();
+        private static final long valueOffset =
+            objectFieldOffset(UNSAFE, "value", Node.class);
+        private static final long nextOffset =
+            objectFieldOffset(UNSAFE, "next", Node.class);
+
     }
 
     /* ---------------- Indexing -------------- */
@@ -547,16 +539,11 @@
             this.right = right;
         }
 
-        /** Updater for casRight */
-        static final AtomicReferenceFieldUpdater<Index, Index>
-            rightUpdater = AtomicReferenceFieldUpdater.newUpdater
-            (Index.class, Index.class, "right");
-
         /**
          * compareAndSet right field
          */
         final boolean casRight(Index<K,V> cmp, Index<K,V> val) {
-            return rightUpdater.compareAndSet(this, cmp, val);
+            return UNSAFE.compareAndSwapObject(this, rightOffset, cmp, val);
         }
 
         /**
@@ -591,6 +578,12 @@
         final boolean unlink(Index<K,V> succ) {
             return !indexesDeletedNode() && casRight(succ, succ.right);
         }
+
+        // Unsafe mechanics
+        private static final sun.misc.Unsafe UNSAFE = sun.misc.Unsafe.getUnsafe();
+        private static final long rightOffset =
+            objectFieldOffset(UNSAFE, "right", Index.class);
+
     }
 
     /* ---------------- Head nodes -------------- */
@@ -640,7 +633,8 @@
      * cast key as Comparable, which may cause ClassCastException,
      * which is propagated back to caller.
      */
-    private Comparable<? super K> comparable(Object key) throws ClassCastException {
+    private Comparable<? super K> comparable(Object key)
+            throws ClassCastException {
         if (key == null)
             throw new NullPointerException();
         if (comparator != null)
@@ -799,68 +793,12 @@
     }
 
     /**
-     * Specialized variant of findNode to perform Map.get. Does a weak
-     * traversal, not bothering to fix any deleted index nodes,
-     * returning early if it happens to see key in index, and passing
-     * over any deleted base nodes, falling back to getUsingFindNode
-     * only if it would otherwise return value from an ongoing
-     * deletion. Also uses "bound" to eliminate need for some
-     * comparisons (see Pugh Cookbook). Also folds uses of null checks
-     * and node-skipping because markers have null keys.
+     * Gets value for key using findNode.
      * @param okey the key
      * @return the value, or null if absent
      */
     private V doGet(Object okey) {
         Comparable<? super K> key = comparable(okey);
-        Node<K,V> bound = null;
-        Index<K,V> q = head;
-        Index<K,V> r = q.right;
-        Node<K,V> n;
-        K k;
-        int c;
-        for (;;) {
-            Index<K,V> d;
-            // Traverse rights
-            if (r != null && (n = r.node) != bound && (k = n.key) != null) {
-                if ((c = key.compareTo(k)) > 0) {
-                    q = r;
-                    r = r.right;
-                    continue;
-                } else if (c == 0) {
-                    Object v = n.value;
-                    return (v != null)? (V)v : getUsingFindNode(key);
-                } else
-                    bound = n;
-            }
-
-            // Traverse down
-            if ((d = q.down) != null) {
-                q = d;
-                r = d.right;
-            } else
-                break;
-        }
-
-        // Traverse nexts
-        for (n = q.node.next;  n != null; n = n.next) {
-            if ((k = n.key) != null) {
-                if ((c = key.compareTo(k)) == 0) {
-                    Object v = n.value;
-                    return (v != null)? (V)v : getUsingFindNode(key);
-                } else if (c < 0)
-                    break;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Performs map.get via findNode.  Used as a backup if doGet
-     * encounters an in-progress deletion.
-     * @param key the key
-     * @return the value, or null if absent
-     */
-    private V getUsingFindNode(Comparable<? super K> key) {
         /*
          * Loop needed here and elsewhere in case value field goes
          * null just as it is about to be returned, in which case we
@@ -943,7 +881,7 @@
         x ^= x << 13;
         x ^= x >>> 17;
         randomSeed = x ^= x << 5;
-        if ((x & 0x8001) != 0) // test highest and lowest bits
+        if ((x & 0x80000001) != 0) // test highest and lowest bits
             return 0;
         int level = 1;
         while (((x >>>= 1) & 1) != 0) ++level;
@@ -1256,7 +1194,7 @@
                 Node<K,V> n = b.next;
                 for (;;) {
                     if (n == null)
-                        return (b.isBaseHeader())? null : b;
+                        return b.isBaseHeader() ? null : b;
                     Node<K,V> f = n.next;            // inconsistent read
                     if (n != b.next)
                         break;
@@ -1374,7 +1312,7 @@
             Node<K,V> n = b.next;
             for (;;) {
                 if (n == null)
-                    return ((rel & LT) == 0 || b.isBaseHeader())? null : b;
+                    return ((rel & LT) == 0 || b.isBaseHeader()) ? null : b;
                 Node<K,V> f = n.next;
                 if (n != b.next)                  // inconsistent read
                     break;
@@ -1390,7 +1328,7 @@
                     (c <  0 && (rel & LT) == 0))
                     return n;
                 if ( c <= 0 && (rel & LT) != 0)
-                    return (b.isBaseHeader())? null : b;
+                    return b.isBaseHeader() ? null : b;
                 b = n;
                 n = f;
             }
@@ -1744,7 +1682,7 @@
             if (n.getValidValue() != null)
                 ++count;
         }
-        return (count >= Integer.MAX_VALUE)? Integer.MAX_VALUE : (int)count;
+        return (count >= Integer.MAX_VALUE) ? Integer.MAX_VALUE : (int) count;
     }
 
     /**
@@ -2099,7 +2037,7 @@
      */
     public K lowerKey(K key) {
         Node<K,V> n = findNear(key, LT);
-        return (n == null)? null : n.key;
+        return (n == null) ? null : n.key;
     }
 
     /**
@@ -2123,7 +2061,7 @@
      */
     public K floorKey(K key) {
         Node<K,V> n = findNear(key, LT|EQ);
-        return (n == null)? null : n.key;
+        return (n == null) ? null : n.key;
     }
 
     /**
@@ -2145,7 +2083,7 @@
      */
     public K ceilingKey(K key) {
         Node<K,V> n = findNear(key, GT|EQ);
-        return (n == null)? null : n.key;
+        return (n == null) ? null : n.key;
     }
 
     /**
@@ -2169,7 +2107,7 @@
      */
     public K higherKey(K key) {
         Node<K,V> n = findNear(key, GT);
-        return (n == null)? null : n.key;
+        return (n == null) ? null : n.key;
     }
 
     /**
@@ -2342,7 +2280,8 @@
         return list;
     }
 
-    static final class KeySet<E> extends AbstractSet<E> implements NavigableSet<E> {
+    static final class KeySet<E>
+            extends AbstractSet<E> implements NavigableSet<E> {
         private final ConcurrentNavigableMap<E,Object> m;
         KeySet(ConcurrentNavigableMap<E,Object> map) { m = map; }
         public int size() { return m.size(); }
@@ -2359,11 +2298,11 @@
         public E last() { return m.lastKey(); }
         public E pollFirst() {
             Map.Entry<E,Object> e = m.pollFirstEntry();
-            return e == null? null : e.getKey();
+            return (e == null) ? null : e.getKey();
         }
         public E pollLast() {
             Map.Entry<E,Object> e = m.pollLastEntry();
-            return e == null? null : e.getKey();
+            return (e == null) ? null : e.getKey();
         }
         public Iterator<E> iterator() {
             if (m instanceof ConcurrentSkipListMap)
@@ -2710,9 +2649,9 @@
                     rel &= ~m.LT;
             }
             if (tooLow(key))
-                return ((rel & m.LT) != 0)? null : lowestEntry();
+                return ((rel & m.LT) != 0) ? null : lowestEntry();
             if (tooHigh(key))
-                return ((rel & m.LT) != 0)? highestEntry() : null;
+                return ((rel & m.LT) != 0) ? highestEntry() : null;
             for (;;) {
                 Node<K,V> n = m.findNear(key, rel);
                 if (n == null || !inBounds(n.key))
@@ -2783,7 +2722,7 @@
 
         public V remove(Object key) {
             K k = (K)key;
-            return (!inBounds(k))? null : m.remove(k);
+            return (!inBounds(k)) ? null : m.remove(k);
         }
 
         public int size() {
@@ -2794,7 +2733,7 @@
                 if (n.getValidValue() != null)
                     ++count;
             }
-            return count >= Integer.MAX_VALUE? Integer.MAX_VALUE : (int)count;
+            return count >= Integer.MAX_VALUE ? Integer.MAX_VALUE : (int)count;
         }
 
         public boolean isEmpty() {
@@ -2972,27 +2911,27 @@
         }
 
         public K firstKey() {
-            return isDescending? highestKey() : lowestKey();
+            return isDescending ? highestKey() : lowestKey();
         }
 
         public K lastKey() {
-            return isDescending? lowestKey() : highestKey();
+            return isDescending ? lowestKey() : highestKey();
         }
 
         public Map.Entry<K,V> firstEntry() {
-            return isDescending? highestEntry() : lowestEntry();
+            return isDescending ? highestEntry() : lowestEntry();
         }
 
         public Map.Entry<K,V> lastEntry() {
-            return isDescending? lowestEntry() : highestEntry();
+            return isDescending ? lowestEntry() : highestEntry();
         }
 
         public Map.Entry<K,V> pollFirstEntry() {
-            return isDescending? removeHighest() : removeLowest();
+            return isDescending ? removeHighest() : removeLowest();
         }
 
         public Map.Entry<K,V> pollLastEntry() {
-            return isDescending? removeLowest() : removeHighest();
+            return isDescending ? removeLowest() : removeHighest();
         }
 
         /* ---------------- Submap Views -------------- */
@@ -3141,4 +3080,22 @@
             }
         }
     }
+
+    // Unsafe mechanics
+    private static final sun.misc.Unsafe UNSAFE = sun.misc.Unsafe.getUnsafe();
+    private static final long headOffset =
+        objectFieldOffset(UNSAFE, "head", ConcurrentSkipListMap.class);
+
+    static long objectFieldOffset(sun.misc.Unsafe UNSAFE,
+                                  String field, Class<?> klazz) {
+        try {
+            return UNSAFE.objectFieldOffset(klazz.getDeclaredField(field));
+        } catch (NoSuchFieldException e) {
+            // Convert Exception to corresponding Error
+            NoSuchFieldError error = new NoSuchFieldError(field);
+            error.initCause(e);
+            throw error;
+        }
+    }
+
 }
--- a/src/share/classes/java/util/concurrent/CopyOnWriteArrayList.java	Thu Feb 10 21:36:18 2011 +0300
+++ b/src/share/classes/java/util/concurrent/CopyOnWriteArrayList.java	Fri Feb 11 12:14:38 2011 -0800
@@ -832,7 +832,7 @@
     }
 
     /**
-     * Save the state of the list to a stream (i.e., serialize it).
+     * Saves the state of the list to a stream (that is, serializes it).
      *
      * @serialData The length of the array backing the list is emitted
      *               (int), followed by all of its elements (each an Object)
@@ -842,27 +842,25 @@
     private void writeObject(java.io.ObjectOutputStream s)
         throws java.io.IOException{
 
-        // Write out element count, and any hidden stuff
         s.defaultWriteObject();
 
         Object[] elements = getArray();
-        int len = elements.length;
         // Write out array length
-        s.writeInt(len);
+        s.writeInt(elements.length);
 
         // Write out all elements in the proper order.
-        for (int i = 0; i < len; i++)
-            s.writeObject(elements[i]);
+        for (Object element : elements)
+            s.writeObject(element);
     }
 
     /**
-     * Reconstitute the list from a stream (i.e., deserialize it).
+     * Reconstitutes the list from a stream (that is, deserializes it).
+     *
      * @param s the stream
      */
     private void readObject(java.io.ObjectInputStream s)
         throws java.io.IOException, ClassNotFoundException {
 
-        // Read in size, and any hidden stuff
         s.defaultReadObject();
 
         // bind to new lock
--- a/src/share/classes/java/util/concurrent/ForkJoinPool.java	Thu Feb 10 21:36:18 2011 +0300
+++ b/src/share/classes/java/util/concurrent/ForkJoinPool.java	Fri Feb 11 12:14:38 2011 -0800
@@ -525,8 +525,8 @@
      */
     private volatile long eventWaiters;
 
-    private static final int  EVENT_COUNT_SHIFT = 32;
-    private static final long WAITER_ID_MASK    = (1L << 16) - 1L;
+    private static final int EVENT_COUNT_SHIFT = 32;
+    private static final int WAITER_ID_MASK    = (1 << 16) - 1;
 
     /**
      * A counter for events that may wake up worker threads:
@@ -615,7 +615,7 @@
     // are usually manually inlined by callers
 
     /**
-     * Increments running count part of workerCounts
+     * Increments running count part of workerCounts.
      */
     final void incrementRunningCount() {
         int c;
@@ -625,7 +625,17 @@
     }
 
     /**
-     * Tries to decrement running count unless already zero
+     * Tries to increment running count part of workerCounts.
+     */
+    final boolean tryIncrementRunningCount() {
+        int c;
+        return UNSAFE.compareAndSwapInt(this, workerCountsOffset,
+                                        c = workerCounts,
+                                        c + ONE_RUNNING);
+    }
+
+    /**
+     * Tries to decrement running count unless already zero.
      */
     final boolean tryDecrementRunningCount() {
         int wc = workerCounts;
@@ -698,10 +708,11 @@
                 for (k = 0; k < n && ws[k] != null; ++k)
                     ;
                 if (k == n)
-                    ws = Arrays.copyOf(ws, n << 1);
+                    ws = workers = Arrays.copyOf(ws, n << 1);
             }
             ws[k] = w;
-            workers = ws; // volatile array write ensures slot visibility
+            int c = eventCount; // advance event count to ensure visibility
+            UNSAFE.compareAndSwapInt(this, eventCountOffset, c, c+1);
         } finally {
             lock.unlock();
         }
@@ -734,7 +745,7 @@
      */
     final void workerTerminated(ForkJoinWorkerThread w) {
         forgetWorker(w);
-        decrementWorkerCounts(w.isTrimmed()? 0 : ONE_RUNNING, ONE_TOTAL);
+        decrementWorkerCounts(w.isTrimmed() ? 0 : ONE_RUNNING, ONE_TOTAL);
         while (w.stealCount != 0) // collect final count
             tryAccumulateStealCount(w);
         tryTerminate(false);
@@ -746,24 +757,23 @@
      * Releases workers blocked on a count not equal to current count.
      * Normally called after precheck that eventWaiters isn't zero to
      * avoid wasted array checks. Gives up upon a change in count or
-     * upon releasing two workers, letting others take over.
+     * upon releasing four workers, letting others take over.
      */
     private void releaseEventWaiters() {
         ForkJoinWorkerThread[] ws = workers;
         int n = ws.length;
         long h = eventWaiters;
         int ec = eventCount;
-        boolean releasedOne = false;
+        int releases = 4;
         ForkJoinWorkerThread w; int id;
-        while ((id = ((int)(h & WAITER_ID_MASK)) - 1) >= 0 &&
+        while ((id = (((int)h) & WAITER_ID_MASK) - 1) >= 0 &&
                (int)(h >>> EVENT_COUNT_SHIFT) != ec &&
                id < n && (w = ws[id]) != null) {
             if (UNSAFE.compareAndSwapLong(this, eventWaitersOffset,
                                           h,  w.nextWaiter)) {
                 LockSupport.unpark(w);
-                if (releasedOne) // exit on second release
+                if (--releases == 0)
                     break;
-                releasedOne = true;
             }
             if (eventCount != ec)
                 break;
@@ -793,7 +803,7 @@
         long nh = (((long)ec) << EVENT_COUNT_SHIFT) | ((long)(w.poolIndex+1));
         long h;
         while ((runState < SHUTDOWN || !tryTerminate(false)) &&
-               (((int)((h = eventWaiters) & WAITER_ID_MASK)) == 0 ||
+               (((int)(h = eventWaiters) & WAITER_ID_MASK) == 0 ||
                 (int)(h >>> EVENT_COUNT_SHIFT) == ec) &&
                eventCount == ec) {
             if (UNSAFE.compareAndSwapLong(this, eventWaitersOffset,
@@ -820,9 +830,9 @@
             if (tryAccumulateStealCount(w)) { // transfer while idle
                 boolean untimed = (w.nextWaiter != 0L ||
                                    (workerCounts & RUNNING_COUNT_MASK) <= 1);
-                long startTime = untimed? 0 : System.nanoTime();
+                long startTime = untimed ? 0 : System.nanoTime();
                 Thread.interrupted();         // clear/ignore interrupt
-                if (eventCount != ec || w.isTerminating())
+                if (w.isTerminating() || eventCount != ec)
                     break;                    // recheck after clear
                 if (untimed)
                     LockSupport.park(w);
@@ -860,7 +870,8 @@
         if ((sw = spareWaiters) != 0 &&
             (id = (sw & SPARE_ID_MASK) - 1) >= 0 &&
             id < n && (w = ws[id]) != null &&
-            (workerCounts & RUNNING_COUNT_MASK) < parallelism &&
+            (runState >= TERMINATING ||
+             (workerCounts & RUNNING_COUNT_MASK) < parallelism) &&
             spareWaiters == sw &&
             UNSAFE.compareAndSwapInt(this, spareWaitersOffset,
                                      sw, w.nextSpare)) {
@@ -914,12 +925,8 @@
                     break;
                 }
                 w.start(recordWorker(w), ueh);
-                if ((workerCounts >>> TOTAL_COUNT_SHIFT) >= pc) {
-                    int c; // advance event count
-                    UNSAFE.compareAndSwapInt(this, eventCountOffset,
-                                             c = eventCount, c+1);
+                if ((workerCounts >>> TOTAL_COUNT_SHIFT) >= pc)
                     break; // add at most one unless total below target
-                }
             }
         }
         if (eventWaiters != 0L)
@@ -955,7 +962,7 @@
             }
             else if ((h = eventWaiters) != 0L) {
                 long nh;
-                int id = ((int)(h & WAITER_ID_MASK)) - 1;
+                int id = (((int)h) & WAITER_ID_MASK) - 1;
                 if (id >= 0 && id < n && (w = ws[id]) != null &&
                     (nh = w.nextWaiter) != 0L && // keep at least one worker
                     UNSAFE.compareAndSwapLong(this, eventWaitersOffset, h, nh))
@@ -1003,24 +1010,31 @@
         int pc = parallelism;
         while (w.runState == 0) {
             int rs = runState;
-            if (rs >= TERMINATING) { // propagate shutdown
+            if (rs >= TERMINATING) {           // propagate shutdown
                 w.shutdown();
                 break;
             }
             if ((inactivate || (active && (rs & ACTIVE_COUNT_MASK) >= pc)) &&
-                UNSAFE.compareAndSwapInt(this, runStateOffset, rs, rs - 1))
+                UNSAFE.compareAndSwapInt(this, runStateOffset, rs, --rs)) {
                 inactivate = active = w.active = false;
-            int wc = workerCounts;
+                if (rs == SHUTDOWN) {          // all inactive and shut down
+                    tryTerminate(false);
+                    continue;
+                }
+            }
+            int wc = workerCounts;             // try to suspend as spare
             if ((wc & RUNNING_COUNT_MASK) > pc) {
                 if (!(inactivate |= active) && // must inactivate to suspend
-                    workerCounts == wc &&      // try to suspend as spare
+                    workerCounts == wc &&
                     UNSAFE.compareAndSwapInt(this, workerCountsOffset,
                                              wc, wc - ONE_RUNNING))
                     w.suspendAsSpare();
             }
             else if ((wc >>> TOTAL_COUNT_SHIFT) < pc)
                 helpMaintainParallelism();     // not enough workers
-            else if (!ran) {
+            else if (ran)
+                break;
+            else {
                 long h = eventWaiters;
                 int ec = eventCount;
                 if (h != 0L && (int)(h >>> EVENT_COUNT_SHIFT) != ec)
@@ -1032,8 +1046,6 @@
                 else if (!(inactivate |= active))
                     eventSync(w, wec);         // must inactivate before sync
             }
-            else
-                break;
         }
     }
 
@@ -1043,35 +1055,67 @@
      *
      * @param joinMe the task to join
      * @param worker the current worker thread
+     * @param timed true if wait should time out
+     * @param nanos timeout value if timed
      */
-    final void awaitJoin(ForkJoinTask<?> joinMe, ForkJoinWorkerThread worker) {
+    final void awaitJoin(ForkJoinTask<?> joinMe, ForkJoinWorkerThread worker,
+                         boolean timed, long nanos) {
+        long startTime = timed ? System.nanoTime() : 0L;
         int retries = 2 + (parallelism >> 2); // #helpJoins before blocking
+        boolean running = true;               // false when count decremented
         while (joinMe.status >= 0) {
-            int wc;
-            worker.helpJoinTask(joinMe);
+            if (runState >= TERMINATING) {
+                joinMe.cancelIgnoringExceptions();
+                break;
+            }
+            running = worker.helpJoinTask(joinMe, running);
             if (joinMe.status < 0)
                 break;
-            else if (retries > 0)
+            if (retries > 0) {
                 --retries;
-            else if (((wc = workerCounts) & RUNNING_COUNT_MASK) != 0 &&
-                     UNSAFE.compareAndSwapInt(this, workerCountsOffset,
-                                              wc, wc - ONE_RUNNING)) {
-                int stat, c; long h;
-                while ((stat = joinMe.status) >= 0 &&
-                       (h = eventWaiters) != 0L && // help release others
-                       (int)(h >>> EVENT_COUNT_SHIFT) != eventCount)
+                continue;
+            }
+            int wc = workerCounts;
+            if ((wc & RUNNING_COUNT_MASK) != 0) {
+                if (running) {
+                    if (!UNSAFE.compareAndSwapInt(this, workerCountsOffset,
+                                                  wc, wc - ONE_RUNNING))
+                        continue;
+                    running = false;
+                }
+                long h = eventWaiters;
+                if (h != 0L && (int)(h >>> EVENT_COUNT_SHIFT) != eventCount)
                     releaseEventWaiters();
-                if (stat >= 0 &&
-                    ((workerCounts & RUNNING_COUNT_MASK) == 0 ||
-                     (stat =
-                      joinMe.internalAwaitDone(JOIN_TIMEOUT_MILLIS)) >= 0))
-                    helpMaintainParallelism(); // timeout or no running workers
-                do {} while (!UNSAFE.compareAndSwapInt
-                             (this, workerCountsOffset,
-                              c = workerCounts, c + ONE_RUNNING));
-                if (stat < 0)
-                    break;   // else restart
+                if ((workerCounts & RUNNING_COUNT_MASK) != 0) {
+                    long ms; int ns;
+                    if (!timed) {
+                        ms = JOIN_TIMEOUT_MILLIS;
+                        ns = 0;
+                    }
+                    else { // at most JOIN_TIMEOUT_MILLIS per wait
+                        long nt = nanos - (System.nanoTime() - startTime);
+                        if (nt <= 0L)
+                            break;
+                        ms = nt / 1000000;
+                        if (ms > JOIN_TIMEOUT_MILLIS) {
+                            ms = JOIN_TIMEOUT_MILLIS;
+                            ns = 0;
+                        }
+                        else
+                            ns = (int) (nt % 1000000);
+                    }
+                    joinMe.internalAwaitDone(ms, ns);
+                }
+                if (joinMe.status < 0)
+                    break;
             }
+            helpMaintainParallelism();
+        }
+        if (!running) {
+            int c;
+            do {} while (!UNSAFE.compareAndSwapInt
+                         (this, workerCountsOffset,
+                          c = workerCounts, c + ONE_RUNNING));
         }
     }
 
@@ -1082,9 +1126,10 @@
         throws InterruptedException {
         while (!blocker.isReleasable()) {
             int wc = workerCounts;
-            if ((wc & RUNNING_COUNT_MASK) != 0 &&
-                UNSAFE.compareAndSwapInt(this, workerCountsOffset,
-                                         wc, wc - ONE_RUNNING)) {
+            if ((wc & RUNNING_COUNT_MASK) == 0)
+                helpMaintainParallelism();
+            else if (UNSAFE.compareAndSwapInt(this, workerCountsOffset,
+                                              wc, wc - ONE_RUNNING)) {
                 try {
                     while (!blocker.isReleasable()) {
                         long h = eventWaiters;
@@ -1129,12 +1174,11 @@
         // Finish now if all threads terminated; else in some subsequent call
         if ((workerCounts >>> TOTAL_COUNT_SHIFT) == 0) {
             advanceRunLevel(TERMINATED);
-            termination.arrive();
+            termination.forceTermination();
         }
         return true;
     }
 
-
     /**
      * Actions on transition to TERMINATING
      *
@@ -1325,17 +1369,13 @@
     // Execution methods
 
     /**
-     * Common code for execute, invoke and submit
+     * Submits task and creates, starts, or resumes some workers if necessary
      */
     private <T> void doSubmit(ForkJoinTask<T> task) {
-        if (task == null)
-            throw new NullPointerException();
-        if (runState >= SHUTDOWN)
-            throw new RejectedExecutionException();
         submissionQueue.offer(task);
         int c; // try to increment event count -- CAS failure OK
         UNSAFE.compareAndSwapInt(this, eventCountOffset, c = eventCount, c+1);
-        helpMaintainParallelism(); // create, start, or resume some workers
+        helpMaintainParallelism();
     }
 
     /**
@@ -1348,8 +1388,33 @@
      *         scheduled for execution
      */
     public <T> T invoke(ForkJoinTask<T> task) {
-        doSubmit(task);
-        return task.join();
+        if (task == null)
+            throw new NullPointerException();
+        if (runState >= SHUTDOWN)
+            throw new RejectedExecutionException();
+        Thread t = Thread.currentThread();
+        if ((t instanceof ForkJoinWorkerThread) &&
+            ((ForkJoinWorkerThread)t).pool == this)
+            return task.invoke();  // bypass submit if in same pool
+        else {
+            doSubmit(task);
+            return task.join();
+        }
+    }
+
+    /**
+     * Unless terminating, forks task if within an ongoing FJ
+     * computation in the current pool, else submits as external task.
+     */
+    private <T> void forkOrSubmit(ForkJoinTask<T> task) {
+        if (runState >= SHUTDOWN)
+            throw new RejectedExecutionException();
+        Thread t = Thread.currentThread();
+        if ((t instanceof ForkJoinWorkerThread) &&
+            ((ForkJoinWorkerThread)t).pool == this)
+            task.fork();
+        else
+            doSubmit(task);
     }
 
     /**
@@ -1361,7 +1426,9 @@
      *         scheduled for execution
      */
     public void execute(ForkJoinTask<?> task) {
-        doSubmit(task);
+        if (task == null)
+            throw new NullPointerException();
+        forkOrSubmit(task);
     }
 
     // AbstractExecutorService methods
@@ -1372,12 +1439,14 @@
      *         scheduled for execution
      */
     public void execute(Runnable task) {
+        if (task == null)
+            throw new NullPointerException();
         ForkJoinTask<?> job;
         if (task instanceof ForkJoinTask<?>) // avoid re-wrap
             job = (ForkJoinTask<?>) task;
         else
             job = ForkJoinTask.adapt(task, null);
-        doSubmit(job);
+        forkOrSubmit(job);
     }
 
     /**
@@ -1390,7 +1459,9 @@
      *         scheduled for execution
      */
     public <T> ForkJoinTask<T> submit(ForkJoinTask<T> task) {
-        doSubmit(task);
+        if (task == null)
+            throw new NullPointerException();
+        forkOrSubmit(task);
         return task;
     }
 
@@ -1400,8 +1471,10 @@
      *         scheduled for execution
      */
     public <T> ForkJoinTask<T> submit(Callable<T> task) {
+        if (task == null)
+            throw new NullPointerException();
         ForkJoinTask<T> job = ForkJoinTask.adapt(task);
-        doSubmit(job);
+        forkOrSubmit(job);
         return job;
     }
 
@@ -1411,8 +1484,10 @@
      *         scheduled for execution
      */
     public <T> ForkJoinTask<T> submit(Runnable task, T result) {
+        if (task == null)
+            throw new NullPointerException();
         ForkJoinTask<T> job = ForkJoinTask.adapt(task, result);
-        doSubmit(job);
+        forkOrSubmit(job);
         return job;
     }
 
@@ -1422,12 +1497,14 @@
      *         scheduled for execution
      */
     public ForkJoinTask<?> submit(Runnable task) {
+        if (task == null)
+            throw new NullPointerException();
         ForkJoinTask<?> job;
         if (task instanceof ForkJoinTask<?>) // avoid re-wrap
             job = (ForkJoinTask<?>) task;
         else
             job = ForkJoinTask.adapt(task, null);
-        doSubmit(job);
+        forkOrSubmit(job);
         return job;
     }
 
@@ -1725,8 +1802,11 @@
      * commenced but not yet completed.  This method may be useful for
      * debugging. A return of {@code true} reported a sufficient
      * period after shutdown may indicate that submitted tasks have
-     * ignored or suppressed interruption, causing this executor not
-     * to properly terminate.
+     * ignored or suppressed interruption, or are waiting for IO,
+     * causing this executor not to properly terminate. (See the
+     * advisory notes for class {@link ForkJoinTask} stating that
+     * tasks should not normally entail blocking operations.  But if
+     * they do, they must abort them on interrupt.)
      *
      * @return {@code true} if terminating but not yet terminated
      */
@@ -1764,10 +1844,11 @@
     public boolean awaitTermination(long timeout, TimeUnit unit)
         throws InterruptedException {
         try {
-            return termination.awaitAdvanceInterruptibly(0, timeout, unit) > 0;
+            termination.awaitAdvanceInterruptibly(0, timeout, unit);
         } catch (TimeoutException ex) {
             return false;
         }
+        return true;
     }
 
     /**
--- a/src/share/classes/java/util/concurrent/ForkJoinTask.java	Thu Feb 10 21:36:18 2011 +0300
+++ b/src/share/classes/java/util/concurrent/ForkJoinTask.java	Fri Feb 11 12:14:38 2011 -0800
@@ -42,6 +42,16 @@
 import java.util.RandomAccess;
 import java.util.Map;
 import java.util.WeakHashMap;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.RunnableFuture;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
 
 /**
  * Abstract base class for tasks that run within a {@link ForkJoinPool}.
@@ -129,6 +139,16 @@
  * result in exceptions or errors, possibly including
  * {@code ClassCastException}.
  *
+ * <p>Method {@link #join} and its variants are appropriate for use
+ * only when completion dependencies are acyclic; that is, the
+ * parallel computation can be described as a directed acyclic graph
+ * (DAG). Otherwise, executions may encounter a form of deadlock as
+ * tasks cyclically wait for each other.  However, this framework
+ * supports other methods and techniques (for example the use of
+ * {@link Phaser}, {@link #helpQuiesce}, and {@link #complete}) that
+ * may be of use in constructing custom subclasses for problems that
+ * are not statically structured as DAGs.
+ *
  * <p>Most base support methods are {@code final}, to prevent
  * overriding of implementations that are intrinsically tied to the
  * underlying lightweight task scheduling framework.  Developers
@@ -143,9 +163,10 @@
  * computation. Large tasks should be split into smaller subtasks,
  * usually via recursive decomposition. As a very rough rule of thumb,
  * a task should perform more than 100 and less than 10000 basic
- * computational steps. If tasks are too big, then parallelism cannot
- * improve throughput. If too small, then memory and internal task
- * maintenance overhead may overwhelm processing.
+ * computational steps, and should avoid indefinite looping. If tasks
+ * are too big, then parallelism cannot improve throughput. If too
+ * small, then memory and internal task maintenance overhead may
+ * overwhelm processing.
  *
  * <p>This class provides {@code adapt} methods for {@link Runnable}
  * and {@link Callable}, that may be of use when mixing execution of
@@ -242,17 +263,20 @@
     }
 
     /**
-     * Blocks a worker thread until completion. Called only by
-     * pool. Currently unused -- pool-based waits use timeout
-     * version below.
+     * Blocks a worker thread until completed or timed out.  Called
+     * only by pool.
      */
-    final void internalAwaitDone() {
-        int s;         // the odd construction reduces lock bias effects
-        while ((s = status) >= 0) {
-            try {
+    final void internalAwaitDone(long millis, int nanos) {
+        int s = status;
+        if ((s == 0 &&
+             UNSAFE.compareAndSwapInt(this, statusOffset, 0, SIGNAL)) ||
+            s > 0)  {
+            try {     // the odd construction reduces lock bias effects
                 synchronized (this) {
-                    if (UNSAFE.compareAndSwapInt(this, statusOffset, s,SIGNAL))
-                        wait();
+                    if (status > 0)
+                        wait(millis, nanos);
+                    else
+                        notifyAll();
                 }
             } catch (InterruptedException ie) {
                 cancelIfTerminating();
@@ -261,46 +285,61 @@
     }
 
     /**
-     * Blocks a worker thread until completed or timed out.  Called
-     * only by pool.
-     *
-     * @return status on exit
-     */
-    final int internalAwaitDone(long millis) {
-        int s;
-        if ((s = status) >= 0) {
-            try {
-                synchronized (this) {
-                    if (UNSAFE.compareAndSwapInt(this, statusOffset, s,SIGNAL))
-                        wait(millis, 0);
-                }
-            } catch (InterruptedException ie) {
-                cancelIfTerminating();
-            }
-            s = status;
-        }
-        return s;
-    }
-
-    /**
      * Blocks a non-worker-thread until completion.
      */
     private void externalAwaitDone() {
-        int s;
-        while ((s = status) >= 0) {
+        if (status >= 0) {
+            boolean interrupted = false;
             synchronized (this) {
-                if (UNSAFE.compareAndSwapInt(this, statusOffset, s, SIGNAL)){
-                    boolean interrupted = false;
-                    while (status >= 0) {
+                for (;;) {
+                    int s = status;
+                    if (s == 0)
+                        UNSAFE.compareAndSwapInt(this, statusOffset,
+                                                 0, SIGNAL);
+                    else if (s < 0) {
+                        notifyAll();
+                        break;
+                    }
+                    else {
                         try {
                             wait();
                         } catch (InterruptedException ie) {
                             interrupted = true;
                         }
                     }
-                    if (interrupted)
-                        Thread.currentThread().interrupt();
-                    break;
+                }
+            }
+            if (interrupted)
+                Thread.currentThread().interrupt();
+        }
+    }
+
+    /**
+     * Blocks a non-worker-thread until completion or interruption or timeout.
+     */
+    private void externalInterruptibleAwaitDone(boolean timed, long nanos)
+        throws InterruptedException {
+        if (Thread.interrupted())
+            throw new InterruptedException();
+        if (status >= 0) {
+            long startTime = timed ? System.nanoTime() : 0L;
+            synchronized (this) {
+                for (;;) {
+                    long nt;
+                    int s = status;
+                    if (s == 0)
+                        UNSAFE.compareAndSwapInt(this, statusOffset,
+                                                 0, SIGNAL);
+                    else if (s < 0) {
+                        notifyAll();
+                        break;
+                    }
+                    else if (!timed)
+                        wait();
+                    else if ((nt = nanos - (System.nanoTime()-startTime)) > 0L)
+                        wait(nt / 1000000, (int)(nt % 1000000));
+                    else
+                        break;
                 }
             }
         }
@@ -335,7 +374,7 @@
      * #isDone} returning {@code true}.
      *
      * <p>This method may be invoked only from within {@code
-     * ForkJoinTask} computations (as may be determined using method
+     * ForkJoinPool} computations (as may be determined using method
      * {@link #inForkJoinPool}).  Attempts to invoke in other contexts
      * result in exceptions or errors, possibly including {@code
      * ClassCastException}.
@@ -349,10 +388,13 @@
     }
 
     /**
-     * Returns the result of the computation when it {@link #isDone is done}.
-     * This method differs from {@link #get()} in that
+     * Returns the result of the computation when it {@link #isDone is
+     * done}.  This method differs from {@link #get()} in that
      * abnormal completion results in {@code RuntimeException} or
-     * {@code Error}, not {@code ExecutionException}.
+     * {@code Error}, not {@code ExecutionException}, and that
+     * interrupts of the calling thread do <em>not</em> cause the
+     * method to abruptly return by throwing {@code
+     * InterruptedException}.
      *
      * @return the computed result
      */
@@ -394,7 +436,7 @@
      * unprocessed.
      *
      * <p>This method may be invoked only from within {@code
-     * ForkJoinTask} computations (as may be determined using method
+     * ForkJoinPool} computations (as may be determined using method
      * {@link #inForkJoinPool}).  Attempts to invoke in other contexts
      * result in exceptions or errors, possibly including {@code
      * ClassCastException}.
@@ -422,7 +464,7 @@
      * normally or exceptionally, or left unprocessed.
      *
      * <p>This method may be invoked only from within {@code
-     * ForkJoinTask} computations (as may be determined using method
+     * ForkJoinPool} computations (as may be determined using method
      * {@link #inForkJoinPool}).  Attempts to invoke in other contexts
      * result in exceptions or errors, possibly including {@code
      * ClassCastException}.
@@ -477,7 +519,7 @@
      * unprocessed.
      *
      * <p>This method may be invoked only from within {@code
-     * ForkJoinTask} computations (as may be determined using method
+     * ForkJoinPool} computations (as may be determined using method
      * {@link #inForkJoinPool}).  Attempts to invoke in other contexts
      * result in exceptions or errors, possibly including {@code
      * ClassCastException}.
@@ -529,25 +571,28 @@
 
     /**
      * Attempts to cancel execution of this task. This attempt will
-     * fail if the task has already completed, has already been
-     * cancelled, or could not be cancelled for some other reason. If
-     * successful, and this task has not started when cancel is
-     * called, execution of this task is suppressed, {@link
-     * #isCancelled} will report true, and {@link #join} will result
-     * in a {@code CancellationException} being thrown.
+     * fail if the task has already completed or could not be
+     * cancelled for some other reason. If successful, and this task
+     * has not started when {@code cancel} is called, execution of
+     * this task is suppressed. After this method returns
+     * successfully, unless there is an intervening call to {@link
+     * #reinitialize}, subsequent calls to {@link #isCancelled},
+     * {@link #isDone}, and {@code cancel} will return {@code true}
+     * and calls to {@link #join} and related methods will result in
+     * {@code CancellationException}.
      *
      * <p>This method may be overridden in subclasses, but if so, must
-     * still ensure that these minimal properties hold. In particular,
-     * the {@code cancel} method itself must not throw exceptions.
+     * still ensure that these properties hold. In particular, the
+     * {@code cancel} method itself must not throw exceptions.
      *
      * <p>This method is designed to be invoked by <em>other</em>
      * tasks. To terminate the current task, you can just return or
      * throw an unchecked exception from its computation method, or
      * invoke {@link #completeExceptionally}.
      *
-     * @param mayInterruptIfRunning this value is ignored in the
-     * default implementation because tasks are not
-     * cancelled via interruption
+     * @param mayInterruptIfRunning this value has no effect in the
+     * default implementation because interrupts are not used to
+     * control cancellation.
      *
      * @return {@code true} if this task is now cancelled
      */
@@ -681,23 +726,13 @@
      * member of a ForkJoinPool and was interrupted while waiting
      */
     public final V get() throws InterruptedException, ExecutionException {
-        int s;
-        if (Thread.currentThread() instanceof ForkJoinWorkerThread) {
+        Thread t = Thread.currentThread();
+        if (t instanceof ForkJoinWorkerThread)
             quietlyJoin();
-            s = status;
-        }
-        else {
-            while ((s = status) >= 0) {
-                synchronized (this) { // interruptible form of awaitDone
-                    if (UNSAFE.compareAndSwapInt(this, statusOffset,
-                                                 s, SIGNAL)) {
-                        while (status >= 0)
-                            wait();
-                    }
-                }
-            }
-        }
-        if (s < NORMAL) {
+        else
+            externalInterruptibleAwaitDone(false, 0L);
+        int s = status;
+        if (s != NORMAL) {
             Throwable ex;
             if (s == CANCELLED)
                 throw new CancellationException();
@@ -723,72 +758,18 @@
      */
     public final V get(long timeout, TimeUnit unit)
         throws InterruptedException, ExecutionException, TimeoutException {
+        long nanos = unit.toNanos(timeout);
         Thread t = Thread.currentThread();
-        ForkJoinPool pool;
-        if (t instanceof ForkJoinWorkerThread) {
-            ForkJoinWorkerThread w = (ForkJoinWorkerThread) t;
-            if (status >= 0 && w.unpushTask(this))
-                quietlyExec();
-            pool = w.pool;
-        }
+        if (t instanceof ForkJoinWorkerThread)
+            ((ForkJoinWorkerThread)t).joinTask(this, true, nanos);
         else
-            pool = null;
-        /*
-         * Timed wait loop intermixes cases for FJ (pool != null) and
-         * non FJ threads. For FJ, decrement pool count but don't try
-         * for replacement; increment count on completion. For non-FJ,
-         * deal with interrupts. This is messy, but a little less so
-         * than is splitting the FJ and nonFJ cases.
-         */
-        boolean interrupted = false;
-        boolean dec = false; // true if pool count decremented
-        long nanos = unit.toNanos(timeout);
-        for (;;) {
-            if (pool == null && Thread.interrupted()) {
-                interrupted = true;
-                break;
-            }
-            int s = status;
-            if (s < 0)
-                break;
-            if (UNSAFE.compareAndSwapInt(this, statusOffset, s, SIGNAL)) {
-                long startTime = System.nanoTime();
-                long nt; // wait time
-                while (status >= 0 &&
-                       (nt = nanos - (System.nanoTime() - startTime)) > 0) {
-                    if (pool != null && !dec)
-                        dec = pool.tryDecrementRunningCount();
-                    else {
-                        long ms = nt / 1000000;
-                        int ns = (int) (nt % 1000000);
-                        try {
-                            synchronized (this) {
-                                if (status >= 0)
-                                    wait(ms, ns);
-                            }
-                        } catch (InterruptedException ie) {
-                            if (pool != null)
-                                cancelIfTerminating();
-                            else {
-                                interrupted = true;
-                                break;
-                            }
-                        }
-                    }
-                }
-                break;
-            }
-        }
-        if (pool != null && dec)
-            pool.incrementRunningCount();
-        if (interrupted)
-            throw new InterruptedException();
-        int es = status;
-        if (es != NORMAL) {
+            externalInterruptibleAwaitDone(true, nanos);
+        int s = status;
+        if (s != NORMAL) {
             Throwable ex;
-            if (es == CANCELLED)
+            if (s == CANCELLED)
                 throw new CancellationException();
-            if (es == EXCEPTIONAL && (ex = exceptionMap.get(this)) != null)
+            if (s == EXCEPTIONAL && (ex = exceptionMap.get(this)) != null)
                 throw new ExecutionException(ex);
             throw new TimeoutException();
         }
@@ -819,7 +800,7 @@
                         return;
                     }
                 }
-                w.joinTask(this);
+                w.joinTask(this, false, 0L);
             }
         }
         else
@@ -855,7 +836,7 @@
      * processed.
      *
      * <p>This method may be invoked only from within {@code
-     * ForkJoinTask} computations (as may be determined using method
+     * ForkJoinPool} computations (as may be determined using method
      * {@link #inForkJoinPool}).  Attempts to invoke in other contexts
      * result in exceptions or errors, possibly including {@code
      * ClassCastException}.
@@ -874,6 +855,12 @@
      * under any other usage conditions are not guaranteed.
      * This method may be useful when executing
      * pre-constructed trees of subtasks in loops.
+     *
+     * <p>Upon completion of this method, {@code isDone()} reports
+     * {@code false}, and {@code getException()} reports {@code
+     * null}. However, the value returned by {@code getRawResult} is
+     * unaffected. To clear this value, you can invoke {@code
+     * setRawResult(null)}.
      */
     public void reinitialize() {
         if (status == EXCEPTIONAL)
@@ -895,11 +882,12 @@
     }
 
     /**
-     * Returns {@code true} if the current thread is executing as a
-     * ForkJoinPool computation.
+     * Returns {@code true} if the current thread is a {@link
+     * ForkJoinWorkerThread} executing as a ForkJoinPool computation.
      *
-     * @return {@code true} if the current thread is executing as a
-     * ForkJoinPool computation, or false otherwise
+     * @return {@code true} if the current thread is a {@link
+     * ForkJoinWorkerThread} executing as a ForkJoinPool computation,
+     * or {@code false} otherwise
      */
     public static boolean inForkJoinPool() {
         return Thread.currentThread() instanceof ForkJoinWorkerThread;
@@ -914,7 +902,7 @@
      * were not, stolen.
      *
      * <p>This method may be invoked only from within {@code
-     * ForkJoinTask} computations (as may be determined using method
+     * ForkJoinPool} computations (as may be determined using method
      * {@link #inForkJoinPool}).  Attempts to invoke in other contexts
      * result in exceptions or errors, possibly including {@code
      * ClassCastException}.
@@ -933,7 +921,7 @@
      * fork other tasks.
      *
      * <p>This method may be invoked only from within {@code
-     * ForkJoinTask} computations (as may be determined using method
+     * ForkJoinPool} computations (as may be determined using method
      * {@link #inForkJoinPool}).  Attempts to invoke in other contexts
      * result in exceptions or errors, possibly including {@code
      * ClassCastException}.
@@ -956,7 +944,7 @@
      * exceeded.
      *
      * <p>This method may be invoked only from within {@code
-     * ForkJoinTask} computations (as may be determined using method
+     * ForkJoinPool} computations (as may be determined using method
      * {@link #inForkJoinPool}).  Attempts to invoke in other contexts
      * result in exceptions or errors, possibly including {@code
      * ClassCastException}.
@@ -1014,7 +1002,7 @@
      * otherwise.
      *
      * <p>This method may be invoked only from within {@code
-     * ForkJoinTask} computations (as may be determined using method
+     * ForkJoinPool} computations (as may be determined using method
      * {@link #inForkJoinPool}).  Attempts to invoke in other contexts
      * result in exceptions or errors, possibly including {@code
      * ClassCastException}.
@@ -1033,7 +1021,7 @@
      * be useful otherwise.
      *
      * <p>This method may be invoked only from within {@code
-     * ForkJoinTask} computations (as may be determined using method
+     * ForkJoinPool} computations (as may be determined using method
      * {@link #inForkJoinPool}).  Attempts to invoke in other contexts
      * result in exceptions or errors, possibly including {@code
      * ClassCastException}.
@@ -1056,7 +1044,7 @@
      * otherwise.
      *
      * <p>This method may be invoked only from within {@code
-     * ForkJoinTask} computations (as may be determined using method
+     * ForkJoinPool} computations (as may be determined using method
      * {@link #inForkJoinPool}).  Attempts to invoke in other contexts
      * result in exceptions or errors, possibly including {@code
      * ClassCastException}.
--- a/src/share/classes/java/util/concurrent/ForkJoinWorkerThread.java	Thu Feb 10 21:36:18 2011 +0300
+++ b/src/share/classes/java/util/concurrent/ForkJoinWorkerThread.java	Fri Feb 11 12:14:38 2011 -0800
@@ -38,16 +38,18 @@
 import java.util.Random;
 import java.util.Collection;
 import java.util.concurrent.locks.LockSupport;
+import java.util.concurrent.RejectedExecutionException;
 
 /**
- * A thread managed by a {@link ForkJoinPool}.  This class is
- * subclassable solely for the sake of adding functionality -- there
- * are no overridable methods dealing with scheduling or execution.
- * However, you can override initialization and termination methods
- * surrounding the main task processing loop.  If you do create such a
- * subclass, you will also need to supply a custom {@link
- * ForkJoinPool.ForkJoinWorkerThreadFactory} to use it in a {@code
- * ForkJoinPool}.
+ * A thread managed by a {@link ForkJoinPool}, which executes
+ * {@link ForkJoinTask}s.
+ * This class is subclassable solely for the sake of adding
+ * functionality -- there are no overridable methods dealing with
+ * scheduling or execution.  However, you can override initialization
+ * and termination methods surrounding the main task processing loop.
+ * If you do create such a subclass, you will also need to supply a
+ * custom {@link ForkJoinPool.ForkJoinWorkerThreadFactory} to use it
+ * in a {@code ForkJoinPool}.
  *
  * @since 1.7
  * @author Doug Lea
@@ -376,7 +378,7 @@
     /**
      * Initializes internal state after construction but before
      * processing any tasks. If you override this method, you must
-     * invoke @code{super.onStart()} at the beginning of the method.
+     * invoke {@code super.onStart()} at the beginning of the method.
      * Initialization requires care: Most fields must have legal
      * default values, to ensure that attempted accesses from other
      * threads work correctly even before this thread starts
@@ -384,7 +386,7 @@
      */
     protected void onStart() {
         int rs = seedGenerator.nextInt();
-        seed = rs == 0? 1 : rs; // seed must be nonzero
+        seed = (rs == 0) ? 1 : rs; // seed must be nonzero
 
         // Allocate name string and arrays in this thread
         String pid = Integer.toString(pool.getPoolNumber());
@@ -426,7 +428,7 @@
     /**
      * This method is required to be public, but should never be
      * called explicitly. It performs the main run loop to execute
-     * ForkJoinTasks.
+     * {@link ForkJoinTask}s.
      */
     public void run() {
         Throwable exception = null;
@@ -628,6 +630,19 @@
                 if (t == null)   // lost to stealer
                     break;
                 if (UNSAFE.compareAndSwapObject(q, u, t, null)) {
+                    /*
+                     * Note: here and in related methods, as a
+                     * performance (not correctness) issue, we'd like
+                     * to encourage compiler not to arbitrarily
+                     * postpone setting sp after successful CAS.
+                     * Currently there is no intrinsic for arranging
+                     * this, but using Unsafe putOrderedInt may be a
+                     * preferable strategy on some compilers even
+                     * though its main effect is a pre-, not post-
+                     * fence. To simplify possible changes, the option
+                     * is left in comments next to the associated
+                     * assignments.
+                     */
                     sp = s; // putOrderedInt may encourage more timely write
                     // UNSAFE.putOrderedInt(this, spOffset, s);
                     return t;
@@ -777,10 +792,10 @@
     // Run State management
 
     // status check methods used mainly by ForkJoinPool
-    final boolean isRunning()     { return runState == 0; }
-    final boolean isTerminated()  { return (runState & TERMINATED) != 0; }
-    final boolean isSuspended()   { return (runState & SUSPENDED) != 0; }
-    final boolean isTrimmed()     { return (runState & TRIMMED) != 0; }
+    final boolean isRunning()    { return runState == 0; }
+    final boolean isTerminated() { return (runState & TERMINATED) != 0; }
+    final boolean isSuspended()  { return (runState & SUSPENDED) != 0; }
+    final boolean isTrimmed()    { return (runState & TRIMMED) != 0; }
 
     final boolean isTerminating() {
         if ((runState & TERMINATING) != 0)
@@ -884,8 +899,7 @@
      */
     final void cancelTasks() {
         ForkJoinTask<?> cj = currentJoin; // try to cancel ongoing tasks
-        if (cj != null) {
-            currentJoin = null;
+        if (cj != null && cj.status >= 0) {
             cj.cancelIgnoringExceptions();
             try {
                 this.interrupt(); // awaken wait
@@ -893,10 +907,8 @@
             }
         }
         ForkJoinTask<?> cs = currentSteal;
-        if (cs != null) {
-            currentSteal = null;
+        if (cs != null && cs.status >= 0)
             cs.cancelIgnoringExceptions();
-        }
         while (base != sp) {
             ForkJoinTask<?> t = deqTask();
             if (t != null)
@@ -959,57 +971,23 @@
      * Possibly runs some tasks and/or blocks, until task is done.
      *
      * @param joinMe the task to join
+     * @param timed true if use timed wait
+     * @param nanos wait time if timed
      */
-    final void joinTask(ForkJoinTask<?> joinMe) {
+    final void joinTask(ForkJoinTask<?> joinMe, boolean timed, long nanos) {
         // currentJoin only written by this thread; only need ordered store
         ForkJoinTask<?> prevJoin = currentJoin;
         UNSAFE.putOrderedObject(this, currentJoinOffset, joinMe);
-        if (sp != base)
-            localHelpJoinTask(joinMe);
-        if (joinMe.status >= 0)
-            pool.awaitJoin(joinMe, this);
+        pool.awaitJoin(joinMe, this, timed, nanos);
         UNSAFE.putOrderedObject(this, currentJoinOffset, prevJoin);
     }
 
     /**
-     * Run tasks in local queue until given task is done.
-     *
-     * @param joinMe the task to join
-     */
-    private void localHelpJoinTask(ForkJoinTask<?> joinMe) {
-        int s;
-        ForkJoinTask<?>[] q;
-        while (joinMe.status >= 0 && (s = sp) != base && (q = queue) != null) {
-            int i = (q.length - 1) & --s;
-            long u = (i << qShift) + qBase; // raw offset
-            ForkJoinTask<?> t = q[i];
-            if (t == null)  // lost to a stealer
-                break;
-            if (UNSAFE.compareAndSwapObject(q, u, t, null)) {
-                /*
-                 * This recheck (and similarly in helpJoinTask)
-                 * handles cases where joinMe is independently
-                 * cancelled or forced even though there is other work
-                 * available. Back out of the pop by putting t back
-                 * into slot before we commit by writing sp.
-                 */
-                if (joinMe.status < 0) {
-                    UNSAFE.putObjectVolatile(q, u, t);
-                    break;
-                }
-                sp = s;
-                // UNSAFE.putOrderedInt(this, spOffset, s);
-                t.quietlyExec();
-            }
-        }
-    }
-
-    /**
-     * Unless terminating, tries to locate and help perform tasks for
-     * a stealer of the given task, or in turn one of its stealers.
-     * Traces currentSteal->currentJoin links looking for a thread
-     * working on a descendant of the given task and with a non-empty
-     * queue to steal back and execute tasks from.
+     * Tries to locate and help perform tasks for a stealer of the
+     * given task, or in turn one of its stealers.  Traces
+     * currentSteal->currentJoin links looking for a thread working on
+     * a descendant of the given task and with a non-empty queue to
+     * steal back and execute tasks from.
      *
      * The implementation is very branchy to cope with potential
      * inconsistencies or loops encountering chains that are stale,
@@ -1019,77 +997,127 @@
      * don't work out.
      *
      * @param joinMe the task to join
+     * @param running if false, then must update pool count upon
+     *  running a task
+     * @return value of running on exit
      */
-    final void helpJoinTask(ForkJoinTask<?> joinMe) {
-        ForkJoinWorkerThread[] ws;
-        int n;
-        if (joinMe.status < 0)                // already done
-            return;
-        if ((runState & TERMINATING) != 0) {  // cancel if shutting down
-            joinMe.cancelIgnoringExceptions();
-            return;
+    final boolean helpJoinTask(ForkJoinTask<?> joinMe, boolean running) {
+        /*
+         * Initial checks to (1) abort if terminating; (2) clean out
+         * old cancelled tasks from local queue; (3) if joinMe is next
+         * task, run it; (4) omit scan if local queue nonempty (since
+         * it may contain non-descendents of joinMe).
+         */
+        ForkJoinPool p = pool;
+        for (;;) {
+            ForkJoinTask<?>[] q;
+            int s;
+            if (joinMe.status < 0)
+                return running;
+            else if ((runState & TERMINATING) != 0) {
+                joinMe.cancelIgnoringExceptions();
+                return running;
+            }
+            else if ((s = sp) == base || (q = queue) == null)
+                break;                            // queue empty
+            else {
+                int i = (q.length - 1) & --s;
+                long u = (i << qShift) + qBase;   // raw offset
+                ForkJoinTask<?> t = q[i];
+                if (t == null)
+                    break;                        // lost to a stealer
+                else if (t != joinMe && t.status >= 0)
+                    return running;               // cannot safely help
+                else if ((running ||
+                          (running = p.tryIncrementRunningCount())) &&
+                         UNSAFE.compareAndSwapObject(q, u, t, null)) {
+                    sp = s; // putOrderedInt may encourage more timely write
+                    // UNSAFE.putOrderedInt(this, spOffset, s);
+                    t.quietlyExec();
+                }
+            }
         }
-        if ((ws = pool.workers) == null || (n = ws.length) <= 1)
-            return;                           // need at least 2 workers
 
-        ForkJoinTask<?> task = joinMe;        // base of chain
-        ForkJoinWorkerThread thread = this;   // thread with stolen task
-        for (int d = 0; d < MAX_HELP_DEPTH; ++d) { // chain length
-            // Try to find v, the stealer of task, by first using hint
-            ForkJoinWorkerThread v = ws[thread.stealHint & (n - 1)];
-            if (v == null || v.currentSteal != task) {
-                for (int j = 0; ; ++j) {      // search array
-                    if (j < n) {
-                        ForkJoinTask<?> vs;
-                        if ((v = ws[j]) != null &&
-                            (vs = v.currentSteal) != null) {
-                            if (joinMe.status < 0 || task.status < 0)
-                                return;       // stale or done
-                            if (vs == task) {
-                                thread.stealHint = j;
-                                break;        // save hint for next time
+        int n;                                    // worker array size
+        ForkJoinWorkerThread[] ws = p.workers;
+        if (ws != null && (n = ws.length) > 1) {  // need at least 2 workers
+            ForkJoinTask<?> task = joinMe;        // base of chain
+            ForkJoinWorkerThread thread = this;   // thread with stolen task
+
+            outer:for (int d = 0; d < MAX_HELP_DEPTH; ++d) { // chain length
+                // Try to find v, the stealer of task, by first using hint
+                ForkJoinWorkerThread v = ws[thread.stealHint & (n - 1)];
+                if (v == null || v.currentSteal != task) {
+                    for (int j = 0; ; ++j) {      // search array
+                        if (j < n) {
+                            ForkJoinTask<?> vs;
+                            if ((v = ws[j]) != null &&
+                                (vs = v.currentSteal) != null) {
+                                if (joinMe.status < 0)
+                                    break outer;
+                                if (vs == task) {
+                                    if (task.status < 0)
+                                        break outer; // stale
+                                    thread.stealHint = j;
+                                    break;        // save hint for next time
+                                }
                             }
                         }
+                        else
+                            break outer;          // no stealer
                     }
-                    else
-                        return;               // no stealer
                 }
+
+                // Try to help v, using specialized form of deqTask
+                for (;;) {
+                    if (joinMe.status < 0)
+                        break outer;
+                    int b = v.base;
+                    ForkJoinTask<?>[] q = v.queue;
+                    if (b == v.sp || q == null)
+                        break;                    // empty
+                    int i = (q.length - 1) & b;
+                    long u = (i << qShift) + qBase;
+                    ForkJoinTask<?> t = q[i];
+                    if (task.status < 0)
+                        break outer;              // stale
+                    if (t != null &&
+                        (running ||
+                         (running = p.tryIncrementRunningCount())) &&
+                        v.base == b++ &&
+                        UNSAFE.compareAndSwapObject(q, u, t, null)) {
+                        if (t != joinMe && joinMe.status < 0) {
+                            UNSAFE.putObjectVolatile(q, u, t);
+                            break outer;          // joinMe cancelled; back out
+                        }
+                        v.base = b;
+                        if (t.status >= 0) {
+                            ForkJoinTask<?> ps = currentSteal;
+                            int pid = poolIndex;
+                            v.stealHint = pid;
+                            UNSAFE.putOrderedObject(this,
+                                                    currentStealOffset, t);
+                            t.quietlyExec();
+                            UNSAFE.putOrderedObject(this,
+                                                    currentStealOffset, ps);
+                        }
+                    }
+                    else if ((runState & TERMINATING) != 0) {
+                        joinMe.cancelIgnoringExceptions();
+                        break outer;
+                    }
+                }
+
+                // Try to descend to find v's stealer
+                ForkJoinTask<?> next = v.currentJoin;
+                if (task.status < 0 || next == null || next == task ||
+                    joinMe.status < 0)
+                    break;                 // done, stale, dead-end, or cyclic
+                task = next;
+                thread = v;
             }
-            for (;;) { // Try to help v, using specialized form of deqTask
-                if (joinMe.status < 0)
-                    return;
-                int b = v.base;
-                ForkJoinTask<?>[] q = v.queue;
-                if (b == v.sp || q == null)
-                    break;
-                int i = (q.length - 1) & b;
-                long u = (i << qShift) + qBase;
-                ForkJoinTask<?> t = q[i];
-                int pid = poolIndex;
-                ForkJoinTask<?> ps = currentSteal;
-                if (task.status < 0)
-                    return;                   // stale or done
-                if (t != null && v.base == b++ &&
-                    UNSAFE.compareAndSwapObject(q, u, t, null)) {
-                    if (joinMe.status < 0) {
-                        UNSAFE.putObjectVolatile(q, u, t);
-                        return;               // back out on cancel
-                    }
-                    v.base = b;
-                    v.stealHint = pid;
-                    UNSAFE.putOrderedObject(this, currentStealOffset, t);
-                    t.quietlyExec();
-                    UNSAFE.putOrderedObject(this, currentStealOffset, ps);
-                }
-            }
-            // Try to descend to find v's stealer
-            ForkJoinTask<?> next = v.currentJoin;
-            if (task.status < 0 || next == null || next == task ||
-                joinMe.status < 0)
-                return;
-            task = next;
-            thread = v;
         }
+        return running;
     }
 
     /**
--- a/src/share/classes/java/util/concurrent/LinkedBlockingDeque.java	Thu Feb 10 21:36:18 2011 +0300
+++ b/src/share/classes/java/util/concurrent/LinkedBlockingDeque.java	Fri Feb 11 12:14:38 2011 -0800
@@ -1029,6 +1029,8 @@
      * elements as they existed upon construction of the iterator, and
      * may (but is not guaranteed to) reflect any modifications
      * subsequent to construction.
+     *
+     * @return an iterator over the elements in this deque in reverse order
      */
     public Iterator<E> descendingIterator() {
         return new DescendingItr();
--- a/src/share/classes/java/util/concurrent/LinkedBlockingQueue.java	Thu Feb 10 21:36:18 2011 +0300
+++ b/src/share/classes/java/util/concurrent/LinkedBlockingQueue.java	Fri Feb 11 12:14:38 2011 -0800
@@ -189,14 +189,14 @@
     }
 
     /**
-     * Creates a node and links it at end of queue.
+     * Links node at end of queue.
      *
-     * @param x the item
+     * @param node the node
      */
-    private void enqueue(E x) {
+    private void enqueue(Node<E> node) {
         // assert putLock.isHeldByCurrentThread();
         // assert last.next == null;
-        last = last.next = new Node<E>(x);
+        last = last.next = node;
     }
 
     /**
@@ -282,7 +282,7 @@
                     throw new NullPointerException();
                 if (n == capacity)
                     throw new IllegalStateException("Queue full");
-                enqueue(e);
+                enqueue(new Node<E>(e));
                 ++n;
             }
             count.set(n);
@@ -332,6 +332,7 @@
         // Note: convention in all put/take/etc is to preset local var
         // holding count negative to indicate failure unless set.
         int c = -1;
+        Node<E> node = new Node(e);
         final ReentrantLock putLock = this.putLock;
         final AtomicInteger count = this.count;
         putLock.lockInterruptibly();
@@ -347,7 +348,7 @@
             while (count.get() == capacity) {
                 notFull.await();
             }
-            enqueue(e);
+            enqueue(node);
             c = count.getAndIncrement();
             if (c + 1 < capacity)
                 notFull.signal();
@@ -382,7 +383,7 @@
                     return false;
                 nanos = notFull.awaitNanos(nanos);
             }
-            enqueue(e);
+            enqueue(new Node<E>(e));
             c = count.getAndIncrement();
             if (c + 1 < capacity)
                 notFull.signal();
@@ -411,11 +412,12 @@
         if (count.get() == capacity)
             return false;
         int c = -1;
+        Node<E> node = new Node(e);
         final ReentrantLock putLock = this.putLock;
         putLock.lock();
         try {
             if (count.get() < capacity) {
-                enqueue(e);
+                enqueue(node);
                 c = count.getAndIncrement();
                 if (c + 1 < capacity)
                     notFull.signal();
@@ -560,6 +562,27 @@
     }
 
     /**
+     * Returns {@code true} if this queue contains the specified element.
+     * More formally, returns {@code true} if and only if this queue contains
+     * at least one element {@code e} such that {@code o.equals(e)}.
+     *
+     * @param o object to be checked for containment in this queue
+     * @return {@code true} if this queue contains the specified element
+     */
+    public boolean contains(Object o) {
+        if (o == null) return false;
+        fullyLock();
+        try {
+            for (Node<E> p = head.next; p != null; p = p.next)
+                if (o.equals(p.item))
+                    return true;
+            return false;
+        } finally {
+            fullyUnlock();
+        }
+    }
+
+    /**
      * Returns an array containing all of the elements in this queue, in
      * proper sequence.
      *
@@ -645,7 +668,20 @@
     public String toString() {
         fullyLock();
         try {
-            return super.toString();
+            Node<E> p = head.next;
+            if (p == null)
+                return "[]";
+
+            StringBuilder sb = new StringBuilder();
+            sb.append('[');
+            for (;;) {
+                E e = p.item;
+                sb.append(e == this ? "(this Collection)" : e);
+                p = p.next;
+                if (p == null)
+                    return sb.append(']').toString();
+                sb.append(',').append(' ');
+            }
         } finally {
             fullyUnlock();
         }
@@ -727,12 +763,14 @@
 
     /**
      * Returns an iterator over the elements in this queue in proper sequence.
-     * The returned {@code Iterator} is a "weakly consistent" iterator that
+     * The elements will be returned in order from first (head) to last (tail).
+     *
+     * <p>The returned iterator is a "weakly consistent" iterator that
      * will never throw {@link java.util.ConcurrentModificationException
-     * ConcurrentModificationException},
-     * and guarantees to traverse elements as they existed upon
-     * construction of the iterator, and may (but is not guaranteed to)
-     * reflect any modifications subsequent to construction.
+     * ConcurrentModificationException}, and guarantees to traverse
+     * elements as they existed upon construction of the iterator, and
+     * may (but is not guaranteed to) reflect any modifications
+     * subsequent to construction.
      *
      * @return an iterator over the elements in this queue in proper sequence
      */
--- a/src/share/classes/java/util/concurrent/LinkedTransferQueue.java	Thu Feb 10 21:36:18 2011 +0300
+++ b/src/share/classes/java/util/concurrent/LinkedTransferQueue.java	Fri Feb 11 12:14:38 2011 -0800
@@ -37,10 +37,10 @@
 
 import java.util.AbstractQueue;
 import java.util.Collection;
-import java.util.ConcurrentModificationException;
 import java.util.Iterator;
 import java.util.NoSuchElementException;
 import java.util.Queue;
+import java.util.concurrent.TimeUnit;
 import java.util.concurrent.locks.LockSupport;
 
 /**
@@ -450,7 +450,7 @@
         }
 
         final boolean casItem(Object cmp, Object val) {
-            //            assert cmp == null || cmp.getClass() != Node.class;
+            // assert cmp == null || cmp.getClass() != Node.class;
             return UNSAFE.compareAndSwapObject(this, itemOffset, cmp, val);
         }
 
@@ -516,7 +516,7 @@
          * Tries to artificially match a data node -- used by remove.
          */
         final boolean tryMatchData() {
-            //            assert isData;
+            // assert isData;
             Object x = item;
             if (x != null && x != this && casItem(x, null)) {
                 LockSupport.unpark(waiter);
@@ -569,7 +569,7 @@
 
     @SuppressWarnings("unchecked")
     static <E> E cast(Object item) {
-        //        assert item == null || item.getClass() != Node.class;
+        // assert item == null || item.getClass() != Node.class;
         return (E) item;
     }
 
@@ -588,7 +588,8 @@
             throw new NullPointerException();
         Node s = null;                        // the node to append, if needed
 
-        retry: for (;;) {                     // restart on append race
+        retry:
+        for (;;) {                            // restart on append race
 
             for (Node h = head, p = h; p != null;) { // find & match first node
                 boolean isData = p.isData;
@@ -599,7 +600,7 @@
                     if (p.casItem(item, e)) { // match
                         for (Node q = p; q != h;) {
                             Node n = q.next;  // update by 2 unless singleton
-                            if (head == h && casHead(h, n == null? q : n)) {
+                            if (head == h && casHead(h, n == null ? q : n)) {
                                 h.forgetNext();
                                 break;
                             }                 // advance and retry
@@ -684,7 +685,7 @@
         for (;;) {
             Object item = s.item;
             if (item != e) {                  // matched
-                //                assert item != s;
+                // assert item != s;
                 s.forgetContents();           // avoid garbage
                 return this.<E>cast(item);
             }
@@ -809,22 +810,61 @@
          * Moves to next node after prev, or first node if prev null.
          */
         private void advance(Node prev) {
-            lastPred = lastRet;
-            lastRet = prev;
-            for (Node p = (prev == null) ? head : succ(prev);
-                 p != null; p = succ(p)) {
-                Object item = p.item;
-                if (p.isData) {
-                    if (item != null && item != p) {
-                        nextItem = LinkedTransferQueue.this.<E>cast(item);
-                        nextNode = p;
+            /*
+             * To track and avoid buildup of deleted nodes in the face
+             * of calls to both Queue.remove and Itr.remove, we must
+             * include variants of unsplice and sweep upon each
+             * advance: Upon Itr.remove, we may need to catch up links
+             * from lastPred, and upon other removes, we might need to
+             * skip ahead from stale nodes and unsplice deleted ones
+             * found while advancing.
+             */
+
+            Node r, b; // reset lastPred upon possible deletion of lastRet
+            if ((r = lastRet) != null && !r.isMatched())
+                lastPred = r;    // next lastPred is old lastRet
+            else if ((b = lastPred) == null || b.isMatched())
+                lastPred = null; // at start of list
+            else {
+                Node s, n;       // help with removal of lastPred.next
+                while ((s = b.next) != null &&
+                       s != b && s.isMatched() &&
+                       (n = s.next) != null && n != s)
+                    b.casNext(s, n);
+            }
+
+            this.lastRet = prev;
+
+            for (Node p = prev, s, n;;) {
+                s = (p == null) ? head : p.next;
+                if (s == null)
+                    break;
+                else if (s == p) {
+                    p = null;
+                    continue;
+                }
+                Object item = s.item;
+                if (s.isData) {
+                    if (item != null && item != s) {
+                        nextItem = LinkedTransferQueue.<E>cast(item);
+                        nextNode = s;
                         return;
                     }
                 }
                 else if (item == null)
                     break;
+                // assert s.isMatched();
+                if (p == null)
+                    p = s;
+                else if ((n = s.next) == null)
+                    break;
+                else if (s == n)
+                    p = null;
+                else
+                    p.casNext(s, n);
             }
             nextNode = null;
+            nextItem = null;
         }
 
         Itr() {
@@ -844,10 +884,12 @@
         }
 
         public final void remove() {
-            Node p = lastRet;
-            if (p == null) throw new IllegalStateException();
-            if (p.tryMatchData())
-                unsplice(lastPred, p);
+            final Node lastRet = this.lastRet;
+            if (lastRet == null)
+                throw new IllegalStateException();
+            this.lastRet = null;
+            if (lastRet.tryMatchData())
+                unsplice(lastPred, lastRet);
         }
     }
 
@@ -997,8 +1039,7 @@
      * Inserts the specified element at the tail of this queue.
      * As the queue is unbounded, this method will never return {@code false}.
      *
-     * @return {@code true} (as specified by
-     *         {@link BlockingQueue#offer(Object) BlockingQueue.offer})
+     * @return {@code true} (as specified by {@link Queue#offer})
      * @throws NullPointerException if the specified element is null
      */
     public boolean offer(E e) {
@@ -1130,15 +1171,15 @@
     }
 
     /**
-     * Returns an iterator over the elements in this queue in proper
-     * sequence, from head to tail.
+     * Returns an iterator over the elements in this queue in proper sequence.
+     * The elements will be returned in order from first (head) to last (tail).
      *
      * <p>The returned iterator is a "weakly consistent" iterator that
-     * will never throw
-     * {@link ConcurrentModificationException ConcurrentModificationException},
-     * and guarantees to traverse elements as they existed upon
-     * construction of the iterator, and may (but is not guaranteed
-     * to) reflect any modifications subsequent to construction.
+     * will never throw {@link java.util.ConcurrentModificationException
+     * ConcurrentModificationException}, and guarantees to traverse
+     * elements as they existed upon construction of the iterator, and
+     * may (but is not guaranteed to) reflect any modifications
+     * subsequent to construction.
      *
      * @return an iterator over the elements in this queue in proper sequence
      */
@@ -1203,6 +1244,28 @@
     }
 
     /**
+     * Returns {@code true} if this queue contains the specified element.
+     * More formally, returns {@code true} if and only if this queue contains
+     * at least one element {@code e} such that {@code o.equals(e)}.
+     *
+     * @param o object to be checked for containment in this queue
+     * @return {@code true} if this queue contains the specified element
+     */
+    public boolean contains(Object o) {
+        if (o == null) return false;
+        for (Node p = head; p != null; p = succ(p)) {
+            Object item = p.item;
+            if (p.isData) {
+                if (item != null && item != p && o.equals(item))
+                    return true;
+            }
+            else if (item == null)
+                break;
+        }
+        return false;
+    }
+
+    /**
      * Always returns {@code Integer.MAX_VALUE} because a
      * {@code LinkedTransferQueue} is not capacity constrained.
      *
--- a/src/share/classes/java/util/concurrent/Phaser.java	Thu Feb 10 21:36:18 2011 +0300
+++ b/src/share/classes/java/util/concurrent/Phaser.java	Fri Feb 11 12:14:38 2011 -0800
@@ -35,6 +35,8 @@
 
 package java.util.concurrent;
 
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.concurrent.locks.LockSupport;
 
@@ -61,38 +63,38 @@
  * Phaser} may be repeatedly awaited.  Method {@link
  * #arriveAndAwaitAdvance} has effect analogous to {@link
  * java.util.concurrent.CyclicBarrier#await CyclicBarrier.await}. Each
- * generation of a {@code Phaser} has an associated phase number. The
- * phase number starts at zero, and advances when all parties arrive
- * at the barrier, wrapping around to zero after reaching {@code
+ * generation of a phaser has an associated phase number. The phase
+ * number starts at zero, and advances when all parties arrive at the
+ * phaser, wrapping around to zero after reaching {@code
  * Integer.MAX_VALUE}. The use of phase numbers enables independent
- * control of actions upon arrival at a barrier and upon awaiting
+ * control of actions upon arrival at a phaser and upon awaiting
  * others, via two kinds of methods that may be invoked by any
  * registered party:
  *
  * <ul>
  *
  *   <li> <b>Arrival.</b> Methods {@link #arrive} and
- *       {@link #arriveAndDeregister} record arrival at a
- *       barrier. These methods do not block, but return an associated
- *       <em>arrival phase number</em>; that is, the phase number of
- *       the barrier to which the arrival applied. When the final
- *       party for a given phase arrives, an optional barrier action
- *       is performed and the phase advances.  Barrier actions,
- *       performed by the party triggering a phase advance, are
- *       arranged by overriding method {@link #onAdvance(int, int)},
- *       which also controls termination. Overriding this method is
- *       similar to, but more flexible than, providing a barrier
- *       action to a {@code CyclicBarrier}.
+ *       {@link #arriveAndDeregister} record arrival.  These methods
+ *       do not block, but return an associated <em>arrival phase
+ *       number</em>; that is, the phase number of the phaser to which
+ *       the arrival applied. When the final party for a given phase
+ *       arrives, an optional action is performed and the phase
+ *       advances.  These actions are performed by the party
+ *       triggering a phase advance, and are arranged by overriding
+ *       method {@link #onAdvance(int, int)}, which also controls
+ *       termination. Overriding this method is similar to, but more
+ *       flexible than, providing a barrier action to a {@code
+ *       CyclicBarrier}.
  *
  *   <li> <b>Waiting.</b> Method {@link #awaitAdvance} requires an
  *       argument indicating an arrival phase number, and returns when
- *       the barrier advances to (or is already at) a different phase.
+ *       the phaser advances to (or is already at) a different phase.
  *       Unlike similar constructions using {@code CyclicBarrier},
  *       method {@code awaitAdvance} continues to wait even if the
  *       waiting thread is interrupted. Interruptible and timeout
  *       versions are also available, but exceptions encountered while
  *       tasks wait interruptibly or with timeout do not change the
- *       state of the barrier. If necessary, you can perform any
+ *       state of the phaser. If necessary, you can perform any
  *       associated recovery within handlers of those exceptions,
  *       often after invoking {@code forceTermination}.  Phasers may
  *       also be used by tasks executing in a {@link ForkJoinPool},
@@ -101,26 +103,39 @@
  *
  * </ul>
  *
- * <p> <b>Termination.</b> A {@code Phaser} may enter a
- * <em>termination</em> state in which all synchronization methods
- * immediately return without updating phaser state or waiting for
- * advance, and indicating (via a negative phase value) that execution
- * is complete.  Termination is triggered when an invocation of {@code
- * onAdvance} returns {@code true}.  As illustrated below, when
- * phasers control actions with a fixed number of iterations, it is
- * often convenient to override this method to cause termination when
- * the current phase number reaches a threshold. Method {@link
- * #forceTermination} is also available to abruptly release waiting
- * threads and allow them to terminate.
+ * <p> <b>Termination.</b> A phaser may enter a <em>termination</em>
+ * state, that may be checked using method {@link #isTerminated}. Upon
+ * termination, all synchronization methods immediately return without
+ * waiting for advance, as indicated by a negative return value.
+ * Similarly, attempts to register upon termination have no effect.
+ * Termination is triggered when an invocation of {@code onAdvance}
+ * returns {@code true}. The default implementation returns {@code
+ * true} if a deregistration has caused the number of registered
+ * parties to become zero.  As illustrated below, when phasers control
+ * actions with a fixed number of iterations, it is often convenient
+ * to override this method to cause termination when the current phase
+ * number reaches a threshold. Method {@link #forceTermination} is
+ * also available to abruptly release waiting threads and allow them
+ * to terminate.
  *
- * <p> <b>Tiering.</b> Phasers may be <em>tiered</em> (i.e., arranged
- * in tree structures) to reduce contention. Phasers with large
- * numbers of parties that would otherwise experience heavy
+ * <p> <b>Tiering.</b> Phasers may be <em>tiered</em> (i.e.,
+ * constructed in tree structures) to reduce contention. Phasers with
+ * large numbers of parties that would otherwise experience heavy
  * synchronization contention costs may instead be set up so that
  * groups of sub-phasers share a common parent.  This may greatly
  * increase throughput even though it incurs greater per-operation
  * overhead.
  *
+ * <p>In a tree of tiered phasers, registration and deregistration of
+ * child phasers with their parent are managed automatically.
+ * Whenever the number of registered parties of a child phaser becomes
+ * non-zero (as established in the {@link #Phaser(Phaser,int)}
+ * constructor, {@link #register}, or {@link #bulkRegister}), the
+ * child phaser is registered with its parent.  Whenever the number of
+ * registered parties becomes zero as the result of an invocation of
+ * {@link #arriveAndDeregister}, the child phaser is deregistered
+ * from its parent.
+ *
  * <p><b>Monitoring.</b> While synchronization methods may be invoked
  * only by registered parties, the current state of a phaser may be
  * monitored by any caller.  At any given moment there are {@link
@@ -136,9 +151,9 @@
  * <p><b>Sample usages:</b>
  *
  * <p>A {@code Phaser} may be used instead of a {@code CountDownLatch}
- * to control a one-shot action serving a variable number of
- * parties. The typical idiom is for the method setting this up to
- * first register, then start the actions, then deregister, as in:
+ * to control a one-shot action serving a variable number of parties.
+ * The typical idiom is for the method setting this up to first
+ * register, then start the actions, then deregister, as in:
  *
  *  <pre> {@code
  * void runTasks(List<Runnable> tasks) {
@@ -208,34 +223,32 @@
  * }}</pre>
  *
  *
- * <p>To create a set of tasks using a tree of phasers,
- * you could use code of the following form, assuming a
- * Task class with a constructor accepting a phaser that
- * it registers for upon construction:
+ * <p>To create a set of {@code n} tasks using a tree of phasers, you
+ * could use code of the following form, assuming a Task class with a
+ * constructor accepting a {@code Phaser} that it registers with upon
+ * construction. After invocation of {@code build(new Task[n], 0, n,
+ * new Phaser())}, these tasks could then be started, for example by
+ * submitting to a pool:
  *
  *  <pre> {@code
- * void build(Task[] actions, int lo, int hi, Phaser ph) {
+ * void build(Task[] tasks, int lo, int hi, Phaser ph) {
  *   if (hi - lo > TASKS_PER_PHASER) {
  *     for (int i = lo; i < hi; i += TASKS_PER_PHASER) {
  *       int j = Math.min(i + TASKS_PER_PHASER, hi);
- *       build(actions, i, j, new Phaser(ph));
+ *       build(tasks, i, j, new Phaser(ph));
  *     }
  *   } else {
  *     for (int i = lo; i < hi; ++i)
- *       actions[i] = new Task(ph);
+ *       tasks[i] = new Task(ph);
  *       // assumes new Task(ph) performs ph.register()
  *   }
- * }
- * // .. initially called, for n tasks via
- * build(new Task[n], 0, n, new Phaser());}</pre>
+ * }}</pre>
  *
  * The best value of {@code TASKS_PER_PHASER} depends mainly on
- * expected barrier synchronization rates. A value as low as four may
- * be appropriate for extremely small per-barrier task bodies (thus
+ * expected synchronization rates. A value as low as four may
+ * be appropriate for extremely small per-phase task bodies (thus
  * high rates), or up to hundreds for extremely large ones.
  *
- * </pre>
- *
  * <p><b>Implementation notes</b>: This implementation restricts the
  * maximum number of parties to 65535. Attempts to register additional
  * parties result in {@code IllegalStateException}. However, you can and
@@ -253,60 +266,66 @@
      */
 
     /**
-     * Barrier state representation. Conceptually, a barrier contains
-     * four values:
+     * Primary state representation, holding four bit-fields:
      *
-     * * parties -- the number of parties to wait (16 bits)
-     * * unarrived -- the number of parties yet to hit barrier (16 bits)
-     * * phase -- the generation of the barrier (31 bits)
-     * * terminated -- set if barrier is terminated (1 bit)
+     * unarrived  -- the number of parties yet to hit barrier (bits  0-15)
+     * parties    -- the number of parties to wait            (bits 16-31)
+     * phase      -- the generation of the barrier            (bits 32-62)
+     * terminated -- set if barrier is terminated             (bit  63 / sign)
      *
-     * However, to efficiently maintain atomicity, these values are
-     * packed into a single (atomic) long. Termination uses the sign
-     * bit of 32 bit representation of phase, so phase is set to -1 on
-     * termination. Good performance relies on keeping state decoding
-     * and encoding simple, and keeping race windows short.
+     * Except that a phaser with no registered parties is
+     * distinguished by the otherwise illegal state of having zero
+     * parties and one unarrived parties (encoded as EMPTY below).
      *
-     * Note: there are some cheats in arrive() that rely on unarrived
-     * count being lowest 16 bits.
+     * To efficiently maintain atomicity, these values are packed into
+     * a single (atomic) long. Good performance relies on keeping
+     * state decoding and encoding simple, and keeping race windows
+     * short.
+     *
+     * All state updates are performed via CAS except initial
+     * registration of a sub-phaser (i.e., one with a non-null
+     * parent).  In this (relatively rare) case, we use built-in
+     * synchronization to lock while first registering with its
+     * parent.
+     *
+     * The phase of a subphaser is allowed to lag that of its
+     * ancestors until it is actually accessed -- see method
+     * reconcileState.
      */
     private volatile long state;
 
-    private static final int ushortMask = 0xffff;
-    private static final int phaseMask  = 0x7fffffff;
+    private static final int  MAX_PARTIES     = 0xffff;
+    private static final int  MAX_PHASE       = Integer.MAX_VALUE;
+    private static final int  PARTIES_SHIFT   = 16;
+    private static final int  PHASE_SHIFT     = 32;
+    private static final int  UNARRIVED_MASK  = 0xffff;      // to mask ints
+    private static final long PARTIES_MASK    = 0xffff0000L; // to mask longs
+    private static final long TERMINATION_BIT = 1L << 63;
+
+    // some special values
+    private static final int  ONE_ARRIVAL     = 1;
+    private static final int  ONE_PARTY       = 1 << PARTIES_SHIFT;
+    private static final int  EMPTY           = 1;
+
+    // The following unpacking methods are usually manually inlined
 
     private static int unarrivedOf(long s) {
-        return (int) (s & ushortMask);
+        int counts = (int)s;
+        return (counts == EMPTY) ? 0 : counts & UNARRIVED_MASK;
     }
 
     private static int partiesOf(long s) {
-        return ((int) s) >>> 16;
+        return (int)s >>> PARTIES_SHIFT;
     }
 
     private static int phaseOf(long s) {
-        return (int) (s >>> 32);
+        return (int)(s >>> PHASE_SHIFT);
     }
 
     private static int arrivedOf(long s) {
-        return partiesOf(s) - unarrivedOf(s);
-    }
-
-    private static long stateFor(int phase, int parties, int unarrived) {
-        return ((((long) phase) << 32) | (((long) parties) << 16) |
-                (long) unarrived);
-    }
-
-    private static long trippedStateFor(int phase, int parties) {
-        long lp = (long) parties;
-        return (((long) phase) << 32) | (lp << 16) | lp;
-    }
-
-    /**
-     * Returns message string for bad bounds exceptions.
-     */
-    private static String badBounds(int parties, int unarrived) {
-        return ("Attempt to set " + unarrived +
-                " unarrived of " + parties + " parties");
+        int counts = (int)s;
+        return (counts == EMPTY) ? 0 :
+            (counts >>> PARTIES_SHIFT) - (counts & UNARRIVED_MASK);
     }
 
     /**
@@ -315,70 +334,180 @@
     private final Phaser parent;
 
     /**
-     * The root of phaser tree. Equals this if not in a tree.  Used to
-     * support faster state push-down.
+     * The root of phaser tree. Equals this if not in a tree.
      */
     private final Phaser root;
 
-    // Wait queues
-
     /**
      * Heads of Treiber stacks for waiting threads. To eliminate
-     * contention while releasing some threads while adding others, we
+     * contention when releasing some threads while adding others, we
      * use two of them, alternating across even and odd phases.
+     * Subphasers share queues with root to speed up releases.
      */
-    private final AtomicReference<QNode> evenQ = new AtomicReference<QNode>();
-    private final AtomicReference<QNode> oddQ  = new AtomicReference<QNode>();
+    private final AtomicReference<QNode> evenQ;
+    private final AtomicReference<QNode> oddQ;
 
     private AtomicReference<QNode> queueFor(int phase) {
         return ((phase & 1) == 0) ? evenQ : oddQ;
     }
 
     /**
-     * Returns current state, first resolving lagged propagation from
-     * root if necessary.
+     * Returns message string for bounds exceptions on arrival.
      */
-    private long getReconciledState() {
-        return (parent == null) ? state : reconcileState();
+    private String badArrive(long s) {
+        return "Attempted arrival of unregistered party for " +
+            stateToString(s);
     }
 
     /**
-     * Recursively resolves state.
+     * Returns message string for bounds exceptions on registration.
      */
-    private long reconcileState() {
-        Phaser p = parent;
-        long s = state;
-        if (p != null) {
-            while (unarrivedOf(s) == 0 && phaseOf(s) != phaseOf(root.state)) {
-                long parentState = p.getReconciledState();
-                int parentPhase = phaseOf(parentState);
-                int phase = phaseOf(s = state);
-                if (phase != parentPhase) {
-                    long next = trippedStateFor(parentPhase, partiesOf(s));
-                    if (casState(s, next)) {
-                        releaseWaiters(phase);
-                        s = next;
+    private String badRegister(long s) {
+        return "Attempt to register more than " +
+            MAX_PARTIES + " parties for " + stateToString(s);
+    }
+
+    /**
+     * Main implementation for methods arrive and arriveAndDeregister.
+     * Manually tuned to speed up and minimize race windows for the
+     * common case of just decrementing unarrived field.
+     *
+     * @param deregister false for arrive, true for arriveAndDeregister
+     */
+    private int doArrive(boolean deregister) {
+        int adj = deregister ? ONE_ARRIVAL|ONE_PARTY : ONE_ARRIVAL;
+        final Phaser root = this.root;
+        for (;;) {
+            long s = (root == this) ? state : reconcileState();
+            int phase = (int)(s >>> PHASE_SHIFT);
+            int counts = (int)s;
+            int unarrived = (counts & UNARRIVED_MASK) - 1;
+            if (phase < 0)
+                return phase;
+            else if (counts == EMPTY || unarrived < 0) {
+                if (root == this || reconcileState() == s)
+                    throw new IllegalStateException(badArrive(s));
+            }
+            else if (UNSAFE.compareAndSwapLong(this, stateOffset, s, s-=adj)) {
+                if (unarrived == 0) {
+                    long n = s & PARTIES_MASK;  // base of next state
+                    int nextUnarrived = (int)n >>> PARTIES_SHIFT;
+                    if (root != this)
+                        return parent.doArrive(nextUnarrived == 0);
+                    if (onAdvance(phase, nextUnarrived))
+                        n |= TERMINATION_BIT;
+                    else if (nextUnarrived == 0)
+                        n |= EMPTY;
+                    else
+                        n |= nextUnarrived;
+                    n |= (long)((phase + 1) & MAX_PHASE) << PHASE_SHIFT;
+                    UNSAFE.compareAndSwapLong(this, stateOffset, s, n);
+                    releaseWaiters(phase);
+                }
+                return phase;
+            }
+        }
+    }
+
+    /**
+     * Implementation of register, bulkRegister
+     *
+     * @param registrations number to add to both parties and
+     * unarrived fields. Must be greater than zero.
+     */
+    private int doRegister(int registrations) {
+        // adjustment to state
+        long adj = ((long)registrations << PARTIES_SHIFT) | registrations;
+        final Phaser parent = this.parent;
+        int phase;
+        for (;;) {
+            long s = state;
+            int counts = (int)s;
+            int parties = counts >>> PARTIES_SHIFT;
+            int unarrived = counts & UNARRIVED_MASK;
+            if (registrations > MAX_PARTIES - parties)
+                throw new IllegalStateException(badRegister(s));
+            else if ((phase = (int)(s >>> PHASE_SHIFT)) < 0)
+                break;
+            else if (counts != EMPTY) {             // not 1st registration
+                if (parent == null || reconcileState() == s) {
+                    if (unarrived == 0)             // wait out advance
+                        root.internalAwaitAdvance(phase, null);
+                    else if (UNSAFE.compareAndSwapLong(this, stateOffset,
+                                                       s, s + adj))
+                        break;
+                }
+            }
+            else if (parent == null) {              // 1st root registration
+                long next = ((long)phase << PHASE_SHIFT) | adj;
+                if (UNSAFE.compareAndSwapLong(this, stateOffset, s, next))
+                    break;
+            }
+            else {
+                synchronized (this) {               // 1st sub registration
+                    if (state == s) {               // recheck under lock
+                        parent.doRegister(1);
+                        do {                        // force current phase
+                            phase = (int)(root.state >>> PHASE_SHIFT);
+                            // assert phase < 0 || (int)state == EMPTY;
+                        } while (!UNSAFE.compareAndSwapLong
+                                 (this, stateOffset, state,
+                                  ((long)phase << PHASE_SHIFT) | adj));
+                        break;
                     }
                 }
             }
         }
+        return phase;
+    }
+
+    /**
+     * Resolves lagged phase propagation from root if necessary.
+     * Reconciliation normally occurs when root has advanced but
+     * subphasers have not yet done so, in which case they must finish
+     * their own advance by setting unarrived to parties (or if
+     * parties is zero, resetting to unregistered EMPTY state).
+     * However, this method may also be called when "floating"
+     * subphasers with possibly some unarrived parties are merely
+     * catching up to current phase, in which case counts are
+     * unaffected.
+     *
+     * @return reconciled state
+     */
+    private long reconcileState() {
+        final Phaser root = this.root;
+        long s = state;
+        if (root != this) {
+            int phase, u, p;
+            // CAS root phase with current parties; possibly trip unarrived
+            while ((phase = (int)(root.state >>> PHASE_SHIFT)) !=
+                   (int)(s >>> PHASE_SHIFT) &&
+                   !UNSAFE.compareAndSwapLong
+                   (this, stateOffset, s,
+                    s = (((long)phase << PHASE_SHIFT) |
+                         (s & PARTIES_MASK) |
+                         ((p = (int)s >>> PARTIES_SHIFT) == 0 ? EMPTY :
+                          (u = (int)s & UNARRIVED_MASK) == 0 ? p : u))))
+                s = state;
+        }
         return s;
     }
 
     /**
-     * Creates a new phaser without any initially registered parties,
-     * initial phase number 0, and no parent. Any thread using this
+     * Creates a new phaser with no initially registered parties, no
+     * parent, and initial phase number 0. Any thread using this
      * phaser will need to first register for it.
      */
     public Phaser() {
-        this(null);
+        this(null, 0);
     }
 
     /**
-     * Creates a new phaser with the given numbers of registered
-     * unarrived parties, initial phase number 0, and no parent.
+     * Creates a new phaser with the given number of registered
+     * unarrived parties, no parent, and initial phase number 0.
      *
-     * @param parties the number of parties required to trip barrier
+     * @param parties the number of parties required to advance to the
+     * next phase
      * @throws IllegalArgumentException if parties less than zero
      * or greater than the maximum number of parties supported
      */
@@ -387,54 +516,62 @@
     }
 
     /**
-     * Creates a new phaser with the given parent, without any
-     * initially registered parties. If parent is non-null this phaser
-     * is registered with the parent and its initial phase number is
-     * the same as that of parent phaser.
+     * Equivalent to {@link #Phaser(Phaser, int) Phaser(parent, 0)}.
      *
      * @param parent the parent phaser
      */
     public Phaser(Phaser parent) {
-        int phase = 0;
-        this.parent = parent;
-        if (parent != null) {
-            this.root = parent.root;
-            phase = parent.register();
-        }
-        else
-            this.root = this;
-        this.state = trippedStateFor(phase, 0);
+        this(parent, 0);
     }
 
     /**
-     * Creates a new phaser with the given parent and numbers of
-     * registered unarrived parties. If parent is non-null, this phaser
-     * is registered with the parent and its initial phase number is
-     * the same as that of parent phaser.
+     * Creates a new phaser with the given parent and number of
+     * registered unarrived parties.  When the given parent is non-null
+     * and the given number of parties is greater than zero, this
+     * child phaser is registered with its parent.
      *
      * @param parent the parent phaser
-     * @param parties the number of parties required to trip barrier
+     * @param parties the number of parties required to advance to the
+     * next phase
      * @throws IllegalArgumentException if parties less than zero
      * or greater than the maximum number of parties supported
      */
     public Phaser(Phaser parent, int parties) {
-        if (parties < 0 || parties > ushortMask)
+        if (parties >>> PARTIES_SHIFT != 0)
             throw new IllegalArgumentException("Illegal number of parties");
         int phase = 0;
         this.parent = parent;
         if (parent != null) {
-            this.root = parent.root;
-            phase = parent.register();
+            final Phaser root = parent.root;
+            this.root = root;
+            this.evenQ = root.evenQ;
+            this.oddQ = root.oddQ;
+            if (parties != 0)
+                phase = parent.doRegister(1);
         }
-        else
+        else {
             this.root = this;
-        this.state = trippedStateFor(phase, parties);
+            this.evenQ = new AtomicReference<QNode>();
+            this.oddQ = new AtomicReference<QNode>();
+        }
+        this.state = (parties == 0) ? (long)EMPTY :
+            ((long)phase << PHASE_SHIFT) |
+            ((long)parties << PARTIES_SHIFT) |
+            ((long)parties);
     }
 
     /**
-     * Adds a new unarrived party to this phaser.
+     * Adds a new unarrived party to this phaser.  If an ongoing
+     * invocation of {@link #onAdvance} is in progress, this method
+     * may await its completion before returning.  If this phaser has
+     * a parent, and this phaser previously had no registered parties,
+     * this child phaser is also registered with its parent. If
+     * this phaser is terminated, the attempt to register has
+     * no effect, and a negative value is returned.
      *
-     * @return the arrival phase number to which this registration applied
+     * @return the arrival phase number to which this registration
+     * applied.  If this value is negative, then this phaser has
+     * terminated, in which case registration has no effect.
      * @throws IllegalStateException if attempting to register more
      * than the maximum supported number of parties
      */
@@ -444,11 +581,22 @@
 
     /**
      * Adds the given number of new unarrived parties to this phaser.
+     * If an ongoing invocation of {@link #onAdvance} is in progress,
+     * this method may await its completion before returning.  If this
+     * phaser has a parent, and the given number of parties is greater
+     * than zero, and this phaser previously had no registered
+     * parties, this child phaser is also registered with its parent.
+     * If this phaser is terminated, the attempt to register has no
+     * effect, and a negative value is returned.
      *
-     * @param parties the number of parties required to trip barrier
-     * @return the arrival phase number to which this registration applied
+     * @param parties the number of additional parties required to
+     * advance to the next phase
+     * @return the arrival phase number to which this registration
+     * applied.  If this value is negative, then this phaser has
+     * terminated, in which case registration has no effect.
      * @throws IllegalStateException if attempting to register more
      * than the maximum supported number of parties
+     * @throws IllegalArgumentException if {@code parties < 0}
      */
     public int bulkRegister(int parties) {
         if (parties < 0)
@@ -459,258 +607,210 @@
     }
 
     /**
-     * Shared code for register, bulkRegister
-     */
-    private int doRegister(int registrations) {
-        int phase;
-        for (;;) {
-            long s = getReconciledState();
-            phase = phaseOf(s);
-            int unarrived = unarrivedOf(s) + registrations;
-            int parties = partiesOf(s) + registrations;
-            if (phase < 0)
-                break;
-            if (parties > ushortMask || unarrived > ushortMask)
-                throw new IllegalStateException(badBounds(parties, unarrived));
-            if (phase == phaseOf(root.state) &&
-                casState(s, stateFor(phase, parties, unarrived)))
-                break;
-        }
-        return phase;
-    }
-
-    /**
-     * Arrives at the barrier, but does not wait for others.  (You can
-     * in turn wait for others via {@link #awaitAdvance}).  It is an
-     * unenforced usage error for an unregistered party to invoke this
-     * method.
+     * Arrives at this phaser, without waiting for others to arrive.
+     *
+     * <p>It is a usage error for an unregistered party to invoke this
+     * method.  However, this error may result in an {@code
+     * IllegalStateException} only upon some subsequent operation on
+     * this phaser, if ever.
      *
      * @return the arrival phase number, or a negative value if terminated
      * @throws IllegalStateException if not terminated and the number
      * of unarrived parties would become negative
      */
     public int arrive() {
-        int phase;
-        for (;;) {
-            long s = state;
-            phase = phaseOf(s);
-            if (phase < 0)
-                break;
-            int parties = partiesOf(s);
-            int unarrived = unarrivedOf(s) - 1;
-            if (unarrived > 0) {        // Not the last arrival
-                if (casState(s, s - 1)) // s-1 adds one arrival
-                    break;
-            }
-            else if (unarrived == 0) {  // the last arrival
-                Phaser par = parent;
-                if (par == null) {      // directly trip
-                    if (casState
-                        (s,
-                         trippedStateFor(onAdvance(phase, parties) ? -1 :
-                                         ((phase + 1) & phaseMask), parties))) {
-                        releaseWaiters(phase);
-                        break;
-                    }
-                }
-                else {                  // cascade to parent
-                    if (casState(s, s - 1)) { // zeroes unarrived
-                        par.arrive();
-                        reconcileState();
-                        break;
-                    }
-                }
-            }
-            else if (phase != phaseOf(root.state)) // or if unreconciled
-                reconcileState();
-            else
-                throw new IllegalStateException(badBounds(parties, unarrived));
-        }
-        return phase;
+        return doArrive(false);
     }
 
     /**
-     * Arrives at the barrier and deregisters from it without waiting
-     * for others. Deregistration reduces the number of parties
-     * required to trip the barrier in future phases.  If this phaser
+     * Arrives at this phaser and deregisters from it without waiting
+     * for others to arrive. Deregistration reduces the number of
+     * parties required to advance in future phases.  If this phaser
      * has a parent, and deregistration causes this phaser to have
-     * zero parties, this phaser also arrives at and is deregistered
-     * from its parent.  It is an unenforced usage error for an
-     * unregistered party to invoke this method.
+     * zero parties, this phaser is also deregistered from its parent.
+     *
+     * <p>It is a usage error for an unregistered party to invoke this
+     * method.  However, this error may result in an {@code
+     * IllegalStateException} only upon some subsequent operation on
+     * this phaser, if ever.
      *
      * @return the arrival phase number, or a negative value if terminated
      * @throws IllegalStateException if not terminated and the number
      * of registered or unarrived parties would become negative
      */
     public int arriveAndDeregister() {
-        // similar code to arrive, but too different to merge
-        Phaser par = parent;
-        int phase;
-        for (;;) {
-            long s = state;
-            phase = phaseOf(s);
-            if (phase < 0)
-                break;
-            int parties = partiesOf(s) - 1;
-            int unarrived = unarrivedOf(s) - 1;
-            if (parties >= 0) {
-                if (unarrived > 0 || (unarrived == 0 && par != null)) {
-                    if (casState
-                        (s,
-                         stateFor(phase, parties, unarrived))) {
-                        if (unarrived == 0) {
-                            par.arriveAndDeregister();
-                            reconcileState();
-                        }
-                        break;
-                    }
-                    continue;
-                }
-                if (unarrived == 0) {
-                    if (casState
-                        (s,
-                         trippedStateFor(onAdvance(phase, parties) ? -1 :
-                                         ((phase + 1) & phaseMask), parties))) {
-                        releaseWaiters(phase);
-                        break;
-                    }
-                    continue;
-                }
-                if (par != null && phase != phaseOf(root.state)) {
-                    reconcileState();
-                    continue;
-                }
-            }
-            throw new IllegalStateException(badBounds(parties, unarrived));
-        }
-        return phase;
+        return doArrive(true);
     }
 
     /**
-     * Arrives at the barrier and awaits others. Equivalent in effect
+     * Arrives at this phaser and awaits others. Equivalent in effect
      * to {@code awaitAdvance(arrive())}.  If you need to await with
      * interruption or timeout, you can arrange this with an analogous
-     * construction using one of the other forms of the awaitAdvance
-     * method.  If instead you need to deregister upon arrival use
-     * {@code arriveAndDeregister}. It is an unenforced usage error
-     * for an unregistered party to invoke this method.
+     * construction using one of the other forms of the {@code
+     * awaitAdvance} method.  If instead you need to deregister upon
+     * arrival, use {@code awaitAdvance(arriveAndDeregister())}.
      *
-     * @return the arrival phase number, or a negative number if terminated
+     * <p>It is a usage error for an unregistered party to invoke this
+     * method.  However, this error may result in an {@code
+     * IllegalStateException} only upon some subsequent operation on
+     * this phaser, if ever.
+     *
+     * @return the arrival phase number, or the (negative)
+     * {@linkplain #getPhase() current phase} if terminated
      * @throws IllegalStateException if not terminated and the number
      * of unarrived parties would become negative
      */
     public int arriveAndAwaitAdvance() {
-        return awaitAdvance(arrive());
+        // Specialization of doArrive+awaitAdvance eliminating some reads/paths
+        final Phaser root = this.root;
+        for (;;) {
+            long s = (root == this) ? state : reconcileState();
+            int phase = (int)(s >>> PHASE_SHIFT);
+            int counts = (int)s;
+            int unarrived = (counts & UNARRIVED_MASK) - 1;
+            if (phase < 0)
+                return phase;
+            else if (counts == EMPTY || unarrived < 0) {
+                if (reconcileState() == s)
+                    throw new IllegalStateException(badArrive(s));
+            }
+            else if (UNSAFE.compareAndSwapLong(this, stateOffset, s,
+                                               s -= ONE_ARRIVAL)) {
+                if (unarrived != 0)
+                    return root.internalAwaitAdvance(phase, null);
+                if (root != this)
+                    return parent.arriveAndAwaitAdvance();
+                long n = s & PARTIES_MASK;  // base of next state
+                int nextUnarrived = (int)n >>> PARTIES_SHIFT;
+                if (onAdvance(phase, nextUnarrived))
+                    n |= TERMINATION_BIT;
+                else if (nextUnarrived == 0)
+                    n |= EMPTY;
+                else
+                    n |= nextUnarrived;
+                int nextPhase = (phase + 1) & MAX_PHASE;
+                n |= (long)nextPhase << PHASE_SHIFT;
+                if (!UNSAFE.compareAndSwapLong(this, stateOffset, s, n))
+                    return (int)(state >>> PHASE_SHIFT); // terminated
+                releaseWaiters(phase);
+                return nextPhase;
+            }
+        }
     }
 
     /**
-     * Awaits the phase of the barrier to advance from the given phase
-     * value, returning immediately if the current phase of the
-     * barrier is not equal to the given phase value or this barrier
-     * is terminated.  It is an unenforced usage error for an
-     * unregistered party to invoke this method.
+     * Awaits the phase of this phaser to advance from the given phase
+     * value, returning immediately if the current phase is not equal
+     * to the given phase value or this phaser is terminated.
      *
      * @param phase an arrival phase number, or negative value if
      * terminated; this argument is normally the value returned by a
-     * previous call to {@code arrive} or its variants
-     * @return the next arrival phase number, or a negative value
-     * if terminated or argument is negative
+     * previous call to {@code arrive} or {@code arriveAndDeregister}.
+     * @return the next arrival phase number, or the argument if it is
+     * negative, or the (negative) {@linkplain #getPhase() current phase}
+     * if terminated
      */
     public int awaitAdvance(int phase) {
+        final Phaser root = this.root;
+        long s = (root == this) ? state : reconcileState();
+        int p = (int)(s >>> PHASE_SHIFT);
         if (phase < 0)
             return phase;
-        long s = getReconciledState();
-        int p = phaseOf(s);
-        if (p != phase)
-            return p;
-        if (unarrivedOf(s) == 0 && parent != null)
-            parent.awaitAdvance(phase);
-        // Fall here even if parent waited, to reconcile and help release
-        return untimedWait(phase);
+        if (p == phase)
+            return root.internalAwaitAdvance(phase, null);
+        return p;
     }
 
     /**
-     * Awaits the phase of the barrier to advance from the given phase
+     * Awaits the phase of this phaser to advance from the given phase
      * value, throwing {@code InterruptedException} if interrupted
-     * while waiting, or returning immediately if the current phase of
-     * the barrier is not equal to the given phase value or this
-     * barrier is terminated. It is an unenforced usage error for an
-     * unregistered party to invoke this method.
+     * while waiting, or returning immediately if the current phase is
+     * not equal to the given phase value or this phaser is
+     * terminated.
      *
      * @param phase an arrival phase number, or negative value if
      * terminated; this argument is normally the value returned by a
-     * previous call to {@code arrive} or its variants
-     * @return the next arrival phase number, or a negative value
-     * if terminated or argument is negative
+     * previous call to {@code arrive} or {@code arriveAndDeregister}.
+     * @return the next arrival phase number, or the argument if it is
+     * negative, or the (negative) {@linkplain #getPhase() current phase}
+     * if terminated
      * @throws InterruptedException if thread interrupted while waiting
      */
     public int awaitAdvanceInterruptibly(int phase)
         throws InterruptedException {
+        final Phaser root = this.root;
+        long s = (root == this) ? state : reconcileState();
+        int p = (int)(s >>> PHASE_SHIFT);
         if (phase < 0)
             return phase;
-        long s = getReconciledState();
-        int p = phaseOf(s);
-        if (p != phase)
-            return p;
-        if (unarrivedOf(s) == 0 && parent != null)
-            parent.awaitAdvanceInterruptibly(phase);
-        return interruptibleWait(phase);
+        if (p == phase) {
+            QNode node = new QNode(this, phase, true, false, 0L);
+            p = root.internalAwaitAdvance(phase, node);
+            if (node.wasInterrupted)
+                throw new InterruptedException();
+        }
+        return p;
     }
 
     /**
-     * Awaits the phase of the barrier to advance from the given phase
+     * Awaits the phase of this phaser to advance from the given phase
      * value or the given timeout to elapse, throwing {@code
      * InterruptedException} if interrupted while waiting, or
-     * returning immediately if the current phase of the barrier is
-     * not equal to the given phase value or this barrier is
-     * terminated.  It is an unenforced usage error for an
-     * unregistered party to invoke this method.
+     * returning immediately if the current phase is not equal to the
+     * given phase value or this phaser is terminated.
      *
      * @param phase an arrival phase number, or negative value if
      * terminated; this argument is normally the value returned by a
-     * previous call to {@code arrive} or its variants
+     * previous call to {@code arrive} or {@code arriveAndDeregister}.
      * @param timeout how long to wait before giving up, in units of
      *        {@code unit}
      * @param unit a {@code TimeUnit} determining how to interpret the
      *        {@code timeout} parameter
-     * @return the next arrival phase number, or a negative value
-     * if terminated or argument is negative
+     * @return the next arrival phase number, or the argument if it is
+     * negative, or the (negative) {@linkplain #getPhase() current phase}
+     * if terminated
      * @throws InterruptedException if thread interrupted while waiting
      * @throws TimeoutException if timed out while waiting
      */
     public int awaitAdvanceInterruptibly(int phase,
                                          long timeout, TimeUnit unit)
         throws InterruptedException, TimeoutException {
+        long nanos = unit.toNanos(timeout);
+        final Phaser root = this.root;
+        long s = (root == this) ? state : reconcileState();
+        int p = (int)(s >>> PHASE_SHIFT);
         if (phase < 0)
             return phase;
-        long s = getReconciledState();
-        int p = phaseOf(s);
-        if (p != phase)
-            return p;
-        if (unarrivedOf(s) == 0 && parent != null)
-            parent.awaitAdvanceInterruptibly(phase, timeout, unit);
-        return timedWait(phase, unit.toNanos(timeout));
+        if (p == phase) {
+            QNode node = new QNode(this, phase, true, true, nanos);
+            p = root.internalAwaitAdvance(phase, node);
+            if (node.wasInterrupted)
+                throw new InterruptedException();
+            else if (p == phase)
+                throw new TimeoutException();
+        }
+        return p;
     }
 
     /**
-     * Forces this barrier to enter termination state. Counts of
-     * arrived and registered parties are unaffected. If this phaser
-     * has a parent, it too is terminated. This method may be useful
-     * for coordinating recovery after one or more tasks encounter
+     * Forces this phaser to enter termination state.  Counts of
+     * registered parties are unaffected.  If this phaser is a member
+     * of a tiered set of phasers, then all of the phasers in the set
+     * are terminated.  If this phaser is already terminated, this
+     * method has no effect.  This method may be useful for
+     * coordinating recovery after one or more tasks encounter
      * unexpected exceptions.
      */
     public void forceTermination() {
-        for (;;) {
-            long s = getReconciledState();
-            int phase = phaseOf(s);
-            int parties = partiesOf(s);
-            int unarrived = unarrivedOf(s);
-            if (phase < 0 ||
-                casState(s, stateFor(-1, parties, unarrived))) {
+        // Only need to change root state
+        final Phaser root = this.root;
+        long s;
+        while ((s = root.state) >= 0) {
+            if (UNSAFE.compareAndSwapLong(root, stateOffset,
+                                          s, s | TERMINATION_BIT)) {
+                // signal all threads
                 releaseWaiters(0);
                 releaseWaiters(1);
-                if (parent != null)
-                    parent.forceTermination();
                 return;
             }
         }
@@ -719,16 +819,18 @@
     /**
      * Returns the current phase number. The maximum phase number is
      * {@code Integer.MAX_VALUE}, after which it restarts at
-     * zero. Upon termination, the phase number is negative.
+     * zero. Upon termination, the phase number is negative,
+     * in which case the prevailing phase prior to termination
+     * may be obtained via {@code getPhase() + Integer.MIN_VALUE}.
      *
      * @return the phase number, or a negative value if terminated
      */
     public final int getPhase() {
-        return phaseOf(getReconciledState());
+        return (int)(root.state >>> PHASE_SHIFT);
     }
 
     /**
-     * Returns the number of parties registered at this barrier.
+     * Returns the number of parties registered at this phaser.
      *
      * @return the number of parties
      */
@@ -738,22 +840,24 @@
 
     /**
      * Returns the number of registered parties that have arrived at
-     * the current phase of this barrier.
+     * the current phase of this phaser. If this phaser has terminated,
+     * the returned value is meaningless and arbitrary.
      *
      * @return the number of arrived parties
      */
     public int getArrivedParties() {
-        return arrivedOf(state);
+        return arrivedOf(reconcileState());
     }
 
     /**
      * Returns the number of registered parties that have not yet
-     * arrived at the current phase of this barrier.
+     * arrived at the current phase of this phaser. If this phaser has
+     * terminated, the returned value is meaningless and arbitrary.
      *
      * @return the number of unarrived parties
      */
     public int getUnarrivedParties() {
-        return unarrivedOf(state);
+        return unarrivedOf(reconcileState());
     }
 
     /**
@@ -776,52 +880,56 @@
     }
 
     /**
-     * Returns {@code true} if this barrier has been terminated.
+     * Returns {@code true} if this phaser has been terminated.
      *
-     * @return {@code true} if this barrier has been terminated
+     * @return {@code true} if this phaser has been terminated
      */
     public boolean isTerminated() {
-        return getPhase() < 0;
+        return root.state < 0L;
     }
 
     /**
      * Overridable method to perform an action upon impending phase
      * advance, and to control termination. This method is invoked
-     * upon arrival of the party tripping the barrier (when all other
+     * upon arrival of the party advancing this phaser (when all other
      * waiting parties are dormant).  If this method returns {@code
-     * true}, then, rather than advance the phase number, this barrier
-     * will be set to a final termination state, and subsequent calls
-     * to {@link #isTerminated} will return true. Any (unchecked)
-     * Exception or Error thrown by an invocation of this method is
-     * propagated to the party attempting to trip the barrier, in
-     * which case no advance occurs.
+     * true}, this phaser will be set to a final termination state
+     * upon advance, and subsequent calls to {@link #isTerminated}
+     * will return true. Any (unchecked) Exception or Error thrown by
+     * an invocation of this method is propagated to the party
+     * attempting to advance this phaser, in which case no advance
+     * occurs.
      *
      * <p>The arguments to this method provide the state of the phaser
-     * prevailing for the current transition. (When called from within
-     * an implementation of {@code onAdvance} the values returned by
-     * methods such as {@code getPhase} may or may not reliably
-     * indicate the state to which this transition applies.)
+     * prevailing for the current transition.  The effects of invoking
+     * arrival, registration, and waiting methods on this phaser from
+     * within {@code onAdvance} are unspecified and should not be
+     * relied on.
      *
-     * <p>The default version returns {@code true} when the number of
-     * registered parties is zero. Normally, overrides that arrange
-     * termination for other reasons should also preserve this
-     * property.
+     * <p>If this phaser is a member of a tiered set of phasers, then
+     * {@code onAdvance} is invoked only for its root phaser on each
+     * advance.
      *
-     * <p>You may override this method to perform an action with side
-     * effects visible to participating tasks, but it is only sensible
-     * to do so in designs where all parties register before any
-     * arrive, and all {@link #awaitAdvance} at each phase.
-     * Otherwise, you cannot ensure lack of interference from other
-     * parties during the invocation of this method. Additionally,
-     * method {@code onAdvance} may be invoked more than once per
-     * transition if registrations are intermixed with arrivals.
+     * <p>To support the most common use cases, the default
+     * implementation of this method returns {@code true} when the
+     * number of registered parties has become zero as the result of a
+     * party invoking {@code arriveAndDeregister}.  You can disable
+     * this behavior, thus enabling continuation upon future
+     * registrations, by overriding this method to always return
+     * {@code false}:
      *
-     * @param phase the phase number on entering the barrier
+     * <pre> {@code
+     * Phaser phaser = new Phaser() {
+     *   protected boolean onAdvance(int phase, int parties) { return false; }
+     * }}</pre>
+     *
+     * @param phase the current phase number on entry to this method,
+     * before this phaser is advanced
      * @param registeredParties the current number of registered parties
-     * @return {@code true} if this barrier should terminate
+     * @return {@code true} if this phaser should terminate
      */
     protected boolean onAdvance(int phase, int registeredParties) {
-        return registeredParties <= 0;
+        return registeredParties == 0;
     }
 
     /**
@@ -831,17 +939,138 @@
      * followed by the number of registered parties, and {@code
      * "arrived = "} followed by the number of arrived parties.
      *
-     * @return a string identifying this barrier, as well as its state
+     * @return a string identifying this phaser, as well as its state
      */
     public String toString() {
-        long s = getReconciledState();
+        return stateToString(reconcileState());
+    }
+
+    /**
+     * Implementation of toString and string-based error messages
+     */
+    private String stateToString(long s) {
         return super.toString() +
             "[phase = " + phaseOf(s) +
             " parties = " + partiesOf(s) +
             " arrived = " + arrivedOf(s) + "]";
     }
 
-    // methods for waiting
+    // Waiting mechanics
+
+    /**
+     * Removes and signals threads from queue for phase.
+     */
+    private void releaseWaiters(int phase) {
+        QNode q;   // first element of queue
+        Thread t;  // its thread
+        AtomicReference<QNode> head = (phase & 1) == 0 ? evenQ : oddQ;
+        while ((q = head.get()) != null &&
+               q.phase != (int)(root.state >>> PHASE_SHIFT)) {
+            if (head.compareAndSet(q, q.next) &&
+                (t = q.thread) != null) {
+                q.thread = null;
+                LockSupport.unpark(t);
+            }
+        }
+    }
+
+    /**
+     * Variant of releaseWaiters that additionally tries to remove any
+     * nodes no longer waiting for advance due to timeout or
+     * interrupt. Currently, nodes are removed only if they are at
+     * head of queue, which suffices to reduce memory footprint in
+     * most usages.
+     *
+     * @return current phase on exit
+     */
+    private int abortWait(int phase) {
+        AtomicReference<QNode> head = (phase & 1) == 0 ? evenQ : oddQ;
+        for (;;) {
+            Thread t;
+            QNode q = head.get();
+            int p = (int)(root.state >>> PHASE_SHIFT);
+            if (q == null || ((t = q.thread) != null && q.phase == p))
+                return p;
+            if (head.compareAndSet(q, q.next) && t != null) {
+                q.thread = null;
+                LockSupport.unpark(t);
+            }
+        }
+    }
+
+    /** The number of CPUs, for spin control */
+    private static final int NCPU = Runtime.getRuntime().availableProcessors();
+
+    /**
+     * The number of times to spin before blocking while waiting for
+     * advance, per arrival while waiting. On multiprocessors, fully
+     * blocking and waking up a large number of threads all at once is
+     * usually a very slow process, so we use rechargeable spins to
+     * avoid it when threads regularly arrive: When a thread in
+     * internalAwaitAdvance notices another arrival before blocking,
+     * and there appear to be enough CPUs available, it spins
+     * SPINS_PER_ARRIVAL more times before blocking. The value trades
+     * off good-citizenship vs big unnecessary slowdowns.
+     */
+    static final int SPINS_PER_ARRIVAL = (NCPU < 2) ? 1 : 1 << 8;
+
+    /**
+     * Possibly blocks and waits for phase to advance unless aborted.
+     * Call only from root node.
+     *
+     * @param phase current phase
+     * @param node if non-null, the wait node to track interrupt and timeout;
+     * if null, denotes noninterruptible wait
+     * @return current phase
+     */
+    private int internalAwaitAdvance(int phase, QNode node) {
+        releaseWaiters(phase-1);          // ensure old queue clean
+        boolean queued = false;           // true when node is enqueued
+        int lastUnarrived = 0;            // to increase spins upon change
+        int spins = SPINS_PER_ARRIVAL;
+        long s;
+        int p;
+        while ((p = (int)((s = state) >>> PHASE_SHIFT)) == phase) {
+            if (node == null) {           // spinning in noninterruptible mode
+                int unarrived = (int)s & UNARRIVED_MASK;
+                if (unarrived != lastUnarrived &&
+                    (lastUnarrived = unarrived) < NCPU)
+                    spins += SPINS_PER_ARRIVAL;
+                boolean interrupted = Thread.interrupted();
+                if (interrupted || --spins < 0) { // need node to record intr
+                    node = new QNode(this, phase, false, false, 0L);
+                    node.wasInterrupted = interrupted;
+                }
+            }
+            else if (node.isReleasable()) // done or aborted
+                break;
+            else if (!queued) {           // push onto queue
+                AtomicReference<QNode> head = (phase & 1) == 0 ? evenQ : oddQ;
+                QNode q = node.next = head.get();
+                if ((q == null || q.phase == phase) &&
+                    (int)(state >>> PHASE_SHIFT) == phase) // avoid stale enq
+                    queued = head.compareAndSet(q, node);
+            }
+            else {
+                try {
+                    ForkJoinPool.managedBlock(node);
+                } catch (InterruptedException ie) {
+                    node.wasInterrupted = true;
+                }
+            }
+        }
+
+        if (node != null) {
+            if (node.thread != null)
+                node.thread = null;       // avoid need for unpark()
+            if (node.wasInterrupted && !node.interruptible)
+                Thread.currentThread().interrupt();
+            if (p == phase && (p = (int)(state >>> PHASE_SHIFT)) == phase)
+                return abortWait(phase); // possibly clean up on abort
+        }
+        releaseWaiters(phase);
+        return p;
+    }
 
     /**
      * Wait nodes for Treiber stack representing wait queue
@@ -849,174 +1078,61 @@
     static final class QNode implements ForkJoinPool.ManagedBlocker {
         final Phaser phaser;
         final int phase;
-        final long startTime;
-        final long nanos;
+        final boolean interruptible;
         final boolean timed;
-        final boolean interruptible;
-        volatile boolean wasInterrupted = false;
+        boolean wasInterrupted;
+        long nanos;
+        long lastTime;
         volatile Thread thread; // nulled to cancel wait
         QNode next;
+
         QNode(Phaser phaser, int phase, boolean interruptible,
-              boolean timed, long startTime, long nanos) {
+              boolean timed, long nanos) {
             this.phaser = phaser;
             this.phase = phase;
+            this.interruptible = interruptible;
+            this.nanos = nanos;
             this.timed = timed;
-            this.interruptible = interruptible;
-            this.startTime = startTime;
-            this.nanos = nanos;
+            this.lastTime = timed ? System.nanoTime() : 0L;
             thread = Thread.currentThread();
         }
+
         public boolean isReleasable() {
-            return (thread == null ||
-                    phaser.getPhase() != phase ||
-                    (interruptible && wasInterrupted) ||
-                    (timed && (nanos - (System.nanoTime() - startTime)) <= 0));
+            if (thread == null)
+                return true;
+            if (phaser.getPhase() != phase) {
+                thread = null;
+                return true;
+            }
+            if (Thread.interrupted())
+                wasInterrupted = true;
+            if (wasInterrupted && interruptible) {
+                thread = null;
+                return true;
+            }
+            if (timed) {
+                if (nanos > 0L) {
+                    long now = System.nanoTime();
+                    nanos -= now - lastTime;
+                    lastTime = now;
+                }
+                if (nanos <= 0L) {
+                    thread = null;
+                    return true;
+                }
+            }
+            return false;
         }
+
         public boolean block() {
-            if (Thread.interrupted()) {
-                wasInterrupted = true;
-                if (interruptible)
-                    return true;
-            }
-            if (!timed)
+            if (isReleasable())
+                return true;
+            else if (!timed)
                 LockSupport.park(this);
-            else {
-                long waitTime = nanos - (System.nanoTime() - startTime);
-                if (waitTime <= 0)
-                    return true;
-                LockSupport.parkNanos(this, waitTime);
-            }
+            else if (nanos > 0)
+                LockSupport.parkNanos(this, nanos);
             return isReleasable();
         }
-        void signal() {
-            Thread t = thread;
-            if (t != null) {
-                thread = null;
-                LockSupport.unpark(t);
-            }
-        }
-        boolean doWait() {
-            if (thread != null) {
-                try {
-                    ForkJoinPool.managedBlock(this);
-                } catch (InterruptedException ie) {
-                }
-            }
-            return wasInterrupted;
-        }
-
-    }
-
-    /**
-     * Removes and signals waiting threads from wait queue.
-     */
-    private void releaseWaiters(int phase) {
-        AtomicReference<QNode> head = queueFor(phase);
-        QNode q;
-        while ((q = head.get()) != null) {
-            if (head.compareAndSet(q, q.next))
-                q.signal();
-        }
-    }
-
-    /**
-     * Tries to enqueue given node in the appropriate wait queue.
-     *
-     * @return true if successful
-     */
-    private boolean tryEnqueue(QNode node) {
-        AtomicReference<QNode> head = queueFor(node.phase);
-        return head.compareAndSet(node.next = head.get(), node);
-    }
-
-    /**
-     * Enqueues node and waits unless aborted or signalled.
-     *
-     * @return current phase
-     */
-    private int untimedWait(int phase) {
-        QNode node = null;
-        boolean queued = false;
-        boolean interrupted = false;
-        int p;
-        while ((p = getPhase()) == phase) {
-            if (Thread.interrupted())
-                interrupted = true;
-            else if (node == null)
-                node = new QNode(this, phase, false, false, 0, 0);
-            else if (!queued)
-                queued = tryEnqueue(node);
-            else
-                interrupted = node.doWait();
-        }
-        if (node != null)
-            node.thread = null;
-        releaseWaiters(phase);
-        if (interrupted)
-            Thread.currentThread().interrupt();
-        return p;
-    }
-
-    /**
-     * Interruptible version
-     * @return current phase
-     */
-    private int interruptibleWait(int phase) throws InterruptedException {
-        QNode node = null;
-        boolean queued = false;
-        boolean interrupted = false;
-        int p;
-        while ((p = getPhase()) == phase && !interrupted) {
-            if (Thread.interrupted())
-                interrupted = true;
-            else if (node == null)
-                node = new QNode(this, phase, true, false, 0, 0);
-            else if (!queued)
-                queued = tryEnqueue(node);
-            else
-                interrupted = node.doWait();
-        }
-        if (node != null)
-            node.thread = null;
-        if (p != phase || (p = getPhase()) != phase)
-            releaseWaiters(phase);
-        if (interrupted)
-            throw new InterruptedException();
-        return p;
-    }
-
-    /**
-     * Timeout version.
-     * @return current phase
-     */
-    private int timedWait(int phase, long nanos)
-        throws InterruptedException, TimeoutException {
-        long startTime = System.nanoTime();
-        QNode node = null;
-        boolean queued = false;
-        boolean interrupted = false;
-        int p;
-        while ((p = getPhase()) == phase && !interrupted) {
-            if (Thread.interrupted())
-                interrupted = true;
-            else if (nanos - (System.nanoTime() - startTime) <= 0)
-                break;
-            else if (node == null)
-                node = new QNode(this, phase, true, true, startTime, nanos);
-            else if (!queued)
-                queued = tryEnqueue(node);
-            else
-                interrupted = node.doWait();
-        }
-        if (node != null)
-            node.thread = nu