changeset 1788:ced0a1a7ec80

Merge
author bpatel
date Thu, 08 Jan 2009 16:34:58 -0800
parents 1aa079321cd2 88f03aba5cf9
children 7ac8c0815000
files jdk/src/share/classes/sun/nio/cs/IBM437.java jdk/src/share/classes/sun/nio/cs/IBM737.java jdk/src/share/classes/sun/nio/cs/IBM775.java jdk/src/share/classes/sun/nio/cs/IBM850.java jdk/src/share/classes/sun/nio/cs/IBM852.java jdk/src/share/classes/sun/nio/cs/IBM855.java jdk/src/share/classes/sun/nio/cs/IBM857.java jdk/src/share/classes/sun/nio/cs/IBM858.java jdk/src/share/classes/sun/nio/cs/IBM862.java jdk/src/share/classes/sun/nio/cs/IBM866.java jdk/src/share/classes/sun/nio/cs/IBM874.java jdk/src/share/classes/sun/nio/cs/ISO_8859_13.java jdk/src/share/classes/sun/nio/cs/ISO_8859_15.java jdk/src/share/classes/sun/nio/cs/ISO_8859_2.java jdk/src/share/classes/sun/nio/cs/ISO_8859_4.java jdk/src/share/classes/sun/nio/cs/ISO_8859_5.java jdk/src/share/classes/sun/nio/cs/ISO_8859_7.java jdk/src/share/classes/sun/nio/cs/ISO_8859_9.java jdk/src/share/classes/sun/nio/cs/KOI8_R.java jdk/src/share/classes/sun/nio/cs/KOI8_U.java jdk/src/share/classes/sun/nio/cs/MS1250.java jdk/src/share/classes/sun/nio/cs/MS1251.java jdk/src/share/classes/sun/nio/cs/MS1252.java jdk/src/share/classes/sun/nio/cs/MS1253.java jdk/src/share/classes/sun/nio/cs/MS1254.java jdk/src/share/classes/sun/nio/cs/MS1257.java jdk/src/share/classes/sun/nio/cs/ext/IBM037.java jdk/src/share/classes/sun/nio/cs/ext/IBM1006.java jdk/src/share/classes/sun/nio/cs/ext/IBM1025.java jdk/src/share/classes/sun/nio/cs/ext/IBM1026.java jdk/src/share/classes/sun/nio/cs/ext/IBM1046.java jdk/src/share/classes/sun/nio/cs/ext/IBM1047.java jdk/src/share/classes/sun/nio/cs/ext/IBM1097.java jdk/src/share/classes/sun/nio/cs/ext/IBM1098.java jdk/src/share/classes/sun/nio/cs/ext/IBM1112.java jdk/src/share/classes/sun/nio/cs/ext/IBM1122.java jdk/src/share/classes/sun/nio/cs/ext/IBM1123.java jdk/src/share/classes/sun/nio/cs/ext/IBM1124.java jdk/src/share/classes/sun/nio/cs/ext/IBM1140.java jdk/src/share/classes/sun/nio/cs/ext/IBM1141.java jdk/src/share/classes/sun/nio/cs/ext/IBM1142.java jdk/src/share/classes/sun/nio/cs/ext/IBM1143.java jdk/src/share/classes/sun/nio/cs/ext/IBM1144.java jdk/src/share/classes/sun/nio/cs/ext/IBM1145.java jdk/src/share/classes/sun/nio/cs/ext/IBM1146.java jdk/src/share/classes/sun/nio/cs/ext/IBM1147.java jdk/src/share/classes/sun/nio/cs/ext/IBM1148.java jdk/src/share/classes/sun/nio/cs/ext/IBM1149.java jdk/src/share/classes/sun/nio/cs/ext/IBM273.java jdk/src/share/classes/sun/nio/cs/ext/IBM277.java jdk/src/share/classes/sun/nio/cs/ext/IBM278.java jdk/src/share/classes/sun/nio/cs/ext/IBM280.java jdk/src/share/classes/sun/nio/cs/ext/IBM284.java jdk/src/share/classes/sun/nio/cs/ext/IBM285.java jdk/src/share/classes/sun/nio/cs/ext/IBM297.java jdk/src/share/classes/sun/nio/cs/ext/IBM420.java jdk/src/share/classes/sun/nio/cs/ext/IBM424.java jdk/src/share/classes/sun/nio/cs/ext/IBM500.java jdk/src/share/classes/sun/nio/cs/ext/IBM838.java jdk/src/share/classes/sun/nio/cs/ext/IBM856.java jdk/src/share/classes/sun/nio/cs/ext/IBM860.java jdk/src/share/classes/sun/nio/cs/ext/IBM861.java jdk/src/share/classes/sun/nio/cs/ext/IBM863.java jdk/src/share/classes/sun/nio/cs/ext/IBM864.java jdk/src/share/classes/sun/nio/cs/ext/IBM865.java jdk/src/share/classes/sun/nio/cs/ext/IBM868.java jdk/src/share/classes/sun/nio/cs/ext/IBM869.java jdk/src/share/classes/sun/nio/cs/ext/IBM870.java jdk/src/share/classes/sun/nio/cs/ext/IBM871.java jdk/src/share/classes/sun/nio/cs/ext/IBM875.java jdk/src/share/classes/sun/nio/cs/ext/IBM918.java jdk/src/share/classes/sun/nio/cs/ext/IBM921.java jdk/src/share/classes/sun/nio/cs/ext/IBM922.java jdk/src/share/classes/sun/nio/cs/ext/ISO_8859_11.java jdk/src/share/classes/sun/nio/cs/ext/ISO_8859_3.java jdk/src/share/classes/sun/nio/cs/ext/ISO_8859_6.java jdk/src/share/classes/sun/nio/cs/ext/ISO_8859_8.java jdk/src/share/classes/sun/nio/cs/ext/MS1255.java jdk/src/share/classes/sun/nio/cs/ext/MS1256.java jdk/src/share/classes/sun/nio/cs/ext/MS1258.java jdk/src/share/classes/sun/nio/cs/ext/MS874.java jdk/src/share/classes/sun/nio/cs/ext/MacArabic.java jdk/src/share/classes/sun/nio/cs/ext/MacCentralEurope.java jdk/src/share/classes/sun/nio/cs/ext/MacCroatian.java jdk/src/share/classes/sun/nio/cs/ext/MacCyrillic.java jdk/src/share/classes/sun/nio/cs/ext/MacDingbat.java jdk/src/share/classes/sun/nio/cs/ext/MacGreek.java jdk/src/share/classes/sun/nio/cs/ext/MacHebrew.java jdk/src/share/classes/sun/nio/cs/ext/MacIceland.java jdk/src/share/classes/sun/nio/cs/ext/MacRoman.java jdk/src/share/classes/sun/nio/cs/ext/MacRomania.java jdk/src/share/classes/sun/nio/cs/ext/MacSymbol.java jdk/src/share/classes/sun/nio/cs/ext/MacThai.java jdk/src/share/classes/sun/nio/cs/ext/MacTurkish.java jdk/src/share/classes/sun/nio/cs/ext/MacUkraine.java jdk/src/share/classes/sun/nio/cs/ext/TIS_620.java langtools/test/com/sun/javadoc/AuthorDD/AuthorDD.java
diffstat 895 files changed, 35734 insertions(+), 29824 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Thu Jan 08 16:26:59 2009 -0800
+++ b/.hgtags	Thu Jan 08 16:34:58 2009 -0800
@@ -15,3 +15,5 @@
 a2879b2837f5a4c87e9542efe69ef138194af8ff jdk7-b38
 126f365cec6c3c2c72de934fa1c64b5f082b55b5 jdk7-b39
 3c53424bbe3bb77e01b468b4b0140deec33e11fc jdk7-b40
+3cb2a607c347934f8e7e86f840a094c28b08d9ea jdk7-b41
+caf58ffa084568990cbb3441f9ae188e36b31770 jdk7-b42
--- a/.hgtags-top-repo	Thu Jan 08 16:26:59 2009 -0800
+++ b/.hgtags-top-repo	Thu Jan 08 16:34:58 2009 -0800
@@ -15,3 +15,5 @@
 cc47a76899ed33a2c513cb688348244c9b5a1288 jdk7-b38
 ab523b49de1fc73fefe6855ce1e0349bdbd7af29 jdk7-b39
 44be42de6693063fb191989bf0e188de2fa51e7c jdk7-b40
+541bdc5ad32fc33255944d0a044ad992f3d915e8 jdk7-b41
+94052b87287303527125026fe4b2698cf867ea83 jdk7-b42
--- a/README-builds.html	Thu Jan 08 16:26:59 2009 -0800
+++ b/README-builds.html	Thu Jan 08 16:34:58 2009 -0800
@@ -839,7 +839,7 @@
             <blockquote>
                 All OpenJDK builds require access to least Ant 1.6.5.
                 The Ant tool is available from the 
-                <a href="http://ant.apache.org/antlibs/bindownload.cgi" target="_blank">
+                <a href="http://ant.apache.org" target="_blank">
                 Ant download site</a>.
                 You should always make sure <tt>ant</tt> is in your PATH, and
                 on Windows you may also need to set 
--- a/corba/.hgtags	Thu Jan 08 16:26:59 2009 -0800
+++ b/corba/.hgtags	Thu Jan 08 16:34:58 2009 -0800
@@ -15,3 +15,5 @@
 08be802754b0296c91a7713b6d85a015dbcd5349 jdk7-b38
 55078b6661e286e90387d1d9950bd865f5cc436e jdk7-b39
 184e21992f47a8d730df1adc5b21a108f3125489 jdk7-b40
+c90eeda9594ed2983403e2049aed8d503126c62e jdk7-b41
+ccd6a16502e0650d91d85c4b86be05cbcd461a87 jdk7-b42
--- a/corba/make/common/Defs-windows.gmk	Thu Jan 08 16:26:59 2009 -0800
+++ b/corba/make/common/Defs-windows.gmk	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 #
-# Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 1999-2008 Sun Microsystems, Inc.  All Rights Reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
--- a/corba/make/common/shared/Compiler-msvc.gmk	Thu Jan 08 16:26:59 2009 -0800
+++ b/corba/make/common/shared/Compiler-msvc.gmk	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 #
-# Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 2005-2008 Sun Microsystems, Inc.  All Rights Reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
--- a/hotspot/.hgtags	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/.hgtags	Thu Jan 08 16:34:58 2009 -0800
@@ -15,3 +15,5 @@
 d9bc824aa078573829bb66572af847e26e1bd12e jdk7-b38
 49ca90d77f34571b0757ebfcb8a7848ef2696b88 jdk7-b39
 81a0cbe3b28460ce836109934ece03db7afaf9cc jdk7-b40
+f9d938ede1960d18cb7cf23c645b026519c1a678 jdk7-b41
+ad8c8ca4ab0f4c86e74c061958f44a8f4a930f2c jdk7-b42
--- a/hotspot/make/hotspot_version	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/make/hotspot_version	Thu Jan 08 16:34:58 2009 -0800
@@ -35,7 +35,7 @@
 
 HS_MAJOR_VER=14
 HS_MINOR_VER=0
-HS_BUILD_NUMBER=08
+HS_BUILD_NUMBER=10
 
 JDK_MAJOR_VER=1
 JDK_MINOR_VER=7
--- a/hotspot/make/linux/adlc_updater	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/make/linux/adlc_updater	Thu Jan 08 16:34:58 2009 -0800
@@ -7,5 +7,13 @@
 #
 # adlc-updater <file> <source-dir> <target-dir>
 #
-[ -f $3/$1 ] && cmp -s $2/$1 $3/$1 || \
-( [ -f $3/$1 ]; echo Updating $3/$1 ; touch $2/made-change ; mv $2/$1 $3/$1 )
+fix_lines() {
+  # repair bare #line directives in $1 to refer to $2
+  awk < $1 > $1+ '
+    /^#line 999999$/ {print "#line " (NR+1) " \"" F2 "\""; next}
+    {print}
+  ' F2=$2
+  mv $1+ $1
+}
+[ -f $3/$1 ] && (fix_lines $2/$1 $3/$1; cmp -s $2/$1 $3/$1) || \
+( [ -f $3/$1 ] && echo Updating $3/$1 ; touch $2/made-change ; mv $2/$1 $3/$1 )
--- a/hotspot/make/linux/makefiles/adlc.make	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/make/linux/makefiles/adlc.make	Thu Jan 08 16:34:58 2009 -0800
@@ -54,9 +54,11 @@
 Src_Dirs_I = ${Src_Dirs} $(GENERATED)
 INCLUDES += $(Src_Dirs_I:%=-I%)
 
+# set flags for adlc compilation
+CPPFLAGS = $(SYSDEFS) $(INCLUDES)
+
 # Force assertions on.
-SYSDEFS += -DASSERT
-CPPFLAGS = $(SYSDEFS) $(INCLUDES)
+CPPFLAGS += -DASSERT
 
 # CFLAGS_WARN holds compiler options to suppress/enable warnings.
 # Suppress warnings (for now)
@@ -125,7 +127,15 @@
 # Note that product files are updated via "mv", which is atomic.
 TEMPDIR := $(OUTDIR)/mktmp$(shell echo $$$$)
 
-ADLCFLAGS = -q -T
+# Pass -D flags into ADLC.
+ADLCFLAGS += $(SYSDEFS)
+
+# Note "+="; it is a hook so flags.make can add more flags, like -g or -DFOO.
+ADLCFLAGS += -q -T
+
+# Normally, debugging is done directly on the ad_<arch>*.cpp files.
+# But -g will put #line directives in those files pointing back to <arch>.ad.
+#ADLCFLAGS += -g
 
 ifdef LP64
 ADLCFLAGS += -D_LP64
@@ -140,6 +150,8 @@
 #
 ADLC_UPDATER_DIRECTORY = $(GAMMADIR)/make/$(OS)
 ADLC_UPDATER = adlc_updater
+$(ADLC_UPDATER): $(ADLC_UPDATER_DIRECTORY)/$(ADLC_UPDATER)
+	$(QUIETLY) cp $< $@; chmod +x $@
 
 # This action refreshes all generated adlc files simultaneously.
 # The way it works is this:
@@ -149,9 +161,8 @@
 # 4) call $(ADLC_UPDATER) on each generated adlc file. It will selectively update changed or missing files.
 # 5) If we actually updated any files, echo a notice.
 #
-refresh_adfiles: $(EXEC) $(SOURCE.AD)
+refresh_adfiles: $(EXEC) $(SOURCE.AD) $(ADLC_UPDATER)
 	@rm -rf $(TEMPDIR); mkdir $(TEMPDIR)
-	$(QUIETLY) [ -f $(ADLC_UPDATER) ] || ( cp $(ADLC_UPDATER_DIRECTORY)/$(ADLC_UPDATER) . ; chmod +x $(ADLC_UPDATER) )
 	$(QUIETLY) $(EXEC) $(ADLCFLAGS) $(SOURCE.AD) \
  -c$(TEMPDIR)/ad_$(Platform_arch_model).cpp -h$(TEMPDIR)/ad_$(Platform_arch_model).hpp -a$(TEMPDIR)/dfa_$(Platform_arch_model).cpp -v$(TEMPDIR)/adGlobals_$(Platform_arch_model).hpp \
 	    || { rm -rf $(TEMPDIR); exit 1; }
@@ -174,7 +185,15 @@
 # #########################################################################
 
 $(SOURCE.AD): $(SOURCES.AD)
-	$(QUIETLY) cat $(SOURCES.AD) > $(SOURCE.AD)
+	$(QUIETLY) $(PROCESS_AD_FILES) $(SOURCES.AD) > $(SOURCE.AD)
+
+#PROCESS_AD_FILES = cat
+# Pass through #line directives, in case user enables -g option above:
+PROCESS_AD_FILES = awk '{ \
+    if (CUR_FN != FILENAME) { CUR_FN=FILENAME; NR_BASE=NR-1; need_lineno=1 } \
+    if (need_lineno && $$0 !~ /\/\//) \
+      { print "\n\n\#line " (NR-NR_BASE) " \"" FILENAME "\""; need_lineno=0 }; \
+    print }'
 
 $(OUTDIR)/%.o: %.cpp
 	@echo Compiling $<
--- a/hotspot/make/solaris/adlc_updater	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/make/solaris/adlc_updater	Thu Jan 08 16:34:58 2009 -0800
@@ -7,5 +7,13 @@
 #
 # adlc-updater <file> <source-dir> <target-dir>
 #
-[ -f $3/$1 ] && cmp -s $2/$1 $3/$1 || \
-( [ -f $3/$1 ]; echo Updating $3/$1 ; touch $2/made-change ; mv $2/$1 $3/$1 )
+fix_lines() {
+  # repair bare #line directives in $1 to refer to $2
+  awk < $1 > $1+ '
+    /^#line 999999$/ {print "#line " (NR+1) " \"" F2 "\""; next}
+    {print}
+  ' F2=$2
+  mv $1+ $1
+}
+[ -f $3/$1 ] && (fix_lines $2/$1 $3/$1; cmp -s $2/$1 $3/$1) || \
+( [ -f $3/$1 ] && echo Updating $3/$1 ; touch $2/made-change ; mv $2/$1 $3/$1 )
--- a/hotspot/make/solaris/makefiles/adlc.make	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/make/solaris/makefiles/adlc.make	Thu Jan 08 16:34:58 2009 -0800
@@ -54,9 +54,11 @@
 Src_Dirs_I = ${Src_Dirs} $(GENERATED)
 INCLUDES += $(Src_Dirs_I:%=-I%)
 
+# set flags for adlc compilation
+CPPFLAGS = $(SYSDEFS) $(INCLUDES)
+
 # Force assertions on.
-SYSDEFS += -DASSERT
-CPPFLAGS = $(SYSDEFS) $(INCLUDES)
+CPPFLAGS += -DASSERT
 
 ifndef USE_GCC
   # We need libCstd.so for adlc 
@@ -141,7 +143,15 @@
 # Note that product files are updated via "mv", which is atomic.
 TEMPDIR := $(OUTDIR)/mktmp$(shell echo $$$$)
 
-ADLCFLAGS = -q -T
+# Pass -D flags into ADLC.
+ADLCFLAGS += $(SYSDEFS)
+
+# Note "+="; it is a hook so flags.make can add more flags, like -g or -DFOO.
+ADLCFLAGS += -q -T
+
+# Normally, debugging is done directly on the ad_<arch>*.cpp files.
+# But -g will put #line directives in those files pointing back to <arch>.ad.
+#ADLCFLAGS += -g
 
 ifdef LP64
 ADLCFLAGS += -D_LP64
@@ -156,6 +166,8 @@
 #
 ADLC_UPDATER_DIRECTORY = $(GAMMADIR)/make/$(OS)
 ADLC_UPDATER = adlc_updater
+$(ADLC_UPDATER): $(ADLC_UPDATER_DIRECTORY)/$(ADLC_UPDATER)
+	$(QUIETLY) cp $< $@; chmod +x $@
 
 # This action refreshes all generated adlc files simultaneously.
 # The way it works is this:
@@ -165,9 +177,8 @@
 # 4) call $(ADLC_UPDATER) on each generated adlc file. It will selectively update changed or missing files.
 # 5) If we actually updated any files, echo a notice.
 #
-refresh_adfiles: $(EXEC) $(SOURCE.AD)
+refresh_adfiles: $(EXEC) $(SOURCE.AD) $(ADLC_UPDATER)
 	@rm -rf $(TEMPDIR); mkdir $(TEMPDIR)
-	$(QUIETLY) [ -f $(ADLC_UPDATER) ] || ( cp $(ADLC_UPDATER_DIRECTORY)/$(ADLC_UPDATER) . ; chmod +x $(ADLC_UPDATER) )
 	$(QUIETLY) $(EXEC) $(ADLCFLAGS) $(SOURCE.AD) \
  -c$(TEMPDIR)/ad_$(Platform_arch_model).cpp -h$(TEMPDIR)/ad_$(Platform_arch_model).hpp -a$(TEMPDIR)/dfa_$(Platform_arch_model).cpp -v$(TEMPDIR)/adGlobals_$(Platform_arch_model).hpp \
 	    || { rm -rf $(TEMPDIR); exit 1; }
@@ -190,7 +201,15 @@
 # #########################################################################
 
 $(SOURCE.AD): $(SOURCES.AD)
-	$(QUIETLY) cat $(SOURCES.AD) > $(SOURCE.AD)
+	$(QUIETLY) $(PROCESS_AD_FILES) $(SOURCES.AD) > $(SOURCE.AD)
+
+#PROCESS_AD_FILES = cat
+# Pass through #line directives, in case user enables -g option above:
+PROCESS_AD_FILES = awk '{ \
+    if (CUR_FN != FILENAME) { CUR_FN=FILENAME; NR_BASE=NR-1; need_lineno=1 } \
+    if (need_lineno && $$0 !~ /\/\//) \
+      { print "\n\n\#line " (NR-NR_BASE) " \"" FILENAME "\""; need_lineno=0 }; \
+    print }'
 
 $(OUTDIR)/%.o: %.cpp
 	@echo Compiling $<
--- a/hotspot/make/windows/build.make	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/make/windows/build.make	Thu Jan 08 16:34:58 2009 -0800
@@ -200,29 +200,6 @@
 checkSA::
 	@echo     Not building SA:  ARCH = ia64
 
-!elseif exist("$(MSVCDIR)\PlatformSDK\Include\dbgeng.h")
-# These don't have to be set because the default
-# setting of INCLUDE and LIB already contain the needed dirs.
-SA_INCLUDE = 
-SA_LIB = 
-
-!elseif exist("$(SYSTEMROOT)\..\Program Files\Microsoft SDK\include\dbgeng.h")
-# These don't have to be set because the default
-# setting of INCLUDE and LIB already contain the needed dirs.
-SA_INCLUDE =
-SA_LIB = 
-
-!else
-checkSA::
-	@echo .
-	@echo ERROR:  Can't build SA because dbgeng.h does not exist here:
-	@echo     $(MSVCDIR)\PlatformSDK\Include\dbgeng.h
-	@echo nor here:
-	@echo     $(SYSTEMROOT)\..\Program Files\Microsoft SDK\include\dbgeng.h
-	@echo You must use Vis. Studio .Net 2003 on Win 32, and you must
-	@echo have the Microsoft SDK installed on Win amd64.
-	@echo You can disable building of SA by specifying BUILD_WIN_SA = 0
-	@echo . && false
 !endif  # ! "$(BUILD_WIN_SA)" != "1"
 
 #########################################################################
--- a/hotspot/make/windows/makefiles/defs.make	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/make/windows/makefiles/defs.make	Thu Jan 08 16:34:58 2009 -0800
@@ -119,7 +119,7 @@
 # we want to release it.  If we build it here,
 # the SDK makefiles will copy it over and put it into
 # the created image.
-BUILD_WIN_SA = 0
+BUILD_WIN_SA = 1
 ifneq ($(ALT_BUILD_WIN_SA),)
   BUILD_WIN_SA = $(ALT_BUILD_WIN_SA)
 endif
--- a/hotspot/make/windows/makefiles/sa.make	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/make/windows/makefiles/sa.make	Thu Jan 08 16:34:58 2009 -0800
@@ -49,6 +49,9 @@
 
 default::  $(GENERATED)\sa-jdi.jar
 
+# Remove the space between $(SA_BUILD_VERSION_PROP) and > below as it adds a white space
+# at the end of SA version string and causes a version mismatch with the target VM version.
+
 $(GENERATED)\sa-jdi.jar: $(AGENT_FILES1:/=\) $(AGENT_FILES2:/=\)
 	@if not exist $(SA_CLASSDIR) mkdir $(SA_CLASSDIR)
 	@echo ...Building sa-jdi.jar
@@ -56,15 +59,15 @@
 	@$(COMPILE_JAVAC) -source 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -g -d $(SA_CLASSDIR) $(AGENT_FILES1:/=\)
 	@$(COMPILE_JAVAC) -source 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -g -d $(SA_CLASSDIR) $(AGENT_FILES2:/=\)
 	$(COMPILE_RMIC) -classpath $(SA_CLASSDIR) -d $(SA_CLASSDIR) sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer
-	$(QUIETLY) echo $(SA_BUILD_VERSION_PROP) > $(SA_PROPERTIES)
-	$(RUN_JAR) cf $@ -C saclasses . 
-	$(RUN_JAR) uf $@ -C $(AGENT_SRC_DIR:/=\) META-INF\services\com.sun.jdi.connect.Connector 
+	$(QUIETLY) echo $(SA_BUILD_VERSION_PROP)> $(SA_PROPERTIES)
 	$(QUIETLY) rm -f $(SA_CLASSDIR)/sun/jvm/hotspot/utilities/soql/sa.js
 	$(QUIETLY) cp $(AGENT_SRC_DIR)/sun/jvm/hotspot/utilities/soql/sa.js $(SA_CLASSDIR)/sun/jvm/hotspot/utilities/soql
-	$(QUIETLY) mkdir -p $(SA_CLASSDIR)/sun/jvm/hotspot/ui/resources
-	$(QUIETLY) rm -f $(SA_CLASSDIR)/sun/jvm/hotspot/ui/resources/*
-	$(QUIETLY) cp $(AGENT_SRC_DIR)/sun/jvm/hotspot/ui/resources/*.png $(SA_CLASSDIR)/sun/jvm/hotspot/ui/resources/
-	$(QUIETLY) cp -r $(AGENT_SRC_DIR)/images/* $(SA_CLASSDIR)/
+	$(QUIETLY) rm -rf $(SA_CLASSDIR)/sun/jvm/hotspot/ui/resources
+	$(QUIETLY) mkdir $(SA_CLASSDIR)\sun\jvm\hotspot\ui\resources
+	$(QUIETLY) cp $(AGENT_SRC_DIR)/sun/jvm/hotspot/ui/resources/*.png $(SA_CLASSDIR)/sun/jvm/hotspot/ui/resources
+	$(QUIETLY) cp -r $(AGENT_SRC_DIR)/images/* $(SA_CLASSDIR)
+	$(RUN_JAR) cf $@ -C saclasses .
+	$(RUN_JAR) uf $@ -C $(AGENT_SRC_DIR:/=\) META-INF\services\com.sun.jdi.connect.Connector
 	$(RUN_JAVAH) -classpath $(SA_CLASSDIR) -jni sun.jvm.hotspot.debugger.windbg.WindbgDebuggerLocal
 	$(RUN_JAVAH) -classpath $(SA_CLASSDIR) -jni sun.jvm.hotspot.debugger.x86.X86ThreadContext 
 	$(RUN_JAVAH) -classpath $(SA_CLASSDIR) -jni sun.jvm.hotspot.debugger.ia64.IA64ThreadContext 
@@ -93,7 +96,7 @@
 SA_CFLAGS = /nologo $(MS_RUNTIME_OPTION) /W3 /Gm $(GX_OPTION) /ZI /Od /D "WIN32" /D "_WINDOWS" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
 !endif
 !if "$(MT)" != ""
-    SA_LINK_FLAGS = /manifest $(SA_LINK_FLAGS)
+SA_LINK_FLAGS = /manifest $(SA_LINK_FLAGS)
 !endif
 SASRCFILE = $(AGENT_DIR)/src/os/win32/windbg/sawindbg.cpp
 SA_LFLAGS = $(SA_LINK_FLAGS) /nologo /subsystem:console /map /debug /machine:$(MACHINE)
--- a/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -2085,7 +2085,7 @@
     } else {
       if (has_tos) {
       // save object pointer before call_VM() clobbers it
-        __ mov(Otos_i, Lscratch);
+        __ push_ptr(Otos_i);  // put object on tos where GC wants it.
       } else {
         // Load top of stack (do not pop the value off the stack);
         __ ld_ptr(Lesp, Interpreter::expr_offset_in_bytes(0), Otos_i);
@@ -2097,7 +2097,7 @@
     __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::post_field_access),
                Otos_i, Rcache);
     if (!is_static && has_tos) {
-      __ mov(Lscratch, Otos_i);  // restore object pointer
+      __ pop_ptr(Otos_i);  // restore object pointer
       __ verify_oop(Otos_i);
     }
     __ get_cache_and_index_at_bcp(Rcache, index, 1);
--- a/hotspot/src/cpu/x86/vm/vm_version_x86_32.hpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/cpu/x86/vm/vm_version_x86_32.hpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/cpu/x86/vm/vm_version_x86_64.hpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/cpu/x86/vm/vm_version_x86_64.hpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/os/linux/launcher/java.c	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/os/linux/launcher/java.c	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1999-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/os/linux/launcher/java.h	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/os/linux/launcher/java.h	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2005 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1999-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/os/linux/launcher/java_md.c	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/os/linux/launcher/java_md.c	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2005 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1999-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/os/linux/vm/globals_linux.hpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/os/linux/vm/globals_linux.hpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2005-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/os/linux/vm/os_linux.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/os/linux/vm/os_linux.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -2272,7 +2272,9 @@
   uncommit_memory(addr, bytes);
 }
 
-void os::numa_make_global(char *addr, size_t bytes)    { }
+void os::numa_make_global(char *addr, size_t bytes) {
+  Linux::numa_interleave_memory(addr, bytes);
+}
 
 void os::numa_make_local(char *addr, size_t bytes, int lgrp_hint) {
   Linux::numa_tonode_memory(addr, bytes, lgrp_hint);
@@ -2314,7 +2316,7 @@
 extern "C" void numa_warn(int number, char *where, ...) { }
 extern "C" void numa_error(char *where) { }
 
-void os::Linux::libnuma_init() {
+bool os::Linux::libnuma_init() {
   // sched_getcpu() should be in libc.
   set_sched_getcpu(CAST_TO_FN_PTR(sched_getcpu_func_t,
                                   dlsym(RTLD_DEFAULT, "sched_getcpu")));
@@ -2330,31 +2332,51 @@
                                         dlsym(handle, "numa_available")));
       set_numa_tonode_memory(CAST_TO_FN_PTR(numa_tonode_memory_func_t,
                                             dlsym(handle, "numa_tonode_memory")));
+      set_numa_interleave_memory(CAST_TO_FN_PTR(numa_interleave_memory_func_t,
+                                            dlsym(handle, "numa_interleave_memory")));
+
+
       if (numa_available() != -1) {
+        set_numa_all_nodes((unsigned long*)dlsym(handle, "numa_all_nodes"));
         // Create a cpu -> node mapping
         _cpu_to_node = new (ResourceObj::C_HEAP) GrowableArray<int>(0, true);
         rebuild_cpu_to_node_map();
+        return true;
       }
     }
   }
+  return false;
 }
 
 // rebuild_cpu_to_node_map() constructs a table mapping cpud id to node id.
 // The table is later used in get_node_by_cpu().
 void os::Linux::rebuild_cpu_to_node_map() {
-  int cpu_num = os::active_processor_count();
+  const size_t NCPUS = 32768; // Since the buffer size computation is very obscure
+                              // in libnuma (possible values are starting from 16,
+                              // and continuing up with every other power of 2, but less
+                              // than the maximum number of CPUs supported by kernel), and
+                              // is a subject to change (in libnuma version 2 the requirements
+                              // are more reasonable) we'll just hardcode the number they use
+                              // in the library.
+  const size_t BitsPerCLong = sizeof(long) * CHAR_BIT;
+
+  size_t cpu_num = os::active_processor_count();
+  size_t cpu_map_size = NCPUS / BitsPerCLong;
+  size_t cpu_map_valid_size =
+    MIN2((cpu_num + BitsPerCLong - 1) / BitsPerCLong, cpu_map_size);
+
   cpu_to_node()->clear();
   cpu_to_node()->at_grow(cpu_num - 1);
-  int node_num = numa_get_groups_num();
-  int cpu_map_size = (cpu_num + BitsPerLong - 1) / BitsPerLong;
+  size_t node_num = numa_get_groups_num();
+
   unsigned long *cpu_map = NEW_C_HEAP_ARRAY(unsigned long, cpu_map_size);
-  for (int i = 0; i < node_num; i++) {
+  for (size_t i = 0; i < node_num; i++) {
     if (numa_node_to_cpus(i, cpu_map, cpu_map_size * sizeof(unsigned long)) != -1) {
-      for (int j = 0; j < cpu_map_size; j++) {
+      for (size_t j = 0; j < cpu_map_valid_size; j++) {
         if (cpu_map[j] != 0) {
-          for (int k = 0; k < BitsPerLong; k++) {
+          for (size_t k = 0; k < BitsPerCLong; k++) {
             if (cpu_map[j] & (1UL << k)) {
-              cpu_to_node()->at_put(j * BitsPerLong + k, i);
+              cpu_to_node()->at_put(j * BitsPerCLong + k, i);
             }
           }
         }
@@ -2377,7 +2399,8 @@
 os::Linux::numa_max_node_func_t os::Linux::_numa_max_node;
 os::Linux::numa_available_func_t os::Linux::_numa_available;
 os::Linux::numa_tonode_memory_func_t os::Linux::_numa_tonode_memory;
-
+os::Linux::numa_interleave_memory_func_t os::Linux::_numa_interleave_memory;
+unsigned long* os::Linux::_numa_all_nodes;
 
 bool os::uncommit_memory(char* addr, size_t size) {
   return ::mmap(addr, size,
@@ -2477,7 +2500,7 @@
 }
 
 bool os::unguard_memory(char* addr, size_t size) {
-  return linux_mprotect(addr, size, PROT_READ|PROT_WRITE|PROT_EXEC);
+  return linux_mprotect(addr, size, PROT_READ|PROT_WRITE);
 }
 
 // Large page support
@@ -3695,7 +3718,17 @@
   }
 
   if (UseNUMA) {
-    Linux::libnuma_init();
+    if (!Linux::libnuma_init()) {
+      UseNUMA = false;
+    } else {
+      if ((Linux::numa_max_node() < 1)) {
+        // There's only one node(they start from 0), disable NUMA.
+        UseNUMA = false;
+      }
+    }
+    if (!UseNUMA && ForceNUMA) {
+      UseNUMA = true;
+    }
   }
 
   if (MaxFDLimit) {
--- a/hotspot/src/os/linux/vm/os_linux.hpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/os/linux/vm/os_linux.hpp	Thu Jan 08 16:34:58 2009 -0800
@@ -146,7 +146,7 @@
   static bool is_floating_stack()             { return _is_floating_stack; }
 
   static void libpthread_init();
-  static void libnuma_init();
+  static bool libnuma_init();
 
   // Minimum stack size a thread can be created with (allowing
   // the VM to completely create the thread and enter user code)
@@ -240,20 +240,23 @@
   typedef int (*numa_max_node_func_t)(void);
   typedef int (*numa_available_func_t)(void);
   typedef int (*numa_tonode_memory_func_t)(void *start, size_t size, int node);
-
+  typedef void (*numa_interleave_memory_func_t)(void *start, size_t size, unsigned long *nodemask);
 
   static sched_getcpu_func_t _sched_getcpu;
   static numa_node_to_cpus_func_t _numa_node_to_cpus;
   static numa_max_node_func_t _numa_max_node;
   static numa_available_func_t _numa_available;
   static numa_tonode_memory_func_t _numa_tonode_memory;
+  static numa_interleave_memory_func_t _numa_interleave_memory;
+  static unsigned long* _numa_all_nodes;
 
   static void set_sched_getcpu(sched_getcpu_func_t func) { _sched_getcpu = func; }
   static void set_numa_node_to_cpus(numa_node_to_cpus_func_t func) { _numa_node_to_cpus = func; }
   static void set_numa_max_node(numa_max_node_func_t func) { _numa_max_node = func; }
   static void set_numa_available(numa_available_func_t func) { _numa_available = func; }
   static void set_numa_tonode_memory(numa_tonode_memory_func_t func) { _numa_tonode_memory = func; }
-
+  static void set_numa_interleave_memory(numa_interleave_memory_func_t func) { _numa_interleave_memory = func; }
+  static void set_numa_all_nodes(unsigned long* ptr) { _numa_all_nodes = ptr; }
 public:
   static int sched_getcpu()  { return _sched_getcpu != NULL ? _sched_getcpu() : -1; }
   static int numa_node_to_cpus(int node, unsigned long *buffer, int bufferlen) {
@@ -264,6 +267,11 @@
   static int numa_tonode_memory(void *start, size_t size, int node) {
     return _numa_tonode_memory != NULL ? _numa_tonode_memory(start, size, node) : -1;
   }
+  static void numa_interleave_memory(void *start, size_t size) {
+    if (_numa_interleave_memory != NULL && _numa_all_nodes != NULL) {
+      _numa_interleave_memory(start, size, _numa_all_nodes);
+    }
+  }
   static int get_node_by_cpu(int cpu_id);
 };
 
--- a/hotspot/src/os/solaris/launcher/java.c	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/os/solaris/launcher/java.c	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 1998-2005 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1998-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/os/solaris/launcher/java.h	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/os/solaris/launcher/java.h	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 1998-2005 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1998-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/os/solaris/launcher/java_md.c	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/os/solaris/launcher/java_md.c	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 1998-2005 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1998-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/os/solaris/vm/globals_solaris.hpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/os/solaris/vm/globals_solaris.hpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2005-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/os/solaris/vm/os_solaris.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/os/solaris/vm/os_solaris.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1638,16 +1638,24 @@
 // getTimeNanos is guaranteed to not move backward on Solaris
 inline hrtime_t getTimeNanos() {
   if (VM_Version::supports_cx8()) {
-    bool retry = false;
-    hrtime_t newtime = gethrtime();
-    hrtime_t oldmaxtime = max_hrtime;
-    hrtime_t retmaxtime = oldmaxtime;
-    while ((newtime > retmaxtime) && (retry == false || retmaxtime != oldmaxtime)) {
-      oldmaxtime = retmaxtime;
-      retmaxtime = Atomic::cmpxchg(newtime, (volatile jlong *)&max_hrtime, oldmaxtime);
-      retry = true;
-    }
-    return (newtime > retmaxtime) ? newtime : retmaxtime;
+    const hrtime_t now = gethrtime();
+    const hrtime_t prev = max_hrtime;
+    if (now <= prev)  return prev;   // same or retrograde time;
+    const hrtime_t obsv = Atomic::cmpxchg(now, (volatile jlong*)&max_hrtime, prev);
+    assert(obsv >= prev, "invariant");   // Monotonicity
+    // If the CAS succeeded then we're done and return "now".
+    // If the CAS failed and the observed value "obs" is >= now then
+    // we should return "obs".  If the CAS failed and now > obs > prv then
+    // some other thread raced this thread and installed a new value, in which case
+    // we could either (a) retry the entire operation, (b) retry trying to install now
+    // or (c) just return obs.  We use (c).   No loop is required although in some cases
+    // we might discard a higher "now" value in deference to a slightly lower but freshly
+    // installed obs value.   That's entirely benign -- it admits no new orderings compared
+    // to (a) or (b) -- and greatly reduces coherence traffic.
+    // We might also condition (c) on the magnitude of the delta between obs and now.
+    // Avoiding excessive CAS operations to hot RW locations is critical.
+    // See http://blogs.sun.com/dave/entry/cas_and_cache_trivia_invalidate
+    return (prev == obsv) ? now : obsv ;
   } else {
     return oldgetTimeNanos();
   }
@@ -3026,6 +3034,8 @@
 
 // Protect memory (Used to pass readonly pages through
 // JNI GetArray<type>Elements with empty arrays.)
+// Also, used for serialization page and for compressed oops null pointer
+// checking.
 bool os::protect_memory(char* addr, size_t bytes, ProtType prot,
                         bool is_committed) {
   unsigned int p = 0;
@@ -3049,7 +3059,7 @@
 }
 
 bool os::unguard_memory(char* addr, size_t bytes) {
-  return solaris_mprotect(addr, bytes, PROT_READ|PROT_WRITE|PROT_EXEC);
+  return solaris_mprotect(addr, bytes, PROT_READ|PROT_WRITE);
 }
 
 // Large page support
@@ -4638,7 +4648,7 @@
   }
 }
 
-void os::Solaris::liblgrp_init() {
+bool os::Solaris::liblgrp_init() {
   void *handle = dlopen("liblgrp.so.1", RTLD_LAZY);
   if (handle != NULL) {
     os::Solaris::set_lgrp_home(CAST_TO_FN_PTR(lgrp_home_func_t, dlsym(handle, "lgrp_home")));
@@ -4653,9 +4663,9 @@
 
     lgrp_cookie_t c = lgrp_init(LGRP_VIEW_CALLER);
     set_lgrp_cookie(c);
-  } else {
-    warning("your OS does not support NUMA");
-  }
+    return true;
+  }
+  return false;
 }
 
 void os::Solaris::misc_sym_init() {
@@ -4824,9 +4834,25 @@
         vm_page_size()));
 
   Solaris::libthread_init();
+
   if (UseNUMA) {
-    Solaris::liblgrp_init();
-  }
+    if (!Solaris::liblgrp_init()) {
+      UseNUMA = false;
+    } else {
+      size_t lgrp_limit = os::numa_get_groups_num();
+      int *lgrp_ids = NEW_C_HEAP_ARRAY(int, lgrp_limit);
+      size_t lgrp_num = os::numa_get_leaf_groups(lgrp_ids, lgrp_limit);
+      FREE_C_HEAP_ARRAY(int, lgrp_ids);
+      if (lgrp_num < 2) {
+        // There's only one locality group, disable NUMA.
+        UseNUMA = false;
+      }
+    }
+    if (!UseNUMA && ForceNUMA) {
+      UseNUMA = true;
+    }
+  }
+
   Solaris::misc_sym_init();
   Solaris::signal_sets_init();
   Solaris::init_signal_mem();
--- a/hotspot/src/os/solaris/vm/os_solaris.hpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/os/solaris/vm/os_solaris.hpp	Thu Jan 08 16:34:58 2009 -0800
@@ -176,7 +176,7 @@
  public:
   static void libthread_init();
   static void synchronization_init();
-  static void liblgrp_init();
+  static bool liblgrp_init();
   // Load miscellaneous symbols.
   static void misc_sym_init();
   // This boolean allows users to forward their own non-matching signals
--- a/hotspot/src/os/windows/vm/globals_windows.hpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/os/windows/vm/globals_windows.hpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2005-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/os/windows/vm/os_windows.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/os/windows/vm/os_windows.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -2020,10 +2020,11 @@
         if (UnguardOnExecutionViolation > 0 && addr != last_addr &&
             (UnguardOnExecutionViolation > 1 || os::address_is_in_vm(addr))) {
 
-          // Unguard and retry
+          // Set memory to RWX and retry
           address page_start =
             (address) align_size_down((intptr_t) addr, (intptr_t) page_size);
-          bool res = os::unguard_memory((char*) page_start, page_size);
+          bool res = os::protect_memory((char*) page_start, page_size,
+                                        os::MEM_PROT_RWX);
 
           if (PrintMiscellaneous && Verbose) {
             char buf[256];
@@ -2217,15 +2218,10 @@
                 // We only expect null pointers in the stubs (vtable)
                 // the rest are checked explicitly now.
                 //
-                CodeBlob* cb = CodeCache::find_blob(pc);
-                if (cb != NULL) {
-                  if (VtableStubs::stub_containing(pc) != NULL) {
-                    if (((uintptr_t)addr) < os::vm_page_size() ) {
-                      // an access to the first page of VM--assume it is a null pointer
-                      return Handle_Exception(exceptionInfo,
-                        SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL));
-                    }
-                  }
+                if (((uintptr_t)addr) < os::vm_page_size() ) {
+                  // an access to the first page of VM--assume it is a null pointer
+                  address stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL);
+                  if (stub != NULL) return Handle_Exception(exceptionInfo, stub);
                 }
               }
             } // in_java
@@ -2241,9 +2237,8 @@
             // Windows 98 reports faulting addresses incorrectly
             if (!MacroAssembler::needs_explicit_null_check((intptr_t)addr) ||
                 !os::win32::is_nt()) {
-
-              return Handle_Exception(exceptionInfo,
-                  SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL));
+              address stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL);
+              if (stub != NULL) return Handle_Exception(exceptionInfo, stub);
             }
             report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord,
                          exceptionInfo->ContextRecord);
@@ -2761,12 +2756,12 @@
 
 bool os::guard_memory(char* addr, size_t bytes) {
   DWORD old_status;
-  return VirtualProtect(addr, bytes, PAGE_EXECUTE_READWRITE | PAGE_GUARD, &old_status) != 0;
+  return VirtualProtect(addr, bytes, PAGE_READWRITE | PAGE_GUARD, &old_status) != 0;
 }
 
 bool os::unguard_memory(char* addr, size_t bytes) {
   DWORD old_status;
-  return VirtualProtect(addr, bytes, PAGE_EXECUTE_READWRITE, &old_status) != 0;
+  return VirtualProtect(addr, bytes, PAGE_READWRITE, &old_status) != 0;
 }
 
 void os::realign_memory(char *addr, size_t bytes, size_t alignment_hint) { }
@@ -3353,6 +3348,10 @@
   // initialize thread priority policy
   prio_init();
 
+  if (UseNUMA && !ForceNUMA) {
+    UseNUMA = false; // Currently unsupported.
+  }
+
   return JNI_OK;
 }
 
--- a/hotspot/src/os/windows/vm/os_windows.hpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/os/windows/vm/os_windows.hpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/os_cpu/linux_x86/vm/linux_x86_32.ad	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/os_cpu/linux_x86/vm/linux_x86_32.ad	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 //
-// Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
+// Copyright 1999-2008 Sun Microsystems, Inc.  All Rights Reserved.
 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 //
 // This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -422,10 +422,11 @@
       if (addr != last_addr &&
           (UnguardOnExecutionViolation > 1 || os::address_is_in_vm(addr))) {
 
-        // Unguard and retry
+        // Set memory to RWX and retry
         address page_start =
           (address) align_size_down((intptr_t) addr, (intptr_t) page_size);
-        bool res = os::unguard_memory((char*) page_start, page_size);
+        bool res = os::protect_memory((char*) page_start, page_size,
+                                      os::MEM_PROT_RWX);
 
         if (PrintMiscellaneous && Verbose) {
           char buf[256];
--- a/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -203,10 +203,10 @@
   return frame(fr->sender_sp(), fr->link(), fr->sender_pc());
 }
 
-extern "C" intptr_t *_get_previous_fp();  // in .il file.
+extern "C" intptr_t *_get_current_fp();  // in .il file
 
 frame os::current_frame() {
-  intptr_t* fp = _get_previous_fp();
+  intptr_t* fp = _get_current_fp();  // it's inlined so want current fp
   frame myframe((intptr_t*)os::current_stack_pointer(),
                 (intptr_t*)fp,
                 CAST_FROM_FN_PTR(address, os::current_frame));
@@ -576,10 +576,11 @@
       if (addr != last_addr &&
           (UnguardOnExecutionViolation > 1 || os::address_is_in_vm(addr))) {
 
-        // Unguard and retry
+        // Make memory rwx and retry
         address page_start =
           (address) align_size_down((intptr_t) addr, (intptr_t) page_size);
-        bool res = os::unguard_memory((char*) page_start, page_size);
+        bool res = os::protect_memory((char*) page_start, page_size,
+                                      os::MEM_PROT_RWX);
 
         if (PrintMiscellaneous && Verbose) {
           char buf[256];
--- a/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_32.il	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_32.il	Thu Jan 08 16:34:58 2009 -0800
@@ -37,10 +37,10 @@
       movl     %gs:0, %eax 
       .end
 
-  // Get callers fp
-      .inline _get_previous_fp,0
+  // Get current fp
+      .inline _get_current_fp,0
+      .volatile
       movl     %ebp, %eax 
-      movl     %eax, %eax
       .end
 
   // Support for jint Atomic::add(jint inc, volatile jint* dest)
--- a/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_64.il	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_64.il	Thu Jan 08 16:34:58 2009 -0800
@@ -30,10 +30,10 @@
       movq     %fs:0, %rax 
       .end
 
-  // Get the frame pointer from previous frame.
-      .inline _get_previous_fp,0
+  // Get the frame pointer from current frame.
+      .inline _get_current_fp,0
+      .volatile
       movq     %rbp, %rax 
-      movq     %rax, %rax 
       .end
 
   // Support for jint Atomic::add(jint add_value, volatile jint* dest)
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/XMLWriter.java	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/XMLWriter.java	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 1998-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1998-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Difference/src/com/sun/hotspot/igv/difference/Difference.java	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Difference/src/com/sun/hotspot/igv/difference/Difference.java	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 1998-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1998-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/CustomFilter.java	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/CustomFilter.java	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 1998-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1998-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/PropertiesSheet.java	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/PropertiesSheet.java	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 1998-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1998-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/RangeSliderModel.java	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/RangeSliderModel.java	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 1998-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1998-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramViewModel.java	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramViewModel.java	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 1998-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1998-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/adlc/adlparse.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/adlc/adlparse.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -108,6 +108,7 @@
     else if (!strcmp(ident, "pipeline"))   pipe_parse();
     else if (!strcmp(ident, "definitions")) definitions_parse();
     else if (!strcmp(ident, "peephole"))   peep_parse();
+    else if (!strcmp(ident, "#line"))      preproc_line();
     else if (!strcmp(ident, "#define"))    preproc_define();
     else if (!strcmp(ident, "#undef"))     preproc_undef();
     else {
@@ -786,9 +787,11 @@
         parse_err(SYNERR, "missing identifier inside register block.\n");
         return;
       }
-      if (strcmp(token,"reg_def")==0)     { reg_def_parse(); }
-      if (strcmp(token,"reg_class")==0)   { reg_class_parse(); }
-      if (strcmp(token,"alloc_class")==0) { alloc_class_parse(); }
+      if (strcmp(token,"reg_def")==0)          { reg_def_parse(); }
+      else if (strcmp(token,"reg_class")==0)   { reg_class_parse(); }
+      else if (strcmp(token,"alloc_class")==0) { alloc_class_parse(); }
+      else if (strcmp(token,"#define")==0)     { preproc_define(); }
+      else { parse_err(SYNERR, "bad token %s inside register block.\n", token); break; }
       skipws();
     }
   }
@@ -903,11 +906,7 @@
   skipws_no_preproc();              // Skip leading whitespace
   // Prepend location descriptor, for debugging; cf. ADLParser::find_cpp_block
   if (_AD._adlocation_debug) {
-    const char* file     = _AD._ADL_file._name;
-    int         line     = linenum();
-    char*       location = (char *)malloc(strlen(file) + 100);
-    sprintf(location, "#line %d \"%s\"\n", line, file);
-    encoding->add_code(location);
+    encoding->add_code(get_line_string());
   }
 
   // Collect the parts of the encode description
@@ -948,6 +947,10 @@
 
   skipws();
 
+  if (_AD._adlocation_debug) {
+    encoding->add_code(end_line_marker());
+  }
+
   // Debug Stuff
   if (_AD._adl_debug > 1) fprintf(stderr,"EncodingClass Form: %s\n", ec_name);
 }
@@ -2349,7 +2352,11 @@
         return;
       }
       RegDef *regDef = _AD._register->getRegDef(rname);
-      reg_class->addReg(regDef);     // add regDef to regClass
+      if (!regDef) {
+        parse_err(SEMERR, "unknown identifier %s inside reg_class list.\n", rname);
+      } else {
+        reg_class->addReg(regDef); // add regDef to regClass
+      }
 
       // Check for ',' and position to next token.
       skipws();
@@ -2746,7 +2753,8 @@
   char      *rule = NULL;         // String representation of predicate
 
   skipws();                       // Skip leading whitespace
-  if ( (rule = get_paren_expr("pred expression")) == NULL ) {
+  int line = linenum();
+  if ( (rule = get_paren_expr("pred expression", true)) == NULL ) {
     parse_err(SYNERR, "incorrect or missing expression for 'predicate'\n");
     return NULL;
   }
@@ -3407,7 +3415,12 @@
         // Check if there is a string to pass through to output
         char *start = _ptr;       // Record start of the next string
         while ((_curchar != '$') && (_curchar != '"') && (_curchar != '%') && (_curchar != '\n')) {
-          if (_curchar == '\\')  next_char();  // superquote
+          if (_curchar == '\\') {
+            next_char();  // superquote
+            if ((_curchar == '$') || (_curchar == '%'))
+              // hack to avoid % escapes and warnings about undefined \ escapes
+              *(_ptr-1) = _curchar;
+          }
           if (_curchar == '\n')  parse_err(SYNERR, "newline in string");  // unimplemented!
           next_char();
         }
@@ -3942,8 +3955,7 @@
     next_char();                  // Skip block delimiter
     skipws_no_preproc();          // Skip leading whitespace
     cppBlock = _ptr;              // Point to start of expression
-    const char* file = _AD._ADL_file._name;
-    int         line = linenum();
+    int line = linenum();
     next = _ptr + 1;
     while(((_curchar != '%') || (*next != '}')) && (_curchar != '\0')) {
       next_char_or_line();
@@ -3958,15 +3970,16 @@
     _curchar = *_ptr;             // Maintain invariant
 
     // Prepend location descriptor, for debugging.
-    char* location = (char *)malloc(strlen(file) + 100);
-    *location = '\0';
-    if (_AD._adlocation_debug)
-      sprintf(location, "#line %d \"%s\"\n", line, file);
-    char* result = (char *)malloc(strlen(location) + strlen(cppBlock) + 1);
-    strcpy(result, location);
-    strcat(result, cppBlock);
-    cppBlock = result;
-    free(location);
+    if (_AD._adlocation_debug) {
+      char* location = get_line_string(line);
+      char* end_loc  = end_line_marker();
+      char* result = (char *)malloc(strlen(location) + strlen(cppBlock) + strlen(end_loc) + 1);
+      strcpy(result, location);
+      strcat(result, cppBlock);
+      strcat(result, end_loc);
+      cppBlock = result;
+      free(location);
+    }
   }
 
   return cppBlock;
@@ -4036,13 +4049,26 @@
 
 // Helper function around get_expr
 // Sets _curchar to '(' so that get_paren_expr will search for a matching ')'
-char *ADLParser::get_paren_expr(const char *description) {
+char *ADLParser::get_paren_expr(const char *description, bool include_location) {
+  int line = linenum();
   if (_curchar != '(')            // Escape if not valid starting position
     return NULL;
   next_char();                    // Skip the required initial paren.
   char *token2 = get_expr(description, ")");
   if (_curchar == ')')
     next_char();                  // Skip required final paren.
+  int junk = 0;
+  if (include_location && _AD._adlocation_debug && !is_int_token(token2, junk)) {
+    // Prepend location descriptor, for debugging.
+    char* location = get_line_string(line);
+    char* end_loc  = end_line_marker();
+    char* result = (char *)malloc(strlen(location) + strlen(token2) + strlen(end_loc) + 1);
+    strcpy(result, location);
+    strcat(result, token2);
+    strcat(result, end_loc);
+    token2 = result;
+    free(location);
+  }
   return token2;
 }
 
@@ -4082,10 +4108,16 @@
   if (do_preproc && start != NULL) {
     const char* def = _AD.get_preproc_def(start);
     if (def != NULL && strcmp(def, start)) {
-      const char* def2 = _AD.get_preproc_def(def);
-      if (def2 != NULL && strcmp(def2, def)) {
-        parse_err(SYNERR, "unimplemented: using %s defined as %s => %s",
-                  start, def, def2);
+      const char* def1 = def;
+      const char* def2 = _AD.get_preproc_def(def1);
+      // implement up to 2 levels of #define
+      if (def2 != NULL && strcmp(def2, def1)) {
+        def = def2;
+        const char* def3 = _AD.get_preproc_def(def2);
+        if (def3 != NULL && strcmp(def3, def2) && strcmp(def3, def1)) {
+          parse_err(SYNERR, "unimplemented: using %s defined as %s => %s => %s",
+                    start, def1, def2, def3);
+        }
       }
       start = strdup(def);
     }
@@ -4431,6 +4463,35 @@
 }
 
 
+//-------------------------------preproc_line----------------------------------
+// A "#line" keyword has been seen, so parse the rest of the line.
+void ADLParser::preproc_line(void) {
+  int line = get_int();
+  skipws_no_preproc();
+  const char* file = NULL;
+  if (_curchar == '"') {
+    next_char();              // Move past the initial '"'
+    file = _ptr;
+    while (true) {
+      if (_curchar == '\n') {
+        parse_err(SYNERR, "missing '\"' at end of #line directive");
+        return;
+      }
+      if (_curchar == '"') {
+        *_ptr  = '\0';          // Terminate the string
+        next_char();
+        skipws_no_preproc();
+        break;
+      }
+      next_char();
+    }
+  }
+  ensure_end_of_line();
+  if (file != NULL)
+    _AD._ADL_file._name = file;
+  _buf.set_linenum(line);
+}
+
 //------------------------------preproc_define---------------------------------
 // A "#define" keyword has been seen, so parse the rest of the line.
 void ADLParser::preproc_define(void) {
@@ -4494,6 +4555,7 @@
 // A preprocessor directive has been encountered.  Be sure it has fallen at
 // the begining of a line, or else report an error.
 void ADLParser::ensure_start_of_line(void) {
+  if (_curchar == '\n') { next_line(); return; }
   assert( _ptr >= _curline && _ptr < _curline+strlen(_curline),
           "Must be able to find which line we are in" );
 
@@ -4662,6 +4724,7 @@
 
 //---------------------------next_char-----------------------------------------
 void ADLParser::next_char() {
+  if (_curchar == '\n')  parse_err(WARN, "must call next_line!");
   _curchar = *++_ptr;
   // if ( _curchar == '\n' ) {
   //   next_line();
@@ -4682,6 +4745,18 @@
 //---------------------------next_line-----------------------------------------
 void ADLParser::next_line() {
   _curline = _buf.get_line();
+  _curchar = ' ';
+}
+
+//------------------------get_line_string--------------------------------------
+// Prepended location descriptor, for debugging.
+// Must return a malloced string (that can be freed if desired).
+char* ADLParser::get_line_string(int linenum) {
+  const char* file = _AD._ADL_file._name;
+  int         line = linenum ? linenum : this->linenum();
+  char* location = (char *)malloc(strlen(file) + 100);
+  sprintf(location, "\n#line %d \"%s\"\n", line, file);
+  return location;
 }
 
 //-------------------------is_literal_constant---------------------------------
@@ -4722,6 +4797,66 @@
   return true;
 }
 
+static const char* skip_expr_ws(const char* str) {
+  const char * cp = str;
+  while (cp[0]) {
+    if (cp[0] <= ' ') {
+      ++cp;
+    } else if (cp[0] == '#') {
+      ++cp;
+      while (cp[0] == ' ')  ++cp;
+      assert(0 == strncmp(cp, "line", 4), "must be a #line directive");
+      const char* eol = strchr(cp, '\n');
+      assert(eol != NULL, "must find end of line");
+      if (eol == NULL)  eol = cp + strlen(cp);
+      cp = eol;
+    } else {
+      break;
+    }
+  }
+  return cp;
+}
+
+//-----------------------equivalent_expressions--------------------------------
+bool ADLParser::equivalent_expressions(const char* str1, const char* str2) {
+  if (str1 == str2)
+    return true;
+  else if (str1 == NULL || str2 == NULL)
+    return false;
+  const char* cp1 = str1;
+  const char* cp2 = str2;
+  char in_quote = '\0';
+  while (cp1[0] && cp2[0]) {
+    if (!in_quote) {
+      // skip spaces and/or cpp directives
+      const char* cp1a = skip_expr_ws(cp1);
+      const char* cp2a = skip_expr_ws(cp2);
+      if (cp1a > cp1 && cp2a > cp2) {
+        cp1 = cp1a; cp2 = cp2a;
+        continue;
+      }
+      if (cp1a > cp1 || cp2a > cp2)  break; // fail
+    }
+    // match one non-space char
+    if (cp1[0] != cp2[0])  break; // fail
+    char ch = cp1[0];
+    cp1++; cp2++;
+    // watch for quotes
+    if (in_quote && ch == '\\') {
+      if (cp1[0] != cp2[0])  break; // fail
+      if (!cp1[0])  break;
+      cp1++; cp2++;
+    }
+    if (in_quote && ch == in_quote) {
+      in_quote = '\0';
+    } else if (!in_quote && (ch == '"' || ch == '\'')) {
+      in_quote = ch;
+    }
+  }
+  return (!cp1[0] && !cp2[0]);
+}
+
+
 //-------------------------------trim------------------------------------------
 void ADLParser::trim(char* &token) {
   while (*token <= ' ')  token++;
--- a/hotspot/src/share/vm/adlc/adlparse.hpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/adlc/adlparse.hpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -93,6 +93,7 @@
   void pipe_parse(void);        // Parse pipeline section
   void definitions_parse(void); // Parse definitions section
   void peep_parse(void);        // Parse peephole rule definitions
+  void preproc_line(void);      // Parse a #line statement
   void preproc_define(void);    // Parse a #define statement
   void preproc_undef(void);     // Parse an #undef statement
 
@@ -226,7 +227,7 @@
   void  get_effectlist(FormDict &effects, FormDict &operands); // Parse effect-operand pairs
   // Return the contents of a parenthesized expression.
   // Requires initial '(' and consumes final ')', which is replaced by '\0'.
-  char *get_paren_expr(const char *description);
+  char *get_paren_expr(const char *description, bool include_location = false);
   // Return expression up to next stop-char, which terminator replaces.
   // Does not require initial '('.  Does not consume final stop-char.
   // Final stop-char is left in _curchar, but is also is replaced by '\0'.
@@ -234,6 +235,11 @@
   char *find_cpp_block(const char *description); // Parse a C++ code block
   // Issue parser error message & go to EOL
   void parse_err(int flag, const char *fmt, ...);
+  // Create a location marker for this file and line.
+  char *get_line_string(int linenum = 0);
+  // Return a location marker which tells the C preprocessor to
+  // forget the previous location marker.  (Requires awk postprocessing.)
+  char *end_line_marker() { return (char*)"\n#line 999999\n"; }
 
   // Return pointer to current character
   inline char  cur_char(void);
@@ -268,5 +274,6 @@
   static bool is_literal_constant(const char *hex_string);
   static bool is_hex_digit(char digit);
   static bool is_int_token(const char* token, int& intval);
+  static bool equivalent_expressions(const char* str1, const char* str2);
   static void trim(char* &token);  // trim leading & trailing spaces
 };
--- a/hotspot/src/share/vm/adlc/archDesc.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/adlc/archDesc.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -140,7 +140,7 @@
       if ((rch == _rchild) || (rch && _rchild && !strcmp(rch, _rchild))) {
         char * predStr = get_pred();
         char * prStr = pr?pr->_pred:NULL;
-        if ((prStr == predStr) || (prStr && predStr && !strcmp(prStr, predStr))) {
+        if (ADLParser::equivalent_expressions(prStr, predStr)) {
           return true;
         }
       }
--- a/hotspot/src/share/vm/adlc/dfa.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/adlc/dfa.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -458,7 +458,7 @@
 
 
 class dfa_shared_preds {
-  enum { count = 2 };
+  enum { count = 4 };
 
   static bool        _found[count];
   static const char* _type [count];
@@ -479,12 +479,15 @@
     char c  = *prev;
     switch( c ) {
     case ' ':
+    case '\n':
       return dfa_shared_preds::valid_loc(pred, prev);
     case '!':
     case '(':
     case '<':
     case '=':
       return true;
+    case '"':  // such as: #line 10 "myfile.ad"\n mypredicate
+      return true;
     case '|':
       if( prev != pred && *(prev-1) == '|' ) return true;
     case '&':
@@ -564,10 +567,14 @@
   }
 };
 // shared predicates, _var and _pred entry should be the same length
-bool         dfa_shared_preds::_found[dfa_shared_preds::count] = { false, false };
-const char*  dfa_shared_preds::_type[dfa_shared_preds::count]  = { "int", "bool" };
-const char*  dfa_shared_preds::_var [dfa_shared_preds::count]  = { "_n_get_int__", "Compile__current____select_24_bit_instr__" };
-const char*  dfa_shared_preds::_pred[dfa_shared_preds::count]  = { "n->get_int()", "Compile::current()->select_24_bit_instr()" };
+bool         dfa_shared_preds::_found[dfa_shared_preds::count]
+  = { false, false, false, false };
+const char*  dfa_shared_preds::_type[dfa_shared_preds::count]
+  = { "int", "jlong", "intptr_t", "bool" };
+const char*  dfa_shared_preds::_var [dfa_shared_preds::count]
+  = { "_n_get_int__", "_n_get_long__", "_n_get_intptr_t__", "Compile__current____select_24_bit_instr__" };
+const char*  dfa_shared_preds::_pred[dfa_shared_preds::count]
+  = { "n->get_int()", "n->get_long()", "n->get_intptr_t()", "Compile::current()->select_24_bit_instr()" };
 
 
 void ArchDesc::gen_dfa_state_body(FILE* fp, Dict &minimize, ProductionState &status, Dict &operands_chained_from, int i) {
--- a/hotspot/src/share/vm/adlc/filebuff.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/adlc/filebuff.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2002 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/adlc/filebuff.hpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/adlc/filebuff.hpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2004 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -68,6 +68,7 @@
   // and increments bufeol and filepos to point at the end of that line.
   char *get_line(void);
   int linenum() const { return _linenum; }
+  void set_linenum(int line) { _linenum = line; }
 
   // This converts a pointer into the buffer to a file offset.  It only works
   // when the pointer is valid (i.e. just obtained from getline()).
--- a/hotspot/src/share/vm/adlc/formssel.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/adlc/formssel.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1102,10 +1102,7 @@
   }
   if( pred1 != NULL && pred2 != NULL ) {
     // compare the predicates
-    const char *str1 = pred1->_pred;
-    const char *str2 = pred2->_pred;
-    if( (str1 == NULL && str2 == NULL)
-        || (str1 != NULL && str2 != NULL && strcmp(str1,str2) == 0) ) {
+    if (ADLParser::equivalent_expressions(pred1->_pred, pred2->_pred)) {
       return true;
     }
   }
--- a/hotspot/src/share/vm/adlc/formssel.hpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/adlc/formssel.hpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 1998-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1998-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1999-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -676,21 +676,6 @@
 }
 
 
-void GraphBuilder::kill_field(ciField* field) {
-  if (UseLocalValueNumbering) {
-    vmap()->kill_field(field);
-  }
-}
-
-
-void GraphBuilder::kill_array(Value value) {
-  if (UseLocalValueNumbering) {
-    vmap()->kill_array(value->type());
-  }
-  _memory->store_value(value);
-}
-
-
 void GraphBuilder::kill_all() {
   if (UseLocalValueNumbering) {
     vmap()->kill_all();
@@ -987,8 +972,8 @@
     length = append(new ArrayLength(array, lock_stack()));
   }
   StoreIndexed* result = new StoreIndexed(array, index, length, type, value, lock_stack());
-  kill_array(value); // invalidate all CSEs that are memory accesses of the same type
   append(result);
+  _memory->store_value(value);
 }
 
 
@@ -1478,9 +1463,6 @@
     case Bytecodes::_putstatic:
       { Value val = pop(type);
         append(new StoreField(append(obj), offset, field, val, true, lock_stack(), state_copy, is_loaded, is_initialized));
-        if (UseLocalValueNumbering) {
-          vmap()->kill_field(field);   // invalidate all CSEs that are memory accesses
-        }
       }
       break;
     case Bytecodes::_getfield :
@@ -1503,7 +1485,6 @@
         if (is_loaded) store = _memory->store(store);
         if (store != NULL) {
           append(store);
-          kill_field(field);   // invalidate all CSEs that are accesses of this field
         }
       }
       break;
@@ -1900,6 +1881,8 @@
       assert(i2->bci() != -1, "should already be linked");
       return i2;
     }
+    ValueNumberingEffects vne(vmap());
+    i1->visit(&vne);
   }
 
   if (i1->as_Phi() == NULL && i1->as_Local() == NULL) {
@@ -1926,14 +1909,8 @@
     assert(_last == i1, "adjust code below");
     StateSplit* s = i1->as_StateSplit();
     if (s != NULL && i1->as_BlockEnd() == NULL) {
-      // Continue CSE across certain intrinsics
-      Intrinsic* intrinsic = s->as_Intrinsic();
-      if (UseLocalValueNumbering) {
-        if (intrinsic == NULL || !intrinsic->preserves_state()) {
-          vmap()->kill_all();      // for now, hopefully we need this only for calls eventually
-          }
-      }
       if (EliminateFieldAccess) {
+        Intrinsic* intrinsic = s->as_Intrinsic();
         if (s->as_Invoke() != NULL || (intrinsic && !intrinsic->preserves_state())) {
           _memory->kill();
         }
--- a/hotspot/src/share/vm/c1/c1_GraphBuilder.hpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.hpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1999-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -283,8 +283,6 @@
   Dependencies* dependency_recorder() const; // = compilation()->dependencies()
   bool direct_compare(ciKlass* k);
 
-  void kill_field(ciField* field);
-  void kill_array(Value value);
   void kill_all();
 
   ValueStack* lock_stack();
--- a/hotspot/src/share/vm/c1/c1_IR.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/c1/c1_IR.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1999-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1210,8 +1210,8 @@
         break;
       case T_LONG:
       case T_DOUBLE:
-        if (c->as_jint_hi_bits() != other->as_jint_lo_bits()) continue;
-        if (c->as_jint_lo_bits() != other->as_jint_hi_bits()) continue;
+        if (c->as_jint_hi_bits() != other->as_jint_hi_bits()) continue;
+        if (c->as_jint_lo_bits() != other->as_jint_lo_bits()) continue;
         break;
       case T_OBJECT:
         if (c->as_jobject() != other->as_jobject()) continue;
--- a/hotspot/src/share/vm/c1/c1_Optimizer.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/c1/c1_Optimizer.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -327,8 +327,6 @@
                 BlockBegin* fsux = if_->fsux();
                 if (swapped) {
                   cond = Instruction::mirror(cond);
-                  tsux = if_->fsux();
-                  fsux = if_->tsux();
                 }
 
                 BlockBegin* tblock = tval->compare(cond, con, tsux, fsux);
--- a/hotspot/src/share/vm/c1/c1_Runtime1.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/c1/c1_Runtime1.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -842,6 +842,13 @@
     if (TracePatching) {
       tty->print_cr("Deoptimizing for patching volatile field reference");
     }
+    // It's possible the nmethod was invalidated in the last
+    // safepoint, but if it's still alive then make it not_entrant.
+    nmethod* nm = CodeCache::find_nmethod(caller_frame.pc());
+    if (nm != NULL) {
+      nm->make_not_entrant();
+    }
+
     VM_DeoptimizeFrame deopt(thread, caller_frame.id());
     VMThread::execute(&deopt);
 
--- a/hotspot/src/share/vm/c1/c1_ValueMap.hpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/c1/c1_ValueMap.hpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1999-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -133,53 +133,77 @@
   virtual void kill_array(ValueType* type) = 0;
 
   // visitor functions
-  void do_StoreField     (StoreField*      x) { kill_field(x->field()); };
-  void do_StoreIndexed   (StoreIndexed*    x) { kill_array(x->type()); };
-  void do_MonitorEnter   (MonitorEnter*    x) { kill_memory(); };
-  void do_MonitorExit    (MonitorExit*     x) { kill_memory(); };
-  void do_Invoke         (Invoke*          x) { kill_memory(); };
-  void do_UnsafePutRaw   (UnsafePutRaw*    x) { kill_memory(); };
-  void do_UnsafePutObject(UnsafePutObject* x) { kill_memory(); };
-  void do_Intrinsic      (Intrinsic*       x) { if (!x->preserves_state()) kill_memory(); };
+  void do_StoreField     (StoreField*      x) {
+    if (!x->is_initialized()) {
+      kill_memory();
+    } else {
+      kill_field(x->field());
+    }
+  }
+  void do_StoreIndexed   (StoreIndexed*    x) { kill_array(x->type()); }
+  void do_MonitorEnter   (MonitorEnter*    x) { kill_memory(); }
+  void do_MonitorExit    (MonitorExit*     x) { kill_memory(); }
+  void do_Invoke         (Invoke*          x) { kill_memory(); }
+  void do_UnsafePutRaw   (UnsafePutRaw*    x) { kill_memory(); }
+  void do_UnsafePutObject(UnsafePutObject* x) { kill_memory(); }
+  void do_Intrinsic      (Intrinsic*       x) { if (!x->preserves_state()) kill_memory(); }
 
-  void do_Phi            (Phi*             x) { /* nothing to do */ };
-  void do_Local          (Local*           x) { /* nothing to do */ };
-  void do_Constant       (Constant*        x) { /* nothing to do */ };
-  void do_LoadField      (LoadField*       x) { /* nothing to do */ };
-  void do_ArrayLength    (ArrayLength*     x) { /* nothing to do */ };
-  void do_LoadIndexed    (LoadIndexed*     x) { /* nothing to do */ };
-  void do_NegateOp       (NegateOp*        x) { /* nothing to do */ };
-  void do_ArithmeticOp   (ArithmeticOp*    x) { /* nothing to do */ };
-  void do_ShiftOp        (ShiftOp*         x) { /* nothing to do */ };
-  void do_LogicOp        (LogicOp*         x) { /* nothing to do */ };
-  void do_CompareOp      (CompareOp*       x) { /* nothing to do */ };
-  void do_IfOp           (IfOp*            x) { /* nothing to do */ };
-  void do_Convert        (Convert*         x) { /* nothing to do */ };
-  void do_NullCheck      (NullCheck*       x) { /* nothing to do */ };
-  void do_NewInstance    (NewInstance*     x) { /* nothing to do */ };
-  void do_NewTypeArray   (NewTypeArray*    x) { /* nothing to do */ };
-  void do_NewObjectArray (NewObjectArray*  x) { /* nothing to do */ };
-  void do_NewMultiArray  (NewMultiArray*   x) { /* nothing to do */ };
-  void do_CheckCast      (CheckCast*       x) { /* nothing to do */ };
-  void do_InstanceOf     (InstanceOf*      x) { /* nothing to do */ };
-  void do_BlockBegin     (BlockBegin*      x) { /* nothing to do */ };
-  void do_Goto           (Goto*            x) { /* nothing to do */ };
-  void do_If             (If*              x) { /* nothing to do */ };
-  void do_IfInstanceOf   (IfInstanceOf*    x) { /* nothing to do */ };
-  void do_TableSwitch    (TableSwitch*     x) { /* nothing to do */ };
-  void do_LookupSwitch   (LookupSwitch*    x) { /* nothing to do */ };
-  void do_Return         (Return*          x) { /* nothing to do */ };
-  void do_Throw          (Throw*           x) { /* nothing to do */ };
-  void do_Base           (Base*            x) { /* nothing to do */ };
-  void do_OsrEntry       (OsrEntry*        x) { /* nothing to do */ };
-  void do_ExceptionObject(ExceptionObject* x) { /* nothing to do */ };
-  void do_RoundFP        (RoundFP*         x) { /* nothing to do */ };
-  void do_UnsafeGetRaw   (UnsafeGetRaw*    x) { /* nothing to do */ };
-  void do_UnsafeGetObject(UnsafeGetObject* x) { /* nothing to do */ };
-  void do_UnsafePrefetchRead (UnsafePrefetchRead*  x) { /* nothing to do */ };
-  void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) { /* nothing to do */ };
-  void do_ProfileCall    (ProfileCall*     x) { /* nothing to do */ };
-  void do_ProfileCounter (ProfileCounter*  x) { /* nothing to do */ };
+  void do_Phi            (Phi*             x) { /* nothing to do */ }
+  void do_Local          (Local*           x) { /* nothing to do */ }
+  void do_Constant       (Constant*        x) { /* nothing to do */ }
+  void do_LoadField      (LoadField*       x) {
+    if (!x->is_initialized()) {
+      kill_memory();
+    }
+  }
+  void do_ArrayLength    (ArrayLength*     x) { /* nothing to do */ }
+  void do_LoadIndexed    (LoadIndexed*     x) { /* nothing to do */ }
+  void do_NegateOp       (NegateOp*        x) { /* nothing to do */ }
+  void do_ArithmeticOp   (ArithmeticOp*    x) { /* nothing to do */ }
+  void do_ShiftOp        (ShiftOp*         x) { /* nothing to do */ }
+  void do_LogicOp        (LogicOp*         x) { /* nothing to do */ }
+  void do_CompareOp      (CompareOp*       x) { /* nothing to do */ }
+  void do_IfOp           (IfOp*            x) { /* nothing to do */ }
+  void do_Convert        (Convert*         x) { /* nothing to do */ }
+  void do_NullCheck      (NullCheck*       x) { /* nothing to do */ }
+  void do_NewInstance    (NewInstance*     x) { /* nothing to do */ }
+  void do_NewTypeArray   (NewTypeArray*    x) { /* nothing to do */ }
+  void do_NewObjectArray (NewObjectArray*  x) { /* nothing to do */ }
+  void do_NewMultiArray  (NewMultiArray*   x) { /* nothing to do */ }
+  void do_CheckCast      (CheckCast*       x) { /* nothing to do */ }
+  void do_InstanceOf     (InstanceOf*      x) { /* nothing to do */ }
+  void do_BlockBegin     (BlockBegin*      x) { /* nothing to do */ }
+  void do_Goto           (Goto*            x) { /* nothing to do */ }
+  void do_If             (If*              x) { /* nothing to do */ }
+  void do_IfInstanceOf   (IfInstanceOf*    x) { /* nothing to do */ }
+  void do_TableSwitch    (TableSwitch*     x) { /* nothing to do */ }
+  void do_LookupSwitch   (LookupSwitch*    x) { /* nothing to do */ }
+  void do_Return         (Return*          x) { /* nothing to do */ }
+  void do_Throw          (Throw*           x) { /* nothing to do */ }
+  void do_Base           (Base*            x) { /* nothing to do */ }
+  void do_OsrEntry       (OsrEntry*        x) { /* nothing to do */ }
+  void do_ExceptionObject(ExceptionObject* x) { /* nothing to do */ }
+  void do_RoundFP        (RoundFP*         x) { /* nothing to do */ }
+  void do_UnsafeGetRaw   (UnsafeGetRaw*    x) { /* nothing to do */ }
+  void do_UnsafeGetObject(UnsafeGetObject* x) { /* nothing to do */ }
+  void do_UnsafePrefetchRead (UnsafePrefetchRead*  x) { /* nothing to do */ }
+  void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) { /* nothing to do */ }
+  void do_ProfileCall    (ProfileCall*     x) { /* nothing to do */ }
+  void do_ProfileCounter (ProfileCounter*  x) { /* nothing to do */ }
+};
+
+
+class ValueNumberingEffects: public ValueNumberingVisitor {
+ private:
+  ValueMap*     _map;
+
+ public:
+  // implementation for abstract methods of ValueNumberingVisitor
+  void          kill_memory()                    { _map->kill_memory(); }
+  void          kill_field(ciField* field)       { _map->kill_field(field); }
+  void          kill_array(ValueType* type)      { _map->kill_array(type); }
+
+  ValueNumberingEffects(ValueMap* map): _map(map) {}
 };
 
 
--- a/hotspot/src/share/vm/ci/ciEnv.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/ci/ciEnv.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1999-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/ci/ciTypeFlow.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/ci/ciTypeFlow.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2000-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -581,7 +581,8 @@
       interf = KlassHandle(THREAD, k);
       vmtimer->resume();
 
-      cp->klass_at_put(interface_index, interf()); // eagerly resolve
+      if (LinkWellKnownClasses)  // my super type is well known to me
+        cp->klass_at_put(interface_index, interf()); // eagerly resolve
     }
 
     if (!Klass::cast(interf())->is_interface()) {
@@ -2699,7 +2700,8 @@
                                                            CHECK_(nullHandle));
       KlassHandle kh (THREAD, k);
       super_klass = instanceKlassHandle(THREAD, kh());
-      cp->klass_at_put(super_class_index, super_klass()); // eagerly resolve
+      if (LinkWellKnownClasses)  // my super class is well known to me
+        cp->klass_at_put(super_class_index, super_klass()); // eagerly resolve
     }
     if (super_klass.not_null()) {
       if (super_klass->is_interface()) {
@@ -3128,7 +3130,8 @@
     this_klass->set_method_ordering(method_ordering());
     this_klass->set_initial_method_idnum(methods->length());
     this_klass->set_name(cp->klass_name_at(this_class_index));
-    cp->klass_at_put(this_class_index, this_klass()); // eagerly resolve
+    if (LinkWellKnownClasses)  // I am well known to myself
+      cp->klass_at_put(this_class_index, this_klass()); // eagerly resolve
     this_klass->set_protection_domain(protection_domain());
     this_klass->set_fields_annotations(fields_annotations());
     this_klass->set_methods_annotations(methods_annotations());
--- a/hotspot/src/share/vm/classfile/classFileParser.hpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/classfile/classFileParser.hpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsOopClosures.hpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsOopClosures.hpp	Thu Jan 08 16:34:58 2009 -0800
@@ -325,24 +325,30 @@
 // For objects in CMS generation, this closure marks
 // given objects (transitively) as being reachable/live.
 // This is currently used during the (weak) reference object
-// processing phase of the CMS final checkpoint step.
+// processing phase of the CMS final checkpoint step, as
+// well as during the concurrent precleaning of the discovered
+// reference lists.
 class CMSKeepAliveClosure: public OopClosure {
  private:
   CMSCollector* _collector;
   const MemRegion _span;
   CMSMarkStack* _mark_stack;
   CMSBitMap*    _bit_map;
+  bool          _concurrent_precleaning;
  protected:
   DO_OOP_WORK_DEFN
  public:
   CMSKeepAliveClosure(CMSCollector* collector, MemRegion span,
-                      CMSBitMap* bit_map, CMSMarkStack* mark_stack):
+                      CMSBitMap* bit_map, CMSMarkStack* mark_stack,
+                      bool cpc):
     _collector(collector),
     _span(span),
     _bit_map(bit_map),
-    _mark_stack(mark_stack) {
+    _mark_stack(mark_stack),
+    _concurrent_precleaning(cpc) {
     assert(!_span.is_empty(), "Empty span could spell trouble");
   }
+  bool    concurrent_precleaning() const { return _concurrent_precleaning; }
   virtual void do_oop(oop* p);
   virtual void do_oop(narrowOop* p);
   inline void do_oop_nv(oop* p)       { CMSKeepAliveClosure::do_oop_work(p); }
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -538,6 +538,7 @@
   _survivor_chunk_capacity(0), // -- ditto --
   _survivor_chunk_index(0),    // -- ditto --
   _ser_pmc_preclean_ovflw(0),
+  _ser_kac_preclean_ovflw(0),
   _ser_pmc_remark_ovflw(0),
   _par_pmc_remark_ovflw(0),
   _ser_kac_ovflw(0),
@@ -1960,6 +1961,7 @@
 
   ref_processor()->set_enqueuing_is_done(false);
   ref_processor()->enable_discovery();
+  ref_processor()->setup_policy(clear_all_soft_refs);
   // If an asynchronous collection finishes, the _modUnionTable is
   // all clear.  If we are assuming the collection from an asynchronous
   // collection, clear the _modUnionTable.
@@ -2383,6 +2385,9 @@
     Universe::verify(true);
   }
 
+  // Snapshot the soft reference policy to be used in this collection cycle.
+  ref_processor()->setup_policy(clear_all_soft_refs);
+
   bool init_mark_was_synchronous = false; // until proven otherwise
   while (_collectorState != Idling) {
     if (TraceCMSState) {
@@ -4388,10 +4393,10 @@
     CMSPrecleanRefsYieldClosure yield_cl(this);
     assert(rp->span().equals(_span), "Spans should be equal");
     CMSKeepAliveClosure keep_alive(this, _span, &_markBitMap,
-                                   &_markStack);
+                                   &_markStack, true /* preclean */);
     CMSDrainMarkingStackClosure complete_trace(this,
-                                  _span, &_markBitMap, &_markStack,
-                                  &keep_alive);
+                                   _span, &_markBitMap, &_markStack,
+                                   &keep_alive, true /* preclean */);
 
     // We don't want this step to interfere with a young
     // collection because we don't want to take CPU
@@ -4590,11 +4595,11 @@
     if (!dirtyRegion.is_empty()) {
       assert(numDirtyCards > 0, "consistency check");
       HeapWord* stop_point = NULL;
+      stopTimer();
+      CMSTokenSyncWithLocks ts(true, gen->freelistLock(),
+                               bitMapLock());
+      startTimer();
       {
-        stopTimer();
-        CMSTokenSyncWithLocks ts(true, gen->freelistLock(),
-                                 bitMapLock());
-        startTimer();
         verify_work_stacks_empty();
         verify_overflow_empty();
         sample_eden();
@@ -4611,10 +4616,6 @@
         assert((CMSPermGenPrecleaningEnabled && (gen == _permGen)) ||
                (_collectorState == AbortablePreclean && should_abort_preclean()),
                "Unparsable objects should only be in perm gen.");
-
-        stopTimer();
-        CMSTokenSyncWithLocks ts(true, bitMapLock());
-        startTimer();
         _modUnionTable.mark_range(MemRegion(stop_point, dirtyRegion.end()));
         if (should_abort_preclean()) {
           break; // out of preclean loop
@@ -4852,17 +4853,19 @@
   // recurrence of that condition.
   assert(_markStack.isEmpty(), "No grey objects");
   size_t ser_ovflw = _ser_pmc_remark_ovflw + _ser_pmc_preclean_ovflw +
-                     _ser_kac_ovflw;
+                     _ser_kac_ovflw        + _ser_kac_preclean_ovflw;
   if (ser_ovflw > 0) {
     if (PrintCMSStatistics != 0) {
       gclog_or_tty->print_cr("Marking stack overflow (benign) "
-        "(pmc_pc="SIZE_FORMAT", pmc_rm="SIZE_FORMAT", kac="SIZE_FORMAT")",
+        "(pmc_pc="SIZE_FORMAT", pmc_rm="SIZE_FORMAT", kac="SIZE_FORMAT
+        ", kac_preclean="SIZE_FORMAT")",
         _ser_pmc_preclean_ovflw, _ser_pmc_remark_ovflw,
-        _ser_kac_ovflw);
+        _ser_kac_ovflw, _ser_kac_preclean_ovflw);
     }
     _markStack.expand();
     _ser_pmc_remark_ovflw = 0;
     _ser_pmc_preclean_ovflw = 0;
+    _ser_kac_preclean_ovflw = 0;
     _ser_kac_ovflw = 0;
   }
   if (_par_pmc_remark_ovflw > 0 || _par_kac_ovflw > 0) {
@@ -5675,40 +5678,29 @@
 
   ResourceMark rm;
   HandleMark   hm;
-  ReferencePolicy* soft_ref_policy;
-
-  assert(!ref_processor()->enqueuing_is_done(), "Enqueuing should not be complete");
-  // Process weak references.
-  if (clear_all_soft_refs) {
-    soft_ref_policy = new AlwaysClearPolicy();
-  } else {
-#ifdef COMPILER2
-    soft_ref_policy = new LRUMaxHeapPolicy();
-#else
-    soft_ref_policy = new LRUCurrentHeapPolicy();
-#endif // COMPILER2
-  }
-  verify_work_stacks_empty();
 
   ReferenceProcessor* rp = ref_processor();
   assert(rp->span().equals(_span), "Spans should be equal");
+  assert(!rp->enqueuing_is_done(), "Enqueuing should not be complete");
+  // Process weak references.
+  rp->setup_policy(clear_all_soft_refs);
+  verify_work_stacks_empty();
+
   CMSKeepAliveClosure cmsKeepAliveClosure(this, _span, &_markBitMap,
-                                          &_markStack);
+                                          &_markStack, false /* !preclean */);
   CMSDrainMarkingStackClosure cmsDrainMarkingStackClosure(this,
                                 _span, &_markBitMap, &_markStack,
-                                &cmsKeepAliveClosure);
+                                &cmsKeepAliveClosure, false /* !preclean */);
   {
     TraceTime t("weak refs processing", PrintGCDetails, false, gclog_or_tty);
     if (rp->processing_is_mt()) {
       CMSRefProcTaskExecutor task_executor(*this);
-      rp->process_discovered_references(soft_ref_policy,
-                                        &_is_alive_closure,
+      rp->process_discovered_references(&_is_alive_closure,
                                         &cmsKeepAliveClosure,
                                         &cmsDrainMarkingStackClosure,
                                         &task_executor);
     } else {
-      rp->process_discovered_references(soft_ref_policy,
-                                        &_is_alive_closure,
+      rp->process_discovered_references(&_is_alive_closure,
                                         &cmsKeepAliveClosure,
                                         &cmsDrainMarkingStackClosure,
                                         NULL);
@@ -6163,8 +6155,8 @@
 #endif
 
 size_t CMSCollector::block_size_using_printezis_bits(HeapWord* addr) const {
-  assert(_markBitMap.isMarked(addr) && _markBitMap.isMarked(addr + 1),
-         "missing Printezis mark?");
+   assert(_markBitMap.isMarked(addr) && _markBitMap.isMarked(addr + 1),
+          "missing Printezis mark?");
   HeapWord* nextOneAddr = _markBitMap.getNextMarkedWordAddress(addr + 2);
   size_t size = pointer_delta(nextOneAddr + 1, addr);
   assert(size == CompactibleFreeListSpace::adjustObjectSize(size),
@@ -8302,8 +8294,29 @@
       }
     )
     if (simulate_overflow || !_mark_stack->push(obj)) {
-      _collector->push_on_overflow_list(obj);
-      _collector->_ser_kac_ovflw++;
+      if (_concurrent_precleaning) {
+        // We dirty the overflown object and let the remark
+        // phase deal with it.
+        assert(_collector->overflow_list_is_empty(), "Error");
+        // In the case of object arrays, we need to dirty all of
+        // the cards that the object spans. No locking or atomics
+        // are needed since no one else can be mutating the mod union
+        // table.
+        if (obj->is_objArray()) {
+          size_t sz = obj->size();
+          HeapWord* end_card_addr =
+            (HeapWord*)round_to((intptr_t)(addr+sz), CardTableModRefBS::card_size);
+          MemRegion redirty_range = MemRegion(addr, end_card_addr);
+          assert(!redirty_range.is_empty(), "Arithmetical tautology");
+          _collector->_modUnionTable.mark_range(redirty_range);
+        } else {
+          _collector->_modUnionTable.mark(addr);
+        }
+        _collector->_ser_kac_preclean_ovflw++;
+      } else {
+        _collector->push_on_overflow_list(obj);
+        _collector->_ser_kac_ovflw++;
+      }
     }
   }
 }
@@ -8400,6 +8413,8 @@
 void CMSDrainMarkingStackClosure::do_void() {
   // the max number to take from overflow list at a time
   const size_t num = _mark_stack->capacity()/4;
+  assert(!_concurrent_precleaning || _collector->overflow_list_is_empty(),
+         "Overflow list should be NULL during concurrent phases");
   while (!_mark_stack->isEmpty() ||
          // if stack is empty, check the overflow list
          _collector->take_from_overflow_list(num, _mark_stack)) {
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp	Thu Jan 08 16:34:58 2009 -0800
@@ -592,6 +592,7 @@
   size_t        _ser_pmc_preclean_ovflw;
   size_t        _ser_pmc_remark_ovflw;
   size_t        _par_pmc_remark_ovflw;
+  size_t        _ser_kac_preclean_ovflw;
   size_t        _ser_kac_ovflw;
   size_t        _par_kac_ovflw;
   NOT_PRODUCT(size_t _num_par_pushes;)
@@ -1749,21 +1750,30 @@
 // work-routine/closure used to complete transitive
 // marking of objects as live after a certain point
 // in which an initial set has been completely accumulated.
+// This closure is currently used both during the final
+// remark stop-world phase, as well as during the concurrent
+// precleaning of the discovered reference lists.
 class CMSDrainMarkingStackClosure: public VoidClosure {
   CMSCollector*        _collector;
   MemRegion            _span;
   CMSMarkStack*        _mark_stack;
   CMSBitMap*           _bit_map;
   CMSKeepAliveClosure* _keep_alive;
+  bool                 _concurrent_precleaning;
  public:
   CMSDrainMarkingStackClosure(CMSCollector* collector, MemRegion span,
                       CMSBitMap* bit_map, CMSMarkStack* mark_stack,
-                      CMSKeepAliveClosure* keep_alive):
+                      CMSKeepAliveClosure* keep_alive,
+                      bool cpc):
     _collector(collector),
     _span(span),
     _bit_map(bit_map),
     _mark_stack(mark_stack),
-    _keep_alive(keep_alive) { }
+    _keep_alive(keep_alive),
+    _concurrent_precleaning(cpc) {
+    assert(_concurrent_precleaning == _keep_alive->concurrent_precleaning(),
+           "Mismatch");
+  }
 
   void do_void();
 };
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2001-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -811,6 +811,7 @@
   ReferenceProcessor* rp = g1h->ref_processor();
   rp->verify_no_references_recorded();
   rp->enable_discovery(); // enable ("weak") refs discovery
+  rp->setup_policy(false); // snapshot the soft ref policy to be used in this cycle
 
   SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set();
   satb_mq_set.set_process_completed_threshold(G1SATBProcessCompletedThreshold);
@@ -1829,32 +1830,21 @@
 void ConcurrentMark::weakRefsWork(bool clear_all_soft_refs) {
   ResourceMark rm;
   HandleMark   hm;
-  ReferencePolicy* soft_ref_policy;
+  G1CollectedHeap* g1h   = G1CollectedHeap::heap();
+  ReferenceProcessor* rp = g1h->ref_processor();
 
   // Process weak references.
-  if (clear_all_soft_refs) {
-    soft_ref_policy = new AlwaysClearPolicy();
-  } else {
-#ifdef COMPILER2
-    soft_ref_policy = new LRUMaxHeapPolicy();
-#else
-    soft_ref_policy = new LRUCurrentHeapPolicy();
-#endif
-  }
+  rp->setup_policy(clear_all_soft_refs);
   assert(_markStack.isEmpty(), "mark stack should be empty");
 
-  G1CollectedHeap* g1 = G1CollectedHeap::heap();
-  G1CMIsAliveClosure g1IsAliveClosure(g1);
-
-  G1CMKeepAliveClosure g1KeepAliveClosure(g1, this, nextMarkBitMap());
+  G1CMIsAliveClosure   g1IsAliveClosure  (g1h);
+  G1CMKeepAliveClosure g1KeepAliveClosure(g1h, this, nextMarkBitMap());
   G1CMDrainMarkingStackClosure
     g1DrainMarkingStackClosure(nextMarkBitMap(), &_markStack,
                                &g1KeepAliveClosure);
 
   // XXXYYY  Also: copy the parallel ref processing code from CMS.
-  ReferenceProcessor* rp = g1->ref_processor();
-  rp->process_discovered_references(soft_ref_policy,
-                                    &g1IsAliveClosure,
+  rp->process_discovered_references(&g1IsAliveClosure,
                                     &g1KeepAliveClosure,
                                     &g1DrainMarkingStackClosure,
                                     NULL);
--- a/hotspot/src/share/vm/gc_implementation/g1/dirtyCardQueue.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/dirtyCardQueue.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2001-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2001-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2001-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -891,6 +891,7 @@
     ReferenceProcessorIsAliveMutator rp_is_alive_null(ref_processor(), NULL);
 
     ref_processor()->enable_discovery();
+    ref_processor()->setup_policy(clear_all_soft_refs);
 
     // Do collection work
     {
@@ -2463,7 +2464,7 @@
 
     COMPILER2_PRESENT(DerivedPointerTable::clear());
 
-    // We want to turn off ref discovere, if necessary, and turn it back on
+    // We want to turn off ref discovery, if necessary, and turn it back on
     // on again later if we do.
     bool was_enabled = ref_processor()->discovery_enabled();
     if (was_enabled) ref_processor()->disable_discovery();
@@ -2953,7 +2954,7 @@
       // The object has been either evacuated or is dead. Fill it with a
       // dummy object.
       MemRegion mr((HeapWord*)obj, obj->size());
-      SharedHeap::fill_region_with_object(mr);
+      CollectedHeap::fill_with_object(mr);
       _cm->clearRangeBothMaps(mr);
     }
   }
@@ -3224,7 +3225,7 @@
     // Otherwise, try to claim it.
     block = r->par_allocate(free_words);
   } while (block == NULL);
-  SharedHeap::fill_region_with_object(MemRegion(block, free_words));
+  fill_with_object(block, free_words);
 }
 
 #define use_local_bitmaps         1
@@ -3618,9 +3619,8 @@
       guarantee(alloc_buffer(purpose)->contains(obj + word_sz - 1),
                 "should contain whole object");
       alloc_buffer(purpose)->undo_allocation(obj, word_sz);
-    }
-    else {
-      SharedHeap::fill_region_with_object(MemRegion(obj, word_sz));
+    } else {
+      CollectedHeap::fill_with_object(obj, word_sz);
       add_to_undo_waste(word_sz);
     }
   }
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2001-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2001-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2001-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,8 +33,9 @@
 
   // hook up weak ref data so it can be used during Mark-Sweep
   assert(GenMarkSweep::ref_processor() == NULL, "no stomping");
+  assert(rp != NULL, "should be non-NULL");
   GenMarkSweep::_ref_processor = rp;
-  assert(rp != NULL, "should be non-NULL");
+  rp->setup_policy(clear_all_softrefs);
 
   // When collecting the permanent generation methodOops may be moving,
   // so we either have to flush all bcp data or convert it into bci.
@@ -121,23 +122,12 @@
                            &GenMarkSweep::follow_root_closure);
 
   // Process reference objects found during marking
-  ReferencePolicy *soft_ref_policy;
-  if (clear_all_softrefs) {
-    soft_ref_policy = new AlwaysClearPolicy();
-  } else {
-#ifdef COMPILER2
-    soft_ref_policy = new LRUMaxHeapPolicy();
-#else
-    soft_ref_policy = new LRUCurrentHeapPolicy();
-#endif
-  }
-  assert(soft_ref_policy != NULL,"No soft reference policy");
-  GenMarkSweep::ref_processor()->process_discovered_references(
-                                   soft_ref_policy,
-                                   &GenMarkSweep::is_alive,
-                                   &GenMarkSweep::keep_alive,
-                                   &GenMarkSweep::follow_stack_closure,
-                                   NULL);
+  ReferenceProcessor* rp = GenMarkSweep::ref_processor();
+  rp->setup_policy(clear_all_softrefs);
+  rp->process_discovered_references(&GenMarkSweep::is_alive,
+                                    &GenMarkSweep::keep_alive,
+                                    &GenMarkSweep::follow_stack_closure,
+                                    NULL);
 
   // Follow system dictionary roots and unload classes
   bool purged_class = SystemDictionary::do_unloading(&GenMarkSweep::is_alive);
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2001-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2001-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -181,7 +181,7 @@
 
   void scrub(CardTableModRefBS* ctbs, BitMap* card_bm) {
     HeapWord* hr_bot = hr()->bottom();
-    int hr_first_card_index = ctbs->index_for(hr_bot);
+    size_t hr_first_card_index = ctbs->index_for(hr_bot);
     bm()->set_intersection_at_offset(*card_bm, hr_first_card_index);
 #if PRT_COUNT_OCCUPIED
     recount_occupied();
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2001-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -102,7 +102,7 @@
       HeapWord* tmp = hr->allocate(sz);
       assert(tmp != NULL, "Humongous allocation failure");
       MemRegion mr = MemRegion(tmp, sz);
-      SharedHeap::fill_region_with_object(mr);
+      CollectedHeap::fill_with_object(mr);
       hr->declare_filled_region_to_BOT(mr);
       if (i == first) {
         first_hr->set_startsHumongous();
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.hpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.hpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2001-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/gc_implementation/g1/ptrQueue.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/ptrQueue.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2001-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/gc_implementation/g1/ptrQueue.hpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/ptrQueue.hpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2001-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/gc_implementation/includeDB_gc_g1	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/includeDB_gc_g1	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 //
-// Copyright 2004-2006 Sun Microsystems, Inc.  All Rights Reserved.
+// Copyright 2004-2008 Sun Microsystems, Inc.  All Rights Reserved.
 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 //
 // This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/gc_implementation/parNew/parGCAllocBuffer.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/parNew/parGCAllocBuffer.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -51,14 +51,14 @@
   if (_retained) {
     // If the buffer had been retained shorten the previous filler object.
     assert(_retained_filler.end() <= _top, "INVARIANT");
-    SharedHeap::fill_region_with_object(_retained_filler);
+    CollectedHeap::fill_with_object(_retained_filler);
     // Wasted space book-keeping, otherwise (normally) done in invalidate()
     _wasted += _retained_filler.word_size();
     _retained = false;
   }
   assert(!end_of_gc || !_retained, "At this point, end_of_gc ==> !_retained.");
   if (_top < _hard_end) {
-    SharedHeap::fill_region_with_object(MemRegion(_top, _hard_end));
+    CollectedHeap::fill_with_object(_top, _hard_end);
     if (!retain) {
       invalidate();
     } else {
@@ -155,7 +155,7 @@
 // modifying the _next_threshold state in the BOT.
 void ParGCAllocBufferWithBOT::fill_region_with_block(MemRegion mr,
                                                      bool contig) {
-  SharedHeap::fill_region_with_object(mr);
+  CollectedHeap::fill_with_object(mr);
   if (contig) {
     _bt.alloc_block(mr.start(), mr.end());
   } else {
@@ -171,7 +171,7 @@
            "or else _true_end should be equal to _hard_end");
     assert(_retained, "or else _true_end should be equal to _hard_end");
     assert(_retained_filler.end() <= _top, "INVARIANT");
-    SharedHeap::fill_region_with_object(_retained_filler);
+    CollectedHeap::fill_with_object(_retained_filler);
     if (_top < _hard_end) {
       fill_region_with_block(MemRegion(_top, _hard_end), true);
     }
@@ -316,11 +316,9 @@
         while (_top <= chunk_boundary) {
           assert(pointer_delta(_hard_end, chunk_boundary) >= AlignmentReserve,
                  "Consequence of last card handling above.");
-          MemRegion chunk_portion(chunk_boundary, _hard_end);
-          _bt.BlockOffsetArray::alloc_block(chunk_portion.start(),
-                                            chunk_portion.end());
-          SharedHeap::fill_region_with_object(chunk_portion);
-          _hard_end = chunk_portion.start();
+          _bt.BlockOffsetArray::alloc_block(chunk_boundary, _hard_end);
+          CollectedHeap::fill_with_object(chunk_boundary, _hard_end);
+          _hard_end = chunk_boundary;
           chunk_boundary -= ChunkSizeInWords;
         }
         _end = _hard_end - AlignmentReserve;
--- a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -201,7 +201,7 @@
            "Should contain whole object.");
     to_space_alloc_buffer()->undo_allocation(obj, word_sz);
   } else {
-    SharedHeap::fill_region_with_object(MemRegion(obj, word_sz));
+    CollectedHeap::fill_with_object(obj, word_sz);
   }
 }
 
@@ -759,17 +759,12 @@
                thread_state_set.steals(),
                thread_state_set.pops()+thread_state_set.steals());
   }
-  assert(thread_state_set.pushes() == thread_state_set.pops() + thread_state_set.steals(),
+  assert(thread_state_set.pushes() == thread_state_set.pops()
+                                    + thread_state_set.steals(),
          "Or else the queues are leaky.");
 
-  // For now, process discovered weak refs sequentially.
-#ifdef COMPILER2
-  ReferencePolicy *soft_ref_policy = new LRUMaxHeapPolicy();
-#else
-  ReferencePolicy *soft_ref_policy = new LRUCurrentHeapPolicy();
-#endif // COMPILER2
-
   // Process (weak) reference objects found during scavenge.
+  ReferenceProcessor* rp = ref_processor();
   IsAliveClosure is_alive(this);
   ScanWeakRefClosure scan_weak_ref(this);
   KeepAliveClosure keep_alive(&scan_weak_ref);
@@ -778,18 +773,17 @@
   set_promo_failure_scan_stack_closure(&scan_without_gc_barrier);
   EvacuateFollowersClosureGeneral evacuate_followers(gch, _level,
     &scan_without_gc_barrier, &scan_with_gc_barrier);
-  if (ref_processor()->processing_is_mt()) {
+  rp->setup_policy(clear_all_soft_refs);
+  if (rp->processing_is_mt()) {
     ParNewRefProcTaskExecutor task_executor(*this, thread_state_set);
-    ref_processor()->process_discovered_references(
-        soft_ref_policy, &is_alive, &keep_alive, &evacuate_followers,
-        &task_executor);
+    rp->process_discovered_references(&is_alive, &keep_alive,
+                                      &evacuate_followers, &task_executor);
   } else {
     thread_state_set.flush();
     gch->set_par_threads(0);  // 0 ==> non-parallel.
     gch->save_marks();
-    ref_processor()->process_discovered_references(
-      soft_ref_policy, &is_alive, &keep_alive, &evacuate_followers,
-      NULL);
+    rp->process_discovered_references(&is_alive, &keep_alive,
+                                      &evacuate_followers, NULL);
   }
   if (!promotion_failed()) {
     // Swap the survivor spaces.
@@ -851,14 +845,14 @@
 
   SpecializationStats::print();
 
-  ref_processor()->set_enqueuing_is_done(true);
-  if (ref_processor()->processing_is_mt()) {
+  rp->set_enqueuing_is_done(true);
+  if (rp->processing_is_mt()) {
     ParNewRefProcTaskExecutor task_executor(*this, thread_state_set);
-    ref_processor()->enqueue_discovered_references(&task_executor);
+    rp->enqueue_discovered_references(&task_executor);
   } else {
-    ref_processor()->enqueue_discovered_references(NULL);
+    rp->enqueue_discovered_references(NULL);
   }
-  ref_processor()->verify_no_references_recorded();
+  rp->verify_no_references_recorded();
 }
 
 static int sum;
@@ -1211,7 +1205,7 @@
   int n = 0;
   while (cur != NULL) {
     oop obj_to_push = cur->forwardee();
-    oop next        = oop(cur->klass());
+    oop next        = oop(cur->klass_or_null());
     cur->set_klass(obj_to_push->klass());
     if (par_scan_state->should_be_partially_scanned(obj_to_push, cur)) {
       obj_to_push = cur;
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.hpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.hpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2005-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2005-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.hpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.hpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2005-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -172,6 +172,7 @@
     COMPILER2_PRESENT(DerivedPointerTable::clear());
 
     ref_processor()->enable_discovery();
+    ref_processor()->setup_policy(clear_all_softrefs);
 
     mark_sweep_phase1(clear_all_softrefs);
 
@@ -388,7 +389,7 @@
   // full GC.
   const size_t alignment = old_gen->virtual_space()->alignment();
   const size_t eden_used = eden_space->used_in_bytes();
-  const size_t promoted = (size_t)(size_policy->avg_promoted()->padded_average());
+  const size_t promoted = (size_t)size_policy->avg_promoted()->padded_average();
   const size_t absorb_size = align_size_up(eden_used + promoted, alignment);
   const size_t eden_capacity = eden_space->capacity_in_bytes();
 
@@ -415,16 +416,14 @@
 
   // Fill the unused part of the old gen.
   MutableSpace* const old_space = old_gen->object_space();
-  MemRegion old_gen_unused(old_space->top(), old_space->end());
+  HeapWord* const unused_start = old_space->top();
+  size_t const unused_words = pointer_delta(old_space->end(), unused_start);
 
-  // If the unused part of the old gen cannot be filled, skip
-  // absorbing eden.
-  if (old_gen_unused.word_size() < SharedHeap::min_fill_size()) {
-    return false;
-  }
-
-  if (!old_gen_unused.is_empty()) {
-    SharedHeap::fill_region_with_object(old_gen_unused);
+  if (unused_words > 0) {
+    if (unused_words < CollectedHeap::min_fill_size()) {
+      return false;  // If the old gen cannot be filled, must give up.
+    }
+    CollectedHeap::fill_with_objects(unused_start, unused_words);
   }
 
   // Take the live data from eden and set both top and end in the old gen to
@@ -440,9 +439,8 @@
 
   // Update the object start array for the filler object and the data from eden.
   ObjectStartArray* const start_array = old_gen->start_array();
-  HeapWord* const start = old_gen_unused.start();
-  for (HeapWord* addr = start; addr < new_top; addr += oop(addr)->size()) {
-    start_array->allocate_block(addr);
+  for (HeapWord* p = unused_start; p < new_top; p += oop(p)->size()) {
+    start_array->allocate_block(p);
   }
 
   // Could update the promoted average here, but it is not typically updated at
@@ -517,20 +515,9 @@
 
   // Process reference objects found during marking
   {
-    ReferencePolicy *soft_ref_policy;
-    if (clear_all_softrefs) {
-      soft_ref_policy = new AlwaysClearPolicy();
-    } else {
-#ifdef COMPILER2
-      soft_ref_policy = new LRUMaxHeapPolicy();
-#else
-      soft_ref_policy = new LRUCurrentHeapPolicy();
-#endif // COMPILER2
-    }
-    assert(soft_ref_policy != NULL,"No soft reference policy");
+    ref_processor()->setup_policy(clear_all_softrefs);
     ref_processor()->process_discovered_references(
-      soft_ref_policy, is_alive_closure(), mark_and_push_closure(),
-      follow_stack_closure(), NULL);
+      is_alive_closure(), mark_and_push_closure(), follow_stack_closure(), NULL);
   }
 
   // Follow system dictionary roots and unload classes
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -275,22 +275,9 @@
                                             HeapWord* q, size_t deadlength) {
   if (allowed_deadspace_words >= deadlength) {
     allowed_deadspace_words -= deadlength;
-    oop(q)->set_mark(markOopDesc::prototype()->set_marked());
-    const size_t aligned_min_int_array_size =
-      align_object_size(typeArrayOopDesc::header_size(T_INT));
-    if (deadlength >= aligned_min_int_array_size) {
-      oop(q)->set_klass(Universe::intArrayKlassObj());
-      assert(((deadlength - aligned_min_int_array_size) * (HeapWordSize/sizeof(jint))) < (size_t)max_jint,
-                "deadspace too big for Arrayoop");
-      typeArrayOop(q)->set_length((int)((deadlength - aligned_min_int_array_size)
-                                            * (HeapWordSize/sizeof(jint))));
-    } else {
-      assert((int) deadlength == instanceOopDesc::header_size(),
-             "size for smallest fake dead object doesn't match");
-      oop(q)->set_klass(SystemDictionary::object_klass());
-    }
-    assert((int) deadlength == oop(q)->size(),
-           "make sure size for fake dead object match");
+    CollectedHeap::fill_with_object(q, deadlength);
+    oop(q)->set_mark(oop(q)->mark()->set_marked());
+    assert((int) deadlength == oop(q)->size(), "bad filler object size");
     // Recall that we required "q == compaction_top".
     return true;
   } else {
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.hpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.hpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2002 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2001-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -88,6 +88,72 @@
 GrowableArray<size_t>   * PSParallelCompact::_last_gc_live_oops_size = NULL;
 #endif
 
+void SplitInfo::record(size_t src_region_idx, size_t partial_obj_size,
+                       HeapWord* destination)
+{
+  assert(src_region_idx != 0, "invalid src_region_idx");
+  assert(partial_obj_size != 0, "invalid partial_obj_size argument");
+  assert(destination != NULL, "invalid destination argument");
+
+  _src_region_idx = src_region_idx;
+  _partial_obj_size = partial_obj_size;
+  _destination = destination;
+
+  // These fields may not be updated below, so make sure they're clear.
+  assert(_dest_region_addr == NULL, "should have been cleared");
+  assert(_first_src_addr == NULL, "should have been cleared");
+
+  // Determine the number of destination regions for the partial object.
+  HeapWord* const last_word = destination + partial_obj_size - 1;
+  const ParallelCompactData& sd = PSParallelCompact::summary_data();
+  HeapWord* const beg_region_addr = sd.region_align_down(destination);
+  HeapWord* const end_region_addr = sd.region_align_down(last_word);
+
+  if (beg_region_addr == end_region_addr) {
+    // One destination region.
+    _destination_count = 1;
+    if (end_region_addr == destination) {
+      // The destination falls on a region boundary, thus the first word of the
+      // partial object will be the first word copied to the destination region.
+      _dest_region_addr = end_region_addr;
+      _first_src_addr = sd.region_to_addr(src_region_idx);
+    }
+  } else {
+    // Two destination regions.  When copied, the partial object will cross a
+    // destination region boundary, so a word somewhere within the partial
+    // object will be the first word copied to the second destination region.
+    _destination_count = 2;
+    _dest_region_addr = end_region_addr;
+    const size_t ofs = pointer_delta(end_region_addr, destination);
+    assert(ofs < _partial_obj_size, "sanity");
+    _first_src_addr = sd.region_to_addr(src_region_idx) + ofs;
+  }
+}
+
+void SplitInfo::clear()
+{
+  _src_region_idx = 0;
+  _partial_obj_size = 0;
+  _destination = NULL;
+  _destination_count = 0;
+  _dest_region_addr = NULL;
+  _first_src_addr = NULL;
+  assert(!is_valid(), "sanity");
+}
+
+#ifdef  ASSERT
+void SplitInfo::verify_clear()
+{
+  assert(_src_region_idx == 0, "not clear");
+  assert(_partial_obj_size == 0, "not clear");
+  assert(_destination == NULL, "not clear");
+  assert(_destination_count == 0, "not clear");
+  assert(_dest_region_addr == NULL, "not clear");
+  assert(_first_src_addr == NULL, "not clear");
+}
+#endif  // #ifdef ASSERT
+
+
 #ifndef PRODUCT
 const char* PSParallelCompact::space_names[] = {
   "perm", "old ", "eden", "from", "to  "
@@ -416,21 +482,134 @@
   }
 }
 
-bool ParallelCompactData::summarize(HeapWord* target_beg, HeapWord* target_end,
+// Find the point at which a space can be split and, if necessary, record the
+// split point.
+//
+// If the current src region (which overflowed the destination space) doesn't
+// have a partial object, the split point is at the beginning of the current src
+// region (an "easy" split, no extra bookkeeping required).
+//
+// If the current src region has a partial object, the split point is in the
+// region where that partial object starts (call it the split_region).  If
+// split_region has a partial object, then the split point is just after that
+// partial object (a "hard" split where we have to record the split data and
+// zero the partial_obj_size field).  With a "hard" split, we know that the
+// partial_obj ends within split_region because the partial object that caused
+// the overflow starts in split_region.  If split_region doesn't have a partial
+// obj, then the split is at the beginning of split_region (another "easy"
+// split).
+HeapWord*
+ParallelCompactData::summarize_split_space(size_t src_region,
+                                           SplitInfo& split_info,
+                                           HeapWord* destination,
+                                           HeapWord* target_end,
+                                           HeapWord** target_next)
+{
+  assert(destination <= target_end, "sanity");
+  assert(destination + _region_data[src_region].data_size() > target_end,
+    "region should not fit into target space");
+
+  size_t split_region = src_region;
+  HeapWord* split_destination = destination;
+  size_t partial_obj_size = _region_data[src_region].partial_obj_size();
+
+  if (destination + partial_obj_size > target_end) {
+    // The split point is just after the partial object (if any) in the
+    // src_region that contains the start of the object that overflowed the
+    // destination space.
+    //
+    // Find the start of the "overflow" object and set split_region to the
+    // region containing it.
+    HeapWord* const overflow_obj = _region_data[src_region].partial_obj_addr();
+    split_region = addr_to_region_idx(overflow_obj);
+
+    // Clear the source_region field of all destination regions whose first word
+    // came from data after the split point (a non-null source_region field
+    // implies a region must be filled).
+    //
+    // An alternative to the simple loop below:  clear during post_compact(),
+    // which uses memcpy instead of individual stores, and is easy to
+    // parallelize.  (The downside is that it clears the entire RegionData
+    // object as opposed to just one field.)
+    //
+    // post_compact() would have to clear the summary data up to the highest
+    // address that was written during the summary phase, which would be
+    //
+    //         max(top, max(new_top, clear_top))
+    //
+    // where clear_top is a new field in SpaceInfo.  Would have to set clear_top
+    // to destination + partial_obj_size, where both have the values passed to
+    // this routine.
+    const RegionData* const sr = region(split_region);
+    const size_t beg_idx =
+      addr_to_region_idx(region_align_up(sr->destination() +
+                                         sr->partial_obj_size()));
+    const size_t end_idx =
+      addr_to_region_idx(region_align_up(destination + partial_obj_size));
+
+    if (TraceParallelOldGCSummaryPhase) {
+        gclog_or_tty->print_cr("split:  clearing source_region field in ["
+                               SIZE_FORMAT ", " SIZE_FORMAT ")",
+                               beg_idx, end_idx);
+    }
+    for (size_t idx = beg_idx; idx < end_idx; ++idx) {
+      _region_data[idx].set_source_region(0);
+    }
+
+    // Set split_destination and partial_obj_size to reflect the split region.
+    split_destination = sr->destination();
+    partial_obj_size = sr->partial_obj_size();
+  }
+
+  // The split is recorded only if a partial object extends onto the region.
+  if (partial_obj_size != 0) {
+    _region_data[split_region].set_partial_obj_size(0);
+    split_info.record(split_region, partial_obj_size, split_destination);
+  }
+
+  // Setup the continuation addresses.
+  *target_next = split_destination + partial_obj_size;
+  HeapWord* const source_next = region_to_addr(split_region) + partial_obj_size;
+
+  if (TraceParallelOldGCSummaryPhase) {
+    const char * split_type = partial_obj_size == 0 ? "easy" : "hard";
+    gclog_or_tty->print_cr("%s split:  src=" PTR_FORMAT " src_c=" SIZE_FORMAT
+                           " pos=" SIZE_FORMAT,
+                           split_type, source_next, split_region,
+                           partial_obj_size);
+    gclog_or_tty->print_cr("%s split:  dst=" PTR_FORMAT " dst_c=" SIZE_FORMAT
+                           " tn=" PTR_FORMAT,
+                           split_type, split_destination,
+                           addr_to_region_idx(split_destination),
+                           *target_next);
+
+    if (partial_obj_size != 0) {
+      HeapWord* const po_beg = split_info.destination();
+      HeapWord* const po_end = po_beg + split_info.partial_obj_size();
+      gclog_or_tty->print_cr("%s split:  "
+                             "po_beg=" PTR_FORMAT " " SIZE_FORMAT " "
+                             "po_end=" PTR_FORMAT " " SIZE_FORMAT,
+                             split_type,
+                             po_beg, addr_to_region_idx(po_beg),
+                             po_end, addr_to_region_idx(po_end));
+    }
+  }
+
+  return source_next;
+}
+
+bool ParallelCompactData::summarize(SplitInfo& split_info,
                                     HeapWord* source_beg, HeapWord* source_end,
-                                    HeapWord** target_next,
-                                    HeapWord** source_next) {
-  // This is too strict.
-  // assert(region_offset(source_beg) == 0, "not RegionSize aligned");
-
+                                    HeapWord** source_next,
+                                    HeapWord* target_beg, HeapWord* target_end,
+                                    HeapWord** target_next)
+{
   if (TraceParallelOldGCSummaryPhase) {
-    tty->print_cr("tb=" PTR_FORMAT " te=" PTR_FORMAT " "
-                  "sb=" PTR_FORMAT " se=" PTR_FORMAT " "
-                  "tn=" PTR_FORMAT " sn=" PTR_FORMAT,
-                  target_beg, target_end,
-                  source_beg, source_end,
-                  target_next != 0 ? *target_next : (HeapWord*) 0,
-                  source_next != 0 ? *source_next : (HeapWord*) 0);
+    HeapWord* const source_next_val = source_next == NULL ? NULL : *source_next;
+    tty->print_cr("sb=" PTR_FORMAT " se=" PTR_FORMAT " sn=" PTR_FORMAT
+                  "tb=" PTR_FORMAT " te=" PTR_FORMAT " tn=" PTR_FORMAT,
+                  source_beg, source_end, source_next_val,
+                  target_beg, target_end, *target_next);
   }
 
   size_t cur_region = addr_to_region_idx(source_beg);
@@ -438,45 +617,53 @@
 
   HeapWord *dest_addr = target_beg;
   while (cur_region < end_region) {
+    // The destination must be set even if the region has no data.
+    _region_data[cur_region].set_destination(dest_addr);
+
     size_t words = _region_data[cur_region].data_size();
-
-#if     1
-    assert(pointer_delta(target_end, dest_addr) >= words,
-           "source region does not fit into target region");
-#else
-    // XXX - need some work on the corner cases here.  If the region does not
-    // fit, then must either make sure any partial_obj from the region fits, or
-    // "undo" the initial part of the partial_obj that is in the previous
-    // region.
-    if (dest_addr + words >= target_end) {
-      // Let the caller know where to continue.
-      *target_next = dest_addr;
-      *source_next = region_to_addr(cur_region);
-      return false;
-    }
-#endif  // #if 1
-
-    _region_data[cur_region].set_destination(dest_addr);
-
-    // Set the destination_count for cur_region, and if necessary, update
-    // source_region for a destination region.  The source_region field is
-    // updated if cur_region is the first (left-most) region to be copied to a
-    // destination region.
-    //
-    // The destination_count calculation is a bit subtle.  A region that has
-    // data that compacts into itself does not count itself as a destination.
-    // This maintains the invariant that a zero count means the region is
-    // available and can be claimed and then filled.
     if (words > 0) {
+      // If cur_region does not fit entirely into the target space, find a point
+      // at which the source space can be 'split' so that part is copied to the
+      // target space and the rest is copied elsewhere.
+      if (dest_addr + words > target_end) {
+        assert(source_next != NULL, "source_next is NULL when splitting");
+        *source_next = summarize_split_space(cur_region, split_info, dest_addr,
+                                             target_end, target_next);
+        return false;
+      }
+
+      // Compute the destination_count for cur_region, and if necessary, update
+      // source_region for a destination region.  The source_region field is
+      // updated if cur_region is the first (left-most) region to be copied to a
+      // destination region.
+      //
+      // The destination_count calculation is a bit subtle.  A region that has
+      // data that compacts into itself does not count itself as a destination.
+      // This maintains the invariant that a zero count means the region is
+      // available and can be claimed and then filled.
+      uint destination_count = 0;
+      if (split_info.is_split(cur_region)) {
+        // The current region has been split:  the partial object will be copied
+        // to one destination space and the remaining data will be copied to
+        // another destination space.  Adjust the initial destination_count and,
+        // if necessary, set the source_region field if the partial object will
+        // cross a destination region boundary.
+        destination_count = split_info.destination_count();
+        if (destination_count == 2) {
+          size_t dest_idx = addr_to_region_idx(split_info.dest_region_addr());
+          _region_data[dest_idx].set_source_region(cur_region);
+        }
+      }
+
       HeapWord* const last_addr = dest_addr + words - 1;
       const size_t dest_region_1 = addr_to_region_idx(dest_addr);
       const size_t dest_region_2 = addr_to_region_idx(last_addr);
-#if     0
+
       // Initially assume that the destination regions will be the same and
       // adjust the value below if necessary.  Under this assumption, if
       // cur_region == dest_region_2, then cur_region will be compacted
       // completely into itself.
-      uint destination_count = cur_region == dest_region_2 ? 0 : 1;
+      destination_count += cur_region == dest_region_2 ? 0 : 1;
       if (dest_region_1 != dest_region_2) {
         // Destination regions differ; adjust destination_count.
         destination_count += 1;
@@ -487,25 +674,6 @@
         // region.
         _region_data[dest_region_1].set_source_region(cur_region);
       }
-#else
-      // Initially assume that the destination regions will be different and
-      // adjust the value below if necessary.  Under this assumption, if
-      // cur_region == dest_region2, then cur_region will be compacted partially
-      // into dest_region_1 and partially into itself.
-      uint destination_count = cur_region == dest_region_2 ? 1 : 2;
-      if (dest_region_1 != dest_region_2) {
-        // Data from cur_region will be copied to the start of dest_region_2.
-        _region_data[dest_region_2].set_source_region(cur_region);
-      } else {
-        // Destination regions are the same; adjust destination_count.
-        destination_count -= 1;
-        if (region_offset(dest_addr) == 0) {
-          // Data from cur_region will be copied to the start of the destination
-          // region.
-          _region_data[dest_region_1].set_source_region(cur_region);
-        }
-      }
-#endif  // #if 0
 
       _region_data[cur_region].set_destination_count(destination_count);
       _region_data[cur_region].set_data_location(region_to_addr(cur_region));
@@ -558,7 +726,7 @@
   size_t live_to_left = bitmap->live_words_in_range(search_start, oop(addr));
 
   result += partial_obj_size + live_to_left;
-  assert(result <= addr, "object cannot move to the right");
+  DEBUG_ONLY(PSParallelCompact::check_new_location(addr, result);)
   return result;
 }
 
@@ -749,6 +917,13 @@
   const size_t end_region =
     _summary_data.addr_to_region_idx(_summary_data.region_align_up(max_top));
   _summary_data.clear_range(beg_region, end_region);
+
+  // Clear the data used to 'split' regions.
+  SplitInfo& split_info = _space_info[id].split_info();
+  if (split_info.is_valid()) {
+    split_info.clear();
+  }
+  DEBUG_ONLY(split_info.verify_clear();)
 }
 
 void PSParallelCompact::pre_compact(PreGCValues* pre_gc_values)
@@ -807,10 +982,11 @@
 {
   TraceTime tm("post compact", print_phases(), true, gclog_or_tty);
 
-  // Clear the marking bitmap and summary data and update top() in each space.
   for (unsigned int id = perm_space_id; id < last_space_id; ++id) {
+    // Clear the marking bitmap, summary data and split info.
     clear_data_covering_space(SpaceId(id));
-    _space_info[id].space()->set_top(_space_info[id].new_top());
+    // Update top().  Must be done after clearing the bitmap and summary data.
+    _space_info[id].publish_new_top();
   }
 
   MutableSpace* const eden_space = _space_info[eden_space_id].space();
@@ -1151,6 +1327,13 @@
 PSParallelCompact::compute_dense_prefix(const SpaceId id,
                                         bool maximum_compaction)
 {
+  if (ParallelOldGCSplitALot) {
+    if (_space_info[id].dense_prefix() != _space_info[id].space()->bottom()) {
+      // The value was chosen to provoke splitting a young gen space; use it.
+      return _space_info[id].dense_prefix();
+    }
+  }
+
   const size_t region_size = ParallelCompactData::RegionSize;
   const ParallelCompactData& sd = summary_data();
 
@@ -1239,16 +1422,221 @@
   return sd.region_to_addr(best_cp);
 }
 
+#ifndef PRODUCT
+void
+PSParallelCompact::fill_with_live_objects(SpaceId id, HeapWord* const start,
+                                          size_t words)
+{
+  if (TraceParallelOldGCSummaryPhase) {
+    tty->print_cr("fill_with_live_objects [" PTR_FORMAT " " PTR_FORMAT ") "
+                  SIZE_FORMAT, start, start + words, words);
+  }
+
+  ObjectStartArray* const start_array = _space_info[id].start_array();
+  CollectedHeap::fill_with_objects(start, words);
+  for (HeapWord* p = start; p < start + words; p += oop(p)->size()) {
+    _mark_bitmap.mark_obj(p, words);
+    _summary_data.add_obj(p, words);
+    start_array->allocate_block(p);
+  }
+}
+
+void
+PSParallelCompact::summarize_new_objects(SpaceId id, HeapWord* start)
+{
+  ParallelCompactData& sd = summary_data();
+  MutableSpace* space = _space_info[id].space();
+
+  // Find the source and destination start addresses.
+  HeapWord* const src_addr = sd.region_align_down(start);
+  HeapWord* dst_addr;
+  if (src_addr < start) {
+    dst_addr = sd.addr_to_region_ptr(src_addr)->destination();
+  } else if (src_addr > space->bottom()) {
+    // The start (the original top() value) is aligned to a region boundary so
+    // the associated region does not have a destination.  Compute the
+    // destination from the previous region.
+    RegionData* const cp = sd.addr_to_region_ptr(src_addr) - 1;
+    dst_addr = cp->destination() + cp->data_size();
+  } else {
+    // Filling the entire space.
+    dst_addr = space->bottom();
+  }
+  assert(dst_addr != NULL, "sanity");
+
+  // Update the summary data.
+  bool result = _summary_data.summarize(_space_info[id].split_info(),
+                                        src_addr, space->top(), NULL,
+                                        dst_addr, space->end(),
+                                        _space_info[id].new_top_addr());
+  assert(result, "should not fail:  bad filler object size");
+}
+
+void
+PSParallelCompact::provoke_split_fill_survivor(SpaceId id)
+{
+  if (total_invocations() % (ParallelOldGCSplitInterval * 3) != 0) {
+    return;
+  }
+
+  MutableSpace* const space = _space_info[id].space();
+  if (space->is_empty()) {
+    HeapWord* b = space->bottom();
+    HeapWord* t = b + space->capacity_in_words() / 2;
+    space->set_top(t);
+    if (ZapUnusedHeapArea) {
+      space->set_top_for_allocations();
+    }
+
+    size_t obj_len = 8;
+    while (b + obj_len <= t) {
+      CollectedHeap::fill_with_object(b, obj_len);
+      mark_bitmap()->mark_obj(b, obj_len);
+      summary_data().add_obj(b, obj_len);
+      b += obj_len;
+      obj_len = (obj_len & 0x18) + 8; // 8 16 24 32 8 16 24 32 ...
+    }
+    if (b < t) {
+      // The loop didn't completely fill to t (top); adjust top downward.
+      space->set_top(b);
+      if (ZapUnusedHeapArea) {
+        space->set_top_for_allocations();
+      }
+    }
+
+    HeapWord** nta = _space_info[id].new_top_addr();
+    bool result = summary_data().summarize(_space_info[id].split_info(),
+                                           space->bottom(), space->top(), NULL,
+                                           space->bottom(), space->end(), nta);
+    assert(result, "space must fit into itself");
+  }
+}
+
+void
+PSParallelCompact::provoke_split(bool & max_compaction)
+{
+  if (total_invocations() % ParallelOldGCSplitInterval != 0) {
+    return;
+  }
+
+  const size_t region_size = ParallelCompactData::RegionSize;
+  ParallelCompactData& sd = summary_data();
+
+  MutableSpace* const eden_space = _space_info[eden_space_id].space();
+  MutableSpace* const from_space = _space_info[from_space_id].space();
+  const size_t eden_live = pointer_delta(eden_space->top(),
+                                         _space_info[eden_space_id].new_top());
+  const size_t from_live = pointer_delta(from_space->top(),
+                                         _space_info[from_space_id].new_top());
+
+  const size_t min_fill_size = CollectedHeap::min_fill_size();
+  const size_t eden_free = pointer_delta(eden_space->end(), eden_space->top());
+  const size_t eden_fillable = eden_free >= min_fill_size ? eden_free : 0;
+  const size_t from_free = pointer_delta(from_space->end(), from_space->top());
+  const size_t from_fillable = from_free >= min_fill_size ? from_free : 0;
+
+  // Choose the space to split; need at least 2 regions live (or fillable).
+  SpaceId id;
+  MutableSpace* space;
+  size_t live_words;
+  size_t fill_words;
+  if (eden_live + eden_fillable >= region_size * 2) {
+    id = eden_space_id;
+    space = eden_space;
+    live_words = eden_live;
+    fill_words = eden_fillable;
+  } else if (from_live + from_fillable >= region_size * 2) {
+    id = from_space_id;
+    space = from_space;
+    live_words = from_live;
+    fill_words = from_fillable;
+  } else {
+    return; // Give up.
+  }
+  assert(fill_words == 0 || fill_words >= min_fill_size, "sanity");
+
+  if (live_words < region_size * 2) {
+    // Fill from top() to end() w/live objects of mixed sizes.
+    HeapWord* const fill_start = space->top();
+    live_words += fill_words;
+
+    space->set_top(fill_start + fill_words);
+    if (ZapUnusedHeapArea) {
+      space->set_top_for_allocations();
+    }
+
+    HeapWord* cur_addr = fill_start;
+    while (fill_words > 0) {
+      const size_t r = (size_t)os::random() % (region_size / 2) + min_fill_size;
+      size_t cur_size = MIN2(align_object_size_(r), fill_words);
+      if (fill_words - cur_size < min_fill_size) {
+        cur_size = fill_words; // Avoid leaving a fragment too small to fill.
+      }
+
+      CollectedHeap::fill_with_object(cur_addr, cur_size);
+      mark_bitmap()->mark_obj(cur_addr, cur_size);
+      sd.add_obj(cur_addr, cur_size);
+
+      cur_addr += cur_size;
+      fill_words -= cur_size;
+    }
+
+    summarize_new_objects(id, fill_start);
+  }
+
+  max_compaction = false;
+
+  // Manipulate the old gen so that it has room for about half of the live data
+  // in the target young gen space (live_words / 2).
+  id = old_space_id;
+  space = _space_info[id].space();
+  const size_t free_at_end = space->free_in_words();
+  const size_t free_target = align_object_size(live_words / 2);
+  const size_t dead = pointer_delta(space->top(), _space_info[id].new_top());
+
+  if (free_at_end >= free_target + min_fill_size) {
+    // Fill space above top() and set the dense prefix so everything survives.
+    HeapWord* const fill_start = space->top();
+    const size_t fill_size = free_at_end - free_target;
+    space->set_top(space->top() + fill_size);
+    if (ZapUnusedHeapArea) {
+      space->set_top_for_allocations();
+    }
+    fill_with_live_objects(id, fill_start, fill_size);
+    summarize_new_objects(id, fill_start);
+    _space_info[id].set_dense_prefix(sd.region_align_down(space->top()));
+  } else if (dead + free_at_end > free_target) {
+    // Find a dense prefix that makes the right amount of space available.
+    HeapWord* cur = sd.region_align_down(space->top());
+    HeapWord* cur_destination = sd.addr_to_region_ptr(cur)->destination();
+    size_t dead_to_right = pointer_delta(space->end(), cur_destination);
+    while (dead_to_right < free_target) {
+      cur -= region_size;
+      cur_destination = sd.addr_to_region_ptr(cur)->destination();
+      dead_to_right = pointer_delta(space->end(), cur_destination);
+    }
+    _space_info[id].set_dense_prefix(cur);
+  }
+}
+#endif // #ifndef PRODUCT
+
 void PSParallelCompact::summarize_spaces_quick()
 {
   for (unsigned int i = 0; i < last_space_id; ++i) {
     const MutableSpace* space = _space_info[i].space();
-    bool result = _summary_data.summarize(space->bottom(), space->end(),
-                                          space->bottom(), space->top(),
-                                          _space_info[i].new_top_addr());
-    assert(result, "should never fail");
+    HeapWord** nta = _space_info[i].new_top_addr();
+    bool result = _summary_data.summarize(_space_info[i].split_info(),
+                                          space->bottom(), space->top(), NULL,
+                                          space->bottom(), space->end(), nta);
+    assert(result, "space must fit into itself");
     _space_info[i].set_dense_prefix(space->bottom());
   }
+
+#ifndef PRODUCT
+  if (ParallelOldGCSplitALot) {
+    provoke_split_fill_survivor(to_space_id);
+  }
+#endif // #ifndef PRODUCT
 }
 
 void PSParallelCompact::fill_dense_prefix_end(SpaceId id)
@@ -1308,8 +1696,7 @@
     }
 #endif  // #ifdef _LP64
 
-    MemRegion region(obj_beg, obj_len);
-    SharedHeap::fill_region_with_object(region);
+    CollectedHeap::fill_with_object(obj_beg, obj_len);
     _mark_bitmap.mark_obj(obj_beg, obj_len);
     _summary_data.add_obj(obj_beg, obj_len);
     assert(start_array(id) != NULL, "sanity");
@@ -1318,11 +1705,23 @@
 }
 
 void
+PSParallelCompact::clear_source_region(HeapWord* beg_addr, HeapWord* end_addr)
+{
+  RegionData* const beg_ptr = _summary_data.addr_to_region_ptr(beg_addr);
+  HeapWord* const end_aligned_up = _summary_data.region_align_up(end_addr);
+  RegionData* const end_ptr = _summary_data.addr_to_region_ptr(end_aligned_up);
+  for (RegionData* cur = beg_ptr; cur < end_ptr; ++cur) {
+    cur->set_source_region(0);
+  }
+}
+
+void
 PSParallelCompact::summarize_space(SpaceId id, bool maximum_compaction)
 {
   assert(id < last_space_id, "id out of range");
-  assert(_space_info[id].dense_prefix() == _space_info[id].space()->bottom(),
-         "should have been set in summarize_spaces_quick()");
+  assert(_space_info[id].dense_prefix() == _space_info[id].space()->bottom() ||
+         ParallelOldGCSplitALot && id == old_space_id,
+         "should have been reset in summarize_spaces_quick()");
 
   const MutableSpace* space = _space_info[id].space();
   if (_space_info[id].new_top() != space->bottom()) {
@@ -1338,20 +1737,24 @@
     }
 #endif  // #ifndef PRODUCT
 
-    // If dead space crosses the dense prefix boundary, it is (at least
-    // partially) filled with a dummy object, marked live and added to the
-    // summary data.  This simplifies the copy/update phase and must be done
-    // before the final locations of objects are determined, to prevent leaving
-    // a fragment of dead space that is too small to fill with an object.
+    // Recompute the summary data, taking into account the dense prefix.  If
+    // every last byte will be reclaimed, then the existing summary data which
+    // compacts everything can be left in place.
     if (!maximum_compaction && dense_prefix_end != space->bottom()) {
+      // If dead space crosses the dense prefix boundary, it is (at least
+      // partially) filled with a dummy object, marked live and added to the
+      // summary data.  This simplifies the copy/update phase and must be done
+      // before the final locations of objects are determined, to prevent
+      // leaving a fragment of dead space that is too small to fill.
       fill_dense_prefix_end(id);
+
+      // Compute the destination of each Region, and thus each object.
+      _summary_data.summarize_dense_prefix(space->bottom(), dense_prefix_end);
+      _summary_data.summarize(_space_info[id].split_info(),
+                              dense_prefix_end, space->top(), NULL,
+                              dense_prefix_end, space->end(),
+                              _space_info[id].new_top_addr());
     }
-
-    // Compute the destination of each Region, and thus each object.
-    _summary_data.summarize_dense_prefix(space->bottom(), dense_prefix_end);
-    _summary_data.summarize(dense_prefix_end, space->end(),
-                            dense_prefix_end, space->top(),
-                            _space_info[id].new_top_addr());
   }
 
   if (TraceParallelOldGCSummaryPhase) {
@@ -1371,6 +1774,30 @@
   }
 }
 
+#ifndef PRODUCT
+void PSParallelCompact::summary_phase_msg(SpaceId dst_space_id,
+                                          HeapWord* dst_beg, HeapWord* dst_end,
+                                          SpaceId src_space_id,
+                                          HeapWord* src_beg, HeapWord* src_end)
+{
+  if (TraceParallelOldGCSummaryPhase) {
+    tty->print_cr("summarizing %d [%s] into %d [%s]:  "
+                  "src=" PTR_FORMAT "-" PTR_FORMAT " "
+                  SIZE_FORMAT "-" SIZE_FORMAT " "
+                  "dst=" PTR_FORMAT "-" PTR_FORMAT " "
+                  SIZE_FORMAT "-" SIZE_FORMAT,
+                  src_space_id, space_names[src_space_id],
+                  dst_space_id, space_names[dst_space_id],
+                  src_beg, src_end,
+                  _summary_data.addr_to_region_idx(src_beg),
+                  _summary_data.addr_to_region_idx(src_end),
+                  dst_beg, dst_end,
+                  _summary_data.addr_to_region_idx(dst_beg),
+                  _summary_data.addr_to_region_idx(dst_end));
+  }
+}
+#endif  // #ifndef PRODUCT
+
 void PSParallelCompact::summary_phase(ParCompactionManager* cm,
                                       bool maximum_compaction)
 {
@@ -1403,57 +1830,80 @@
 
   // The amount of live data that will end up in old space (assuming it fits).
   size_t old_space_total_live = 0;
-  unsigned int id;
-  for (id = old_space_id; id < last_space_id; ++id) {
+  assert(perm_space_id < old_space_id, "should not count perm data here");
+  for (unsigned int id = old_space_id; id < last_space_id; ++id) {
     old_space_total_live += pointer_delta(_space_info[id].new_top(),
                                           _space_info[id].space()->bottom());
   }
 
-  const MutableSpace* old_space = _space_info[old_space_id].space();
-  if (old_space_total_live > old_space->capacity_in_words()) {
+  MutableSpace* const old_space = _space_info[old_space_id].space();
+  const size_t old_capacity = old_space->capacity_in_words();
+  if (old_space_total_live > old_capacity) {
     // XXX - should also try to expand
     maximum_compaction = true;
-  } else if (!UseParallelOldGCDensePrefix) {
-    maximum_compaction = true;
   }
+#ifndef PRODUCT
+  if (ParallelOldGCSplitALot && old_space_total_live < old_capacity) {
+    provoke_split(maximum_compaction);
+  }
+#endif // #ifndef PRODUCT
 
   // Permanent and Old generations.
   summarize_space(perm_space_id, maximum_compaction);
   summarize_space(old_space_id, maximum_compaction);
 
-  // Summarize the remaining spaces (those in the young gen) into old space.  If
-  // the live data from a space doesn't fit, the existing summarization is left
-  // intact, so the data is compacted down within the space itself.
-  HeapWord** new_top_addr = _space_info[old_space_id].new_top_addr();
-  HeapWord* const target_space_end = old_space->end();
-  for (id = eden_space_id; id < last_space_id; ++id) {
+  // Summarize the remaining spaces in the young gen.  The initial target space
+  // is the old gen.  If a space does not fit entirely into the target, then the
+  // remainder is compacted into the space itself and that space becomes the new
+  // target.
+  SpaceId dst_space_id = old_space_id;
+  HeapWord* dst_space_end = old_space->end();
+  HeapWord** new_top_addr = _space_info[dst_space_id].new_top_addr();
+  for (unsigned int id = eden_space_id; id < last_space_id; ++id) {
     const MutableSpace* space = _space_info[id].space();
     const size_t live = pointer_delta(_space_info[id].new_top(),
                                       space->bottom());
-    const size_t available = pointer_delta(target_space_end, *new_top_addr);
+    const size_t available = pointer_delta(dst_space_end, *new_top_addr);
+
+    NOT_PRODUCT(summary_phase_msg(dst_space_id, *new_top_addr, dst_space_end,
+                                  SpaceId(id), space->bottom(), space->top());)
     if (live > 0 && live <= available) {
       // All the live data will fit.
-      if (TraceParallelOldGCSummaryPhase) {
-        tty->print_cr("summarizing %d into old_space @ " PTR_FORMAT,
-                      id, *new_top_addr);
-      }
-      _summary_data.summarize(*new_top_addr, target_space_end,
-                              space->bottom(), space->top(),
-                              new_top_addr);
-
-      // Clear the source_region field for each region in the space.
-      HeapWord* const new_top = _space_info[id].new_top();
-      HeapWord* const clear_end = _summary_data.region_align_up(new_top);
-      RegionData* beg_region =
-        _summary_data.addr_to_region_ptr(space->bottom());
-      RegionData* end_region = _summary_data.addr_to_region_ptr(clear_end);
-      while (beg_region < end_region) {
-        beg_region->set_source_region(0);
-        ++beg_region;
-      }
+      bool done = _summary_data.summarize(_space_info[id].split_info(),
+                                          space->bottom(), space->top(),
+                                          NULL,
+                                          *new_top_addr, dst_space_end,
+                                          new_top_addr);
+      assert(done, "space must fit into old gen");
 
       // Reset the new_top value for the space.
       _space_info[id].set_new_top(space->bottom());
+    } else if (live > 0) {
+      // Attempt to fit part of the source space into the target space.
+      HeapWord* next_src_addr = NULL;
+      bool done = _summary_data.summarize(_space_info[id].split_info(),
+                                          space->bottom(), space->top(),
+                                          &next_src_addr,
+                                          *new_top_addr, dst_space_end,
+                                          new_top_addr);
+      assert(!done, "space should not fit into old gen");
+      assert(next_src_addr != NULL, "sanity");
+
+      // The source space becomes the new target, so the remainder is compacted
+      // within the space itself.
+      dst_space_id = SpaceId(id);
+      dst_space_end = space->end();
+      new_top_addr = _space_info[id].new_top_addr();
+      NOT_PRODUCT(summary_phase_msg(dst_space_id,
+                                    space->bottom(), dst_space_end,
+                                    SpaceId(id), next_src_addr, space->top());)
+      done = _summary_data.summarize(_space_info[id].split_info(),
+                                     next_src_addr, space->top(),
+                                     NULL,
+                                     space->bottom(), dst_space_end,
+                                     new_top_addr);
+      assert(done, "space must fit when compacted into itself");
+      assert(*new_top_addr <= space->top(), "usage should not grow");
     }
   }
 
@@ -1578,6 +2028,7 @@
     COMPILER2_PRESENT(DerivedPointerTable::clear());
 
     ref_processor()->enable_discovery();
+    ref_processor()->setup_policy(maximum_heap_compaction);
 
     bool marked_for_unloading = false;
 
@@ -1806,9 +2257,14 @@
 
   // Fill the unused part of the old gen.
   MutableSpace* const old_space = old_gen->object_space();
-  MemRegion old_gen_unused(old_space->top(), old_space->end());
-  if (!old_gen_unused.is_empty()) {
-    SharedHeap::fill_region_with_object(old_gen_unused);
+  HeapWord* const unused_start = old_space->top();
+  size_t const unused_words = pointer_delta(old_space->end(), unused_start);
+
+  if (unused_words > 0) {
+    if (unused_words < CollectedHeap::min_fill_size()) {
+      return false;  // If the old gen cannot be filled, must give up.
+    }
+    CollectedHeap::fill_with_objects(unused_start, unused_words);
   }
 
   // Take the live data from eden and set both top and end in the old gen to
@@ -1824,9 +2280,8 @@
 
   // Update the object start array for the filler object and the data from eden.
   ObjectStartArray* const start_array = old_gen->start_array();
-  HeapWord* const start = old_gen_unused.start();
-  for (HeapWord* addr = start; addr < new_top; addr += oop(addr)->size()) {
-    start_array->allocate_block(addr);
+  for (HeapWord* p = unused_start; p < new_top; p += oop(p)->size()) {
+    start_array->allocate_block(p);
   }
 
   // Could update the promoted average here, but it is not typically updated at
@@ -1894,26 +2349,14 @@
   // Process reference objects found during marking
   {
     TraceTime tm_r("reference processing", print_phases(), true, gclog_or_tty);
-    ReferencePolicy *soft_ref_policy;
-    if (maximum_heap_compaction) {
-      soft_ref_policy = new AlwaysClearPolicy();
-    } else {
-#ifdef COMPILER2
-      soft_ref_policy = new LRUMaxHeapPolicy();
-#else
-      soft_ref_policy = new LRUCurrentHeapPolicy();
-#endif // COMPILER2
-    }
-    assert(soft_ref_policy != NULL, "No soft reference policy");
     if (ref_processor()->processing_is_mt()) {
       RefProcTaskExecutor task_executor;
       ref_processor()->process_discovered_references(
-        soft_ref_policy, is_alive_closure(), &mark_and_push_closure,
-        &follow_stack_closure, &task_executor);
+        is_alive_closure(), &mark_and_push_closure, &follow_stack_closure,
+        &task_executor);
     } else {
       ref_processor()->process_discovered_references(
-        soft_ref_policy, is_alive_closure(), &mark_and_push_closure,
-        &follow_stack_closure, NULL);
+        is_alive_closure(), &mark_and_push_closure, &follow_stack_closure, NULL);
     }
   }
 
@@ -2059,14 +2502,13 @@
   // regions in the dense prefix.  Assume that 1 gc thread
   // will work on opening the gaps and the remaining gc threads
   // will work on the dense prefix.
-  SpaceId space_id = old_space_id;
-  while (space_id != last_space_id) {
+  unsigned int space_id;
+  for (space_id = old_space_id; space_id < last_space_id; ++ space_id) {
     HeapWord* const dense_prefix_end = _space_info[space_id].dense_prefix();
     const MutableSpace* const space = _space_info[space_id].space();
 
     if (dense_prefix_end == space->bottom()) {
       // There is no dense prefix for this space.
-      space_id = next_compaction_space_id(space_id);
       continue;
     }
 
@@ -2116,23 +2558,20 @@
         // region_index_end is not processed
         size_t region_index_end = MIN2(region_index_start + regions_per_thread,
                                        region_index_end_dense_prefix);
-        q->enqueue(new UpdateDensePrefixTask(
-                                 space_id,
-                                 region_index_start,
-                                 region_index_end));
+        q->enqueue(new UpdateDensePrefixTask(SpaceId(space_id),
+                                             region_index_start,
+                                             region_index_end));
         region_index_start = region_index_end;
       }
     }
     // This gets any part of the dense prefix that did not
     // fit evenly.
     if (region_index_start < region_index_end_dense_prefix) {
-      q->enqueue(new UpdateDensePrefixTask(
-                                 space_id,
-                                 region_index_start,
-                                 region_index_end_dense_prefix));
+      q->enqueue(new UpdateDensePrefixTask(SpaceId(space_id),
+                                           region_index_start,
+                                           region_index_end_dense_prefix));
     }
-    space_id = next_compaction_space_id(space_id);
-  }  // End tasks for dense prefix
+  }
 }
 
 void PSParallelCompact::enqueue_region_stealing_tasks(
@@ -2578,16 +3017,24 @@
   return m->bit_to_addr(cur_beg);
 }
 
-HeapWord*
-PSParallelCompact::first_src_addr(HeapWord* const dest_addr,
-                                 size_t src_region_idx)
+HeapWord* PSParallelCompact::first_src_addr(HeapWord* const dest_addr,
+                                            SpaceId src_space_id,
+                                            size_t src_region_idx)
 {
+  assert(summary_data().is_region_aligned(dest_addr), "not aligned");
+
+  const SplitInfo& split_info = _space_info[src_space_id].split_info();
+  if (split_info.dest_region_addr() == dest_addr) {
+    // The partial object ending at the split point contains the first word to
+    // be copied to dest_addr.
+    return split_info.first_src_addr();
+  }
+
+  const ParallelCompactData& sd = summary_data();
   ParMarkBitMap* const bitmap = mark_bitmap();
-  const ParallelCompactData& sd = summary_data();
   const size_t RegionSize = ParallelCompactData::RegionSize;
 
   assert(sd.is_region_aligned(dest_addr), "not aligned");
-
   const RegionData* const src_region_ptr = sd.region(src_region_idx);
   const size_t partial_obj_size = src_region_ptr->partial_obj_size();
   HeapWord* const src_region_destination = src_region_ptr->destination();
@@ -2636,19 +3083,34 @@
 }
 
 void PSParallelCompact::decrement_destination_counts(ParCompactionManager* cm,
+                                                     SpaceId src_space_id,
                                                      size_t beg_region,
                                                      HeapWord* end_addr)
 {
   ParallelCompactData& sd = summary_data();
+
+#ifdef ASSERT
+  MutableSpace* const src_space = _space_info[src_space_id].space();
+  HeapWord* const beg_addr = sd.region_to_addr(beg_region);
+  assert(src_space->contains(beg_addr) || beg_addr == src_space->end(),
+         "src_space_id does not match beg_addr");
+  assert(src_space->contains(end_addr) || end_addr == src_space->end(),
+         "src_space_id does not match end_addr");
+#endif // #ifdef ASSERT
+
   RegionData* const beg = sd.region(beg_region);
-  HeapWord* const end_addr_aligned_up = sd.region_align_up(end_addr);
-  RegionData* const end = sd.addr_to_region_ptr(end_addr_aligned_up);
-  size_t cur_idx = beg_region;
-  for (RegionData* cur = beg; cur < end; ++cur, ++cur_idx) {
+  RegionData* const end = sd.addr_to_region_ptr(sd.region_align_up(end_addr));
+
+  // Regions up to new_top() are enqueued if they become available.
+  HeapWord* const new_top = _space_info[src_space_id].new_top();
+  RegionData* const enqueue_end =
+    sd.addr_to_region_ptr(sd.region_align_up(new_top));
+
+  for (RegionData* cur = beg; cur < end; ++cur) {
     assert(cur->data_size() > 0, "region must have live data");
     cur->decrement_destination_count();
-    if (cur_idx <= cur->source_region() && cur->available() && cur->claim()) {
-      cm->save_for_processing(cur_idx);
+    if (cur < enqueue_end && cur->available() && cur->claim()) {
+      cm->save_for_processing(sd.region(cur));
     }
   }
 }
@@ -2748,7 +3210,7 @@
   HeapWord* src_space_top = _space_info[src_space_id].space()->top();
 
   MoveAndUpdateClosure closure(bitmap, cm, start_array, dest_addr, words);
-  closure.set_source(first_src_addr(dest_addr, src_region_idx));
+  closure.set_source(first_src_addr(dest_addr, src_space_id, src_region_idx));
 
   // Adjust src_region_idx to prepare for decrementing destination counts (the
   // destination count is not decremented when a region is copied to itself).
@@ -2763,7 +3225,8 @@
     HeapWord* const old_src_addr = closure.source();
     closure.copy_partial_obj();
     if (closure.is_full()) {
-      decrement_destination_counts(cm, src_region_idx, closure.source());
+      decrement_destination_counts(cm, src_space_id, src_region_idx,
+                                   closure.source());
       region_ptr->set_deferred_obj_addr(NULL);
       region_ptr->set_completed();
       return;
@@ -2772,7 +3235,7 @@
     HeapWord* const end_addr = sd.region_align_down(closure.source());
     if (sd.region_align_down(old_src_addr) != end_addr) {
       // The partial object was copied from more than one source region.
-      decrement_destination_counts(cm, src_region_idx, end_addr);
+      decrement_destination_counts(cm, src_space_id, src_region_idx, end_addr);
 
       // Move to the next source region, possibly switching spaces as well.  All
       // args except end_addr may be modified.
@@ -2812,19 +3275,21 @@
       region_ptr->set_deferred_obj_addr(closure.destination());
       status = closure.copy_until_full(); // copies from closure.source()
 
-      decrement_destination_counts(cm, src_region_idx, closure.source());
+      decrement_destination_counts(cm, src_space_id, src_region_idx,
+                                   closure.source());
       region_ptr->set_completed();
       return;
     }
 
     if (status == ParMarkBitMap::full) {
-      decrement_destination_counts(cm, src_region_idx, closure.source());
+      decrement_destination_counts(cm, src_space_id, src_region_idx,
+                                   closure.source());
       region_ptr->set_deferred_obj_addr(NULL);
       region_ptr->set_completed();
       return;
     }
 
-    decrement_destination_counts(cm, src_region_idx, end_addr);
+    decrement_destination_counts(cm, src_space_id, src_region_idx, end_addr);
 
     // Move to the next source region, possibly switching spaces as well.  All
     // args except end_addr may be modified.
@@ -2903,7 +3368,7 @@
 ParMarkBitMap::IterationStatus MoveAndUpdateClosure::copy_until_full()
 {
   if (source() != destination()) {
-    assert(source() > destination(), "must copy to the left");
+    DEBUG_ONLY(PSParallelCompact::check_new_location(source(), destination());)
     Copy::aligned_conjoint_words(source(), destination(), words_remaining());
   }
   update_state(words_remaining());
@@ -2924,7 +3389,7 @@
   // This test is necessary; if omitted, the pointer updates to a partial object
   // that crosses the dense prefix boundary could be overwritten.
   if (source() != destination()) {
-    assert(source() > destination(), "must copy to the left");
+    DEBUG_ONLY(PSParallelCompact::check_new_location(source(), destination());)
     Copy::aligned_conjoint_words(source(), destination(), words);
   }
   update_state(words);
@@ -2949,7 +3414,7 @@
   }
 
   if (destination() != source()) {
-    assert(destination() < source(), "must copy to the left");
+    DEBUG_ONLY(PSParallelCompact::check_new_location(source(), destination());)
     Copy::aligned_conjoint_words(source(), destination(), words);
   }
 
@@ -3019,34 +3484,3 @@
     summary_data().calc_new_pointer(Universe::intArrayKlassObj());
 }
 
-// The initial implementation of this method created a field
-// _next_compaction_space_id in SpaceInfo and initialized
-// that field in SpaceInfo::initialize_space_info().  That
-// required that _next_compaction_space_id be declared a
-// SpaceId in SpaceInfo and that would have required that
-// either SpaceId be declared in a separate class or that
-// it be declared in SpaceInfo.  It didn't seem consistent
-// to declare it in SpaceInfo (didn't really fit logically).
-// Alternatively, defining a separate class to define SpaceId
-// seem excessive.  This implementation is simple and localizes
-// the knowledge.
-
-PSParallelCompact::SpaceId
-PSParallelCompact::next_compaction_space_id(SpaceId id) {
-  assert(id < last_space_id, "id out of range");
-  switch (id) {
-    case perm_space_id :
-      return last_space_id;
-    case old_space_id :
-      return eden_space_id;
-    case eden_space_id :
-      return from_space_id;
-    case from_space_id :
-      return to_space_id;
-    case to_space_id :
-      return last_space_id;
-    default:
-      assert(false, "Bad space id");
-      return last_space_id;
-  }
-}
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp	Thu Jan 08 16:34:58 2009 -0800
@@ -36,6 +36,123 @@
 class MoveAndUpdateClosure;
 class RefProcTaskExecutor;
 
+// The SplitInfo class holds the information needed to 'split' a source region
+// so that the live data can be copied to two destination *spaces*.  Normally,
+// all the live data in a region is copied to a single destination space (e.g.,
+// everything live in a region in eden is copied entirely into the old gen).
+// However, when the heap is nearly full, all the live data in eden may not fit
+// into the old gen.  Copying only some of the regions from eden to old gen
+// requires finding a region that does not contain a partial object (i.e., no
+// live object crosses the region boundary) somewhere near the last object that
+// does fit into the old gen.  Since it's not always possible to find such a
+// region, splitting is necessary for predictable behavior.
+//
+// A region is always split at the end of the partial object.  This avoids
+// additional tests when calculating the new location of a pointer, which is a
+// very hot code path.  The partial object and everything to its left will be
+// copied to another space (call it dest_space_1).  The live data to the right
+// of the partial object will be copied either within the space itself, or to a
+// different destination space (distinct from dest_space_1).
+//
+// Split points are identified during the summary phase, when region
+// destinations are computed:  data about the split, including the
+// partial_object_size, is recorded in a SplitInfo record and the
+// partial_object_size field in the summary data is set to zero.  The zeroing is
+// possible (and necessary) since the partial object will move to a different
+// destination space than anything to its right, thus the partial object should
+// not affect the locations of any objects to its right.
+//
+// The recorded data is used during the compaction phase, but only rarely:  when
+// the partial object on the split region will be copied across a destination
+// region boundary.  This test is made once each time a region is filled, and is
+// a simple address comparison, so the overhead is negligible (see
+// PSParallelCompact::first_src_addr()).
+//
+// Notes:
+//
+// Only regions with partial objects are split; a region without a partial
+// object does not need any extra bookkeeping.
+//
+// At most one region is split per space, so the amount of data required is
+// constant.
+//
+// A region is split only when the destination space would overflow.  Once that
+// happens, the destination space is abandoned and no other data (even from
+// other source spaces) is targeted to that destination space.  Abandoning the
+// destination space may leave a somewhat large unused area at the end, if a
+// large object caused the overflow.
+//
+// Future work:
+//
+// More bookkeeping would be required to continue to use the destination space.
+// The most general solution would allow data from regions in two different
+// source spaces to be "joined" in a single destination region.  At the very
+// least, additional code would be required in next_src_region() to detect the
+// join and skip to an out-of-order source region.  If the join region was also
+// the last destination region to which a split region was copied (the most
+// likely case), then additional work would be needed to get fill_region() to
+// stop iteration and switch to a new source region at the right point.  Basic
+// idea would be to use a fake value for the top of the source space.  It is
+// doable, if a bit tricky.
+//
+// A simpler (but less general) solution would fill the remainder of the
+// destination region with a dummy object and continue filling the next
+// destination region.
+
+class SplitInfo
+{
+public:
+  // Return true if this split info is valid (i.e., if a split has been
+  // recorded).  The very first region cannot have a partial object and thus is
+  // never split, so 0 is the 'invalid' value.
+  bool is_valid() const { return _src_region_idx > 0; }
+
+  // Return true if this split holds data for the specified source region.
+  inline bool is_split(size_t source_region) const;
+
+  // The index of the split region, the size of the partial object on that
+  // region and the destination of the partial object.
+  size_t    src_region_idx() const   { return _src_region_idx; }
+  size_t    partial_obj_size() const { return _partial_obj_size; }
+  HeapWord* destination() const      { return _destination; }
+
+  // The destination count of the partial object referenced by this split
+  // (either 1 or 2).  This must be added to the destination count of the
+  // remainder of the source region.
+  unsigned int destination_count() const { return _destination_count; }
+
+  // If a word within the partial object will be written to the first word of a
+  // destination region, this is the address of the destination region;
+  // otherwise this is NULL.
+  HeapWord* dest_region_addr() const     { return _dest_region_addr; }
+
+  // If a word within the partial object will be written to the first word of a
+  // destination region, this is the address of that word within the partial
+  // object; otherwise this is NULL.
+  HeapWord* first_src_addr() const       { return _first_src_addr; }
+
+  // Record the data necessary to split the region src_region_idx.
+  void record(size_t src_region_idx, size_t partial_obj_size,
+              HeapWord* destination);
+
+  void clear();
+
+  DEBUG_ONLY(void verify_clear();)
+
+private:
+  size_t       _src_region_idx;
+  size_t       _partial_obj_size;
+  HeapWord*    _destination;
+  unsigned int _destination_count;
+  HeapWord*    _dest_region_addr;
+  HeapWord*    _first_src_addr;
+};
+
+inline bool SplitInfo::is_split(size_t region_idx) const
+{
+  return _src_region_idx == region_idx && is_valid();
+}
+
 class SpaceInfo
 {
  public:
@@ -58,18 +175,23 @@
   // is no start array.
   ObjectStartArray* start_array() const { return _start_array; }
 
+  SplitInfo& split_info() { return _split_info; }
+
   void set_space(MutableSpace* s)           { _space = s; }
   void set_new_top(HeapWord* addr)          { _new_top = addr; }
   void set_min_dense_prefix(HeapWord* addr) { _min_dense_prefix = addr; }
   void set_dense_prefix(HeapWord* addr)     { _dense_prefix = addr; }
   void set_start_array(ObjectStartArray* s) { _start_array = s; }
 
+  void publish_new_top() const              { _space->set_top(_new_top); }
+
  private:
   MutableSpace*     _space;
   HeapWord*         _new_top;
   HeapWord*         _min_dense_prefix;
   HeapWord*         _dense_prefix;
   ObjectStartArray* _start_array;
+  SplitInfo         _split_info;
 };
 
 class ParallelCompactData
@@ -230,9 +352,14 @@
   // must be region-aligned; end need not be.
   void summarize_dense_prefix(HeapWord* beg, HeapWord* end);
 
-  bool summarize(HeapWord* target_beg, HeapWord* target_end,
+  HeapWord* summarize_split_space(size_t src_region, SplitInfo& split_info,
+                                  HeapWord* destination, HeapWord* target_end,
+                                  HeapWord** target_next);
+  bool summarize(SplitInfo& split_info,
                  HeapWord* source_beg, HeapWord* source_end,
-                 HeapWord** target_next, HeapWord** source_next = 0);
+                 HeapWord** source_next,
+                 HeapWord* target_beg, HeapWord* target_end,
+                 HeapWord** target_next);
 
   void clear();
   void clear_range(size_t beg_region, size_t end_region);
@@ -838,13 +965,31 @@
   // non-empty.
   static void fill_dense_prefix_end(SpaceId id);
 
+  // Clear the summary data source_region field for the specified addresses.
+  static void clear_source_region(HeapWord* beg_addr, HeapWord* end_addr);
+
+#ifndef PRODUCT
+  // Routines to provoke splitting a young gen space (ParallelOldGCSplitALot).
+
+  // Fill the region [start, start + words) with live object(s).  Only usable
+  // for the old and permanent generations.
+  static void fill_with_live_objects(SpaceId id, HeapWord* const start,
+                                     size_t words);
+  // Include the new objects in the summary data.
+  static void summarize_new_objects(SpaceId id, HeapWord* start);
+
+  // Add live objects to a survivor space since it's rare that both survivors
+  // are non-empty.
+  static void provoke_split_fill_survivor(SpaceId id);
+
+  // Add live objects and/or choose the dense prefix to provoke splitting.
+  static void provoke_split(bool & maximum_compaction);
+#endif
+
   static void summarize_spaces_quick();
   static void summarize_space(SpaceId id, bool maximum_compaction);
   static void summary_phase(ParCompactionManager* cm, bool maximum_compaction);
 
-  // The space that is compacted after space_id.
-  static SpaceId next_compaction_space_id(SpaceId space_id);
-
   // Adjust addresses in roots.  Does not adjust addresses in heap.
   static void adjust_roots();
 
@@ -999,6 +1144,7 @@
   // Return the address of the word to be copied to dest_addr, which must be
   // aligned to a region boundary.
   static HeapWord* first_src_addr(HeapWord* const dest_addr,
+                                  SpaceId src_space_id,
                                   size_t src_region_idx);
 
   // Determine the next source region, set closure.source() to the start of the
@@ -1012,8 +1158,10 @@
                                 HeapWord* end_addr);
 
   // Decrement the destination count for each non-empty source region in the
-  // range [beg_region, region(region_align_up(end_addr))).
+  // range [beg_region, region(region_align_up(end_addr))).  If the destination
+  // count for a region goes to 0 and it needs to be filled, enqueue it.
   static void decrement_destination_counts(ParCompactionManager* cm,
+                                           SpaceId src_space_id,
                                            size_t beg_region,
                                            HeapWord* end_addr);
 
@@ -1081,9 +1229,15 @@
                                        const SpaceId id,
                                        const bool maximum_compaction,
                                        HeapWord* const addr);
+  static void summary_phase_msg(SpaceId dst_space_id,
+                                HeapWord* dst_beg, HeapWord* dst_end,
+                                SpaceId src_space_id,
+                                HeapWord* src_beg, HeapWord* src_end);
 #endif  // #ifndef PRODUCT
 
 #ifdef  ASSERT
+  // Sanity check the new location of a word in the heap.
+  static inline void check_new_location(HeapWord* old_addr, HeapWord* new_addr);
   // Verify that all the regions have been emptied.
   static void verify_complete(SpaceId space_id);
 #endif  // #ifdef ASSERT
@@ -1251,6 +1405,15 @@
   }
 }
 
+#ifdef ASSERT
+inline void
+PSParallelCompact::check_new_location(HeapWord* old_addr, HeapWord* new_addr)
+{
+  assert(old_addr >= new_addr || space_id(old_addr) != space_id(new_addr),
+         "must move left or to a different space");
+}
+#endif // ASSERT
+
 class MoveAndUpdateClosure: public ParMarkBitMapClosure {
  public:
   inline MoveAndUpdateClosure(ParMarkBitMap* bitmap, ParCompactionManager* cm,
@@ -1324,31 +1487,28 @@
   oop(addr)->update_contents(compaction_manager());
 }
 
-class FillClosure: public ParMarkBitMapClosure {
- public:
+class FillClosure: public ParMarkBitMapClosure
+{
+public:
   FillClosure(ParCompactionManager* cm, PSParallelCompact::SpaceId space_id) :
     ParMarkBitMapClosure(PSParallelCompact::mark_bitmap(), cm),
-    _space_id(space_id),
-    _start_array(PSParallelCompact::start_array(space_id)) {
-    assert(_space_id == PSParallelCompact::perm_space_id ||
-           _space_id == PSParallelCompact::old_space_id,
+    _start_array(PSParallelCompact::start_array(space_id))
+  {
+    assert(space_id == PSParallelCompact::perm_space_id ||
+           space_id == PSParallelCompact::old_space_id,
            "cannot use FillClosure in the young gen");
-    assert(bitmap() != NULL, "need a bitmap");
-    assert(_start_array != NULL, "need a start array");
-  }
-
-  void fill_region(HeapWord* addr, size_t size) {
-    MemRegion region(addr, size);
-    SharedHeap::fill_region_with_object(region);
-    _start_array->allocate_block(addr);
   }
 
   virtual IterationStatus do_addr(HeapWord* addr, size_t size) {
-    fill_region(addr, size);
+    CollectedHeap::fill_with_objects(addr, size);
+    HeapWord* const end = addr + size;
+    do {
+      _start_array->allocate_block(addr);
+      addr += oop(addr)->size();
+    } while (addr < end);
     return ParMarkBitMap::incomplete;
   }
 
 private:
-  const PSParallelCompact::SpaceId _space_id;
-  ObjectStartArray* const          _start_array;
+  ObjectStartArray* const _start_array;
 };
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPermGen.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPermGen.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2005 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2001-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -499,26 +499,15 @@
       // We lost, someone else "owns" this object
       guarantee(o->is_forwarded(), "Object must be forwarded if the cas failed.");
 
-      // Unallocate the space used. NOTE! We may have directly allocated
-      // the object. If so, we cannot deallocate it, so we have to test!
+      // Try to deallocate the space.  If it was directly allocated we cannot
+      // deallocate it, so we have to test.  If the deallocation fails,
+      // overwrite with a filler object.
       if (new_obj_is_tenured) {
         if (!_old_lab.unallocate_object(new_obj)) {
-          // The promotion lab failed to unallocate the object.
-          // We need to overwrite the object with a filler that
-          // contains no interior pointers.
-          MemRegion mr((HeapWord*)new_obj, new_obj_size);
-          // Clean this up and move to oopFactory (see bug 4718422)
-          SharedHeap::fill_region_with_object(mr);
+          CollectedHeap::fill_with_object((HeapWord*) new_obj, new_obj_size);
         }
-      } else {
-        if (!_young_lab.unallocate_object(new_obj)) {
-          // The promotion lab failed to unallocate the object.
-          // We need to overwrite the object with a filler that
-          // contains no interior pointers.
-          MemRegion mr((HeapWord*)new_obj, new_obj_size);
-          // Clean this up and move to oopFactory (see bug 4718422)
-          SharedHeap::fill_region_with_object(mr);
-        }
+      } else if (!_young_lab.unallocate_object(new_obj)) {
+        CollectedHeap::fill_with_object((HeapWord*) new_obj, new_obj_size);
       }
 
       // don't update this before the unallocation!
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -330,6 +330,7 @@
     COMPILER2_PRESENT(DerivedPointerTable::clear());
 
     reference_processor()->enable_discovery();
+    reference_processor()->setup_policy(false);
 
     // We track how much was promoted to the next generation for
     // the AdaptiveSizePolicy.
@@ -394,24 +395,16 @@
 
     // Process reference objects discovered during scavenge
     {
-#ifdef COMPILER2
-      ReferencePolicy *soft_ref_policy = new LRUMaxHeapPolicy();
-#else
-      ReferencePolicy *soft_ref_policy = new LRUCurrentHeapPolicy();
-#endif // COMPILER2
-
+      reference_processor()->setup_policy(false); // not always_clear
       PSKeepAliveClosure keep_alive(promotion_manager);
       PSEvacuateFollowersClosure evac_followers(promotion_manager);
-      assert(soft_ref_policy != NULL,"No soft reference policy");
       if (reference_processor()->processing_is_mt()) {
         PSRefProcTaskExecutor task_executor;
         reference_processor()->process_discovered_references(
-          soft_ref_policy, &_is_alive_closure, &keep_alive, &evac_followers,
-          &task_executor);
+          &_is_alive_closure, &keep_alive, &evac_followers, &task_executor);
       } else {
         reference_processor()->process_discovered_references(
-          soft_ref_policy, &_is_alive_closure, &keep_alive, &evac_followers,
-          NULL);
+          &_is_alive_closure, &keep_alive, &evac_followers, NULL);
       }
     }
 
--- a/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -76,8 +76,8 @@
     MutableSpace *s = ls->space();
     if (s->top() < top()) { // For all spaces preceeding the one containing top()
       if (s->free_in_words() > 0) {
-        SharedHeap::fill_region_with_object(MemRegion(s->top(), s->end()));
         size_t area_touched_words = pointer_delta(s->end(), s->top());
+        CollectedHeap::fill_with_object(s->top(), area_touched_words);
 #ifndef ASSERT
         if (!ZapUnusedHeapArea) {
           area_touched_words = MIN2((size_t)align_object_size(typeArrayOopDesc::header_size(T_INT)),
@@ -414,9 +414,20 @@
   if (limit > 0) {
     limit = round_down(limit, page_size());
     if (chunk_size > current_chunk_size(i)) {
-      chunk_size = MIN2((off_t)chunk_size, (off_t)current_chunk_size(i) + (off_t)limit);
+      size_t upper_bound = pages_available * page_size();
+      if (upper_bound > limit &&
+          current_chunk_size(i) < upper_bound - limit) {
+        // The resulting upper bound should not exceed the available
+        // amount of memory (pages_available * page_size()).
+        upper_bound = current_chunk_size(i) + limit;
+      }
+      chunk_size = MIN2(chunk_size, upper_bound);
     } else {
-      chunk_size = MAX2((off_t)chunk_size, (off_t)current_chunk_size(i) - (off_t)limit);
+      size_t lower_bound = page_size();
+      if (current_chunk_size(i) > limit) { // lower_bound shouldn't underflow.
+        lower_bound = current_chunk_size(i) - limit;
+      }
+      chunk_size = MAX2(chunk_size, lower_bound);
     }
   }
   assert(chunk_size <= pages_available * page_size(), "Chunk size out of range");
@@ -675,11 +686,11 @@
       // a minimal object; assuming that's not the last chunk in which case we don't care.
       if (i < lgrp_spaces()->length() - 1) {
         size_t remainder = pointer_delta(s->end(), value);
-        const size_t minimal_object_size = oopDesc::header_size();
-        if (remainder < minimal_object_size && remainder > 0) {
-          // Add a filler object of a minimal size, it will cross the chunk boundary.
-          SharedHeap::fill_region_with_object(MemRegion(value, minimal_object_size));
-          value += minimal_object_size;
+        const size_t min_fill_size = CollectedHeap::min_fill_size();
+        if (remainder < min_fill_size && remainder > 0) {
+          // Add a minimum size filler object; it will cross the chunk boundary.
+          CollectedHeap::fill_with_object(value, min_fill_size);
+          value += min_fill_size;
           assert(!s->contains(value), "Should be in the next chunk");
           // Restart the loop from the same chunk, since the value has moved
           // to the next one.
--- a/hotspot/src/share/vm/gc_interface/collectedHeap.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/gc_interface/collectedHeap.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -30,12 +30,21 @@
 int CollectedHeap::_fire_out_of_memory_count = 0;
 #endif
 
+size_t CollectedHeap::_filler_array_max_size = 0;
+
 // Memory state functions.
 
-CollectedHeap::CollectedHeap() :
-  _reserved(), _barrier_set(NULL), _is_gc_active(false),
-  _total_collections(0), _total_full_collections(0),
-  _gc_cause(GCCause::_no_gc), _gc_lastcause(GCCause::_no_gc) {
+CollectedHeap::CollectedHeap()
+{
+  const size_t max_len = size_t(arrayOopDesc::max_array_length(T_INT));
+  const size_t elements_per_word = HeapWordSize / sizeof(jint);
+  _filler_array_max_size = align_object_size(filler_array_hdr_size() +
+                                             max_len * elements_per_word);
+
+  _barrier_set = NULL;
+  _is_gc_active = false;
+  _total_collections = _total_full_collections = 0;
+  _gc_cause = _gc_lastcause = GCCause::_no_gc;
   NOT_PRODUCT(_promotion_failure_alot_count = 0;)
   NOT_PRODUCT(_promotion_failure_alot_gc_number = 0;)
 
@@ -128,6 +137,94 @@
   return obj;
 }
 
+size_t CollectedHeap::filler_array_hdr_size() {
+  return size_t(arrayOopDesc::header_size(T_INT));
+}
+
+size_t CollectedHeap::filler_array_min_size() {
+  return align_object_size(filler_array_hdr_size());
+}
+
+size_t CollectedHeap::filler_array_max_size() {
+  return _filler_array_max_size;
+}
+
+#ifdef ASSERT
+void CollectedHeap::fill_args_check(HeapWord* start, size_t words)
+{
+  assert(words >= min_fill_size(), "too small to fill");
+  assert(words % MinObjAlignment == 0, "unaligned size");
+  assert(Universe::heap()->is_in_reserved(start), "not in heap");
+  assert(Universe::heap()->is_in_reserved(start + words - 1), "not in heap");
+}
+
+void CollectedHeap::zap_filler_array(HeapWord* start, size_t words)
+{
+  if (ZapFillerObjects) {
+    Copy::fill_to_words(start + filler_array_hdr_size(),
+                        words - filler_array_hdr_size(), 0XDEAFBABE);
+  }
+}
+#endif // ASSERT
+
+void
+CollectedHeap::fill_with_array(HeapWord* start, size_t words)
+{
+  assert(words >= filler_array_min_size(), "too small for an array");
+  assert(words <= filler_array_max_size(), "too big for a single object");
+
+  const size_t payload_size = words - filler_array_hdr_size();
+  const size_t len = payload_size * HeapWordSize / sizeof(jint);
+
+  // Set the length first for concurrent GC.
+  ((arrayOop)start)->set_length((int)len);
+  post_allocation_setup_common(Universe::intArrayKlassObj(), start, words);
+  DEBUG_ONLY(zap_filler_array(start, words);)
+}
+
+void
+CollectedHeap::fill_with_object_impl(HeapWord* start, size_t words)
+{
+  assert(words <= filler_array_max_size(), "too big for a single object");
+
+  if (words >= filler_array_min_size()) {
+    fill_with_array(start, words);
+  } else if (words > 0) {
+    assert(words == min_fill_size(), "unaligned size");
+    post_allocation_setup_common(SystemDictionary::object_klass(), start,
+                                 words);
+  }
+}
+
+void CollectedHeap::fill_with_object(HeapWord* start, size_t words)
+{
+  DEBUG_ONLY(fill_args_check(start, words);)
+  HandleMark hm;  // Free handles before leaving.
+  fill_with_object_impl(start, words);
+}
+
+void CollectedHeap::fill_with_objects(HeapWord* start, size_t words)
+{
+  DEBUG_ONLY(fill_args_check(start, words);)
+  HandleMark hm;  // Free handles before leaving.
+
+#ifdef LP64
+  // A single array can fill ~8G, so multiple objects are needed only in 64-bit.
+  // First fill with arrays, ensuring that any remaining space is big enough to
+  // fill.  The remainder is filled with a single object.
+  const size_t min = min_fill_size();
+  const size_t max = filler_array_max_size();
+  while (words > max) {
+    const size_t cur = words - max >= min ? max : max - min;
+    fill_with_array(start, cur);
+    start += cur;
+    words -= cur;
+  }
+#endif
+
+  fill_with_object_impl(start, words);
+}
+
 oop CollectedHeap::new_store_barrier(oop new_obj) {
   // %%% This needs refactoring.  (It was imported from the server compiler.)
   guarantee(can_elide_tlab_store_barriers(), "store barrier elision not supported");
--- a/hotspot/src/share/vm/gc_interface/collectedHeap.hpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/gc_interface/collectedHeap.hpp	Thu Jan 08 16:34:58 2009 -0800
@@ -47,6 +47,9 @@
   static int       _fire_out_of_memory_count;
 #endif
 
+  // Used for filler objects (static, but initialized in ctor).
+  static size_t _filler_array_max_size;
+
  protected:
   MemRegion _reserved;
   BarrierSet* _barrier_set;
@@ -119,6 +122,21 @@
   // Clears an allocated object.
   inline static void init_obj(HeapWord* obj, size_t size);
 
+  // Filler object utilities.
+  static inline size_t filler_array_hdr_size();
+  static inline size_t filler_array_min_size();
+  static inline size_t filler_array_max_size();
+
+  DEBUG_ONLY(static void fill_args_check(HeapWord* start, size_t words);)
+  DEBUG_ONLY(static void zap_filler_array(HeapWord* start, size_t words);)
+
+  // Fill with a single array; caller must ensure filler_array_min_size() <=
+  // words <= filler_array_max_size().
+  static inline void fill_with_array(HeapWord* start, size_t words);
+
+  // Fill with a single object (either an int array or a java.lang.Object).
+  static inline void fill_with_object_impl(HeapWord* start, size_t words);
+
   // Verification functions
   virtual void check_for_bad_heap_word_value(HeapWord* addr, size_t size)
     PRODUCT_RETURN;
@@ -294,6 +312,27 @@
   // The boundary between a "large" and "small" array of primitives, in words.
   virtual size_t large_typearray_limit() = 0;
 
+  // Utilities for turning raw memory into filler objects.
+  //
+  // min_fill_size() is the smallest region that can be filled.
+  // fill_with_objects() can fill arbitrary-sized regions of the heap using
+  // multiple objects.  fill_with_object() is for regions known to be smaller
+  // than the largest array of integers; it uses a single object to fill the
+  // region and has slightly less overhead.
+  static size_t min_fill_size() {
+    return size_t(align_object_size(oopDesc::header_size()));
+  }
+
+  static void fill_with_objects(HeapWord* start, size_t words);
+
+  static void fill_with_object(HeapWord* start, size_t words);
+  static void fill_with_object(MemRegion region) {
+    fill_with_object(region.start(), region.word_size());
+  }
+  static void fill_with_object(HeapWord* start, HeapWord* end) {
+    fill_with_object(start, pointer_delta(end, start));
+  }
+
   // Some heaps may offer a contiguous region for shared non-blocking
   // allocation, via inlined code (by exporting the address of the top and
   // end fields defining the extent of the contiguous allocation region.)
--- a/hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp	Thu Jan 08 16:34:58 2009 -0800
@@ -34,7 +34,6 @@
 void CollectedHeap::post_allocation_setup_no_klass_install(KlassHandle klass,
                                                            HeapWord* objPtr,
                                                            size_t size) {
-
   oop obj = (oop)objPtr;
 
   assert(obj != NULL, "NULL object pointer");
@@ -44,9 +43,6 @@
     // May be bootstrapping
     obj->set_mark(markOopDesc::prototype());
   }
-
-  // support low memory notifications (no-op if not enabled)
-  LowMemoryDetector::detect_low_memory_for_collected_pools();
 }
 
 void CollectedHeap::post_allocation_install_obj_klass(KlassHandle klass,
@@ -65,6 +61,9 @@
 
 // Support for jvmti and dtrace
 inline void post_allocation_notify(KlassHandle klass, oop obj) {
+  // support low memory notifications (no-op if not enabled)
+  LowMemoryDetector::detect_low_memory_for_collected_pools();
+
   // support for JVMTI VMObjectAlloc event (no-op if not enabled)
   JvmtiExport::vm_object_alloc_event_collector(obj);
 
--- a/hotspot/src/share/vm/includeDB_core	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/includeDB_core	Thu Jan 08 16:34:58 2009 -0800
@@ -2303,6 +2303,7 @@
 javaCalls.cpp                           interfaceSupport.hpp
 javaCalls.cpp                           interpreter.hpp
 javaCalls.cpp                           javaCalls.hpp
+javaCalls.cpp                           jniCheck.hpp
 javaCalls.cpp                           linkResolver.hpp
 javaCalls.cpp                           mutexLocker.hpp
 javaCalls.cpp                           nmethod.hpp
@@ -3434,6 +3435,7 @@
 referenceProcessor.cpp                  systemDictionary.hpp
 
 referenceProcessor.hpp                  instanceRefKlass.hpp
+referenceProcessor.hpp                  referencePolicy.hpp
 
 reflection.cpp                          arguments.hpp
 reflection.cpp                          handles.inline.hpp
--- a/hotspot/src/share/vm/includeDB_features	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/includeDB_features	Thu Jan 08 16:34:58 2009 -0800
@@ -115,6 +115,8 @@
 heapInspection.cpp                      os.hpp
 heapInspection.cpp                      resourceArea.hpp
 
+javaCalls.cpp                           jniCheck.hpp
+
 jniCheck.cpp                            fieldDescriptor.hpp
 jniCheck.cpp                            handles.hpp
 jniCheck.cpp                            instanceKlass.hpp
--- a/hotspot/src/share/vm/includeDB_gc	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/includeDB_gc	Thu Jan 08 16:34:58 2009 -0800
@@ -28,21 +28,22 @@
 collectedHeap.cpp                       collectedHeap.inline.hpp
 collectedHeap.cpp                       init.hpp
 collectedHeap.cpp                       oop.inline.hpp
+collectedHeap.cpp                       systemDictionary.hpp
 collectedHeap.cpp                       thread_<os_family>.inline.hpp
 
 collectedHeap.hpp                       allocation.hpp
 collectedHeap.hpp                       barrierSet.hpp
 collectedHeap.hpp                       gcCause.hpp
 collectedHeap.hpp                       handles.hpp
-collectedHeap.hpp			perfData.hpp
+collectedHeap.hpp                       perfData.hpp
 collectedHeap.hpp                       safepoint.hpp
 
 collectedHeap.inline.hpp                arrayOop.hpp
 collectedHeap.inline.hpp                collectedHeap.hpp
 collectedHeap.inline.hpp                copy.hpp
 collectedHeap.inline.hpp                jvmtiExport.hpp
-collectedHeap.inline.hpp		            lowMemoryDetector.hpp
-collectedHeap.inline.hpp		            sharedRuntime.hpp
+collectedHeap.inline.hpp                lowMemoryDetector.hpp
+collectedHeap.inline.hpp                sharedRuntime.hpp
 collectedHeap.inline.hpp                thread.hpp
 collectedHeap.inline.hpp                threadLocalAllocBuffer.inline.hpp
 collectedHeap.inline.hpp                universe.hpp
--- a/hotspot/src/share/vm/interpreter/bytecodeStream.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/interpreter/bytecodeStream.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/interpreter/bytecodes.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/interpreter/bytecodes.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/interpreter/bytecodes.hpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/interpreter/bytecodes.hpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/memory/cardTableModRefBS.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/memory/cardTableModRefBS.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -283,7 +283,7 @@
     } else {
       entry = byte_after(old_region.last());
     }
-    assert(index_for(new_region.last()) < (int) _guard_index,
+    assert(index_for(new_region.last()) <  _guard_index,
       "The guard card will be overwritten");
     // This line commented out cleans the newly expanded region and
     // not the aligned up expanded region.
--- a/hotspot/src/share/vm/memory/cardTableModRefBS.hpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/memory/cardTableModRefBS.hpp	Thu Jan 08 16:34:58 2009 -0800
@@ -428,7 +428,7 @@
   }
 
   // Mapping from address to card marking array index.
-  int index_for(void* p) {
+  size_t index_for(void* p) {
     assert(_whole_heap.contains(p),
            "out of bounds access to card marking array");
     return byte_for(p) - _byte_map;
--- a/hotspot/src/share/vm/memory/defNewGeneration.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/memory/defNewGeneration.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -540,14 +540,6 @@
   assert(gch->no_allocs_since_save_marks(0),
          "save marks have not been newly set.");
 
-  // Weak refs.
-  // FIXME: Are these storage leaks, or are they resource objects?
-#ifdef COMPILER2
-  ReferencePolicy *soft_ref_policy = new LRUMaxHeapPolicy();
-#else
-  ReferencePolicy *soft_ref_policy = new LRUCurrentHeapPolicy();
-#endif // COMPILER2
-
   // Not very pretty.
   CollectorPolicy* cp = gch->collector_policy();
 
@@ -574,8 +566,10 @@
   evacuate_followers.do_void();
 
   FastKeepAliveClosure keep_alive(this, &scan_weak_ref);
-  ref_processor()->process_discovered_references(
-    soft_ref_policy, &is_alive, &keep_alive, &evacuate_followers, NULL);
+  ReferenceProcessor* rp = ref_processor();
+  rp->setup_policy(clear_all_soft_refs);
+  rp->process_discovered_references(&is_alive, &keep_alive, &evacuate_followers,
+                                    NULL);
   if (!promotion_failed()) {
     // Swap the survivor spaces.
     eden()->clear(SpaceDecorator::Mangle);
--- a/hotspot/src/share/vm/memory/genCollectedHeap.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/memory/genCollectedHeap.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -525,8 +525,9 @@
           if (rp->discovery_is_atomic()) {
             rp->verify_no_references_recorded();
             rp->enable_discovery();
+            rp->setup_policy(clear_all_soft_refs);
           } else {
-            // collect() will enable discovery as appropriate
+            // collect() below will enable discovery as appropriate
           }
           _gens[i]->collect(full, clear_all_soft_refs, size, is_tlab);
           if (!rp->enqueuing_is_done()) {
--- a/hotspot/src/share/vm/memory/genMarkSweep.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/memory/genMarkSweep.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -31,8 +31,9 @@
 
   // hook up weak ref data so it can be used during Mark-Sweep
   assert(ref_processor() == NULL, "no stomping");
+  assert(rp != NULL, "should be non-NULL");
   _ref_processor = rp;
-  assert(rp != NULL, "should be non-NULL");
+  rp->setup_policy(clear_all_softrefs);
 
   TraceTime t1("Full GC", PrintGC && !PrintGCDetails, true, gclog_or_tty);
 
@@ -245,20 +246,9 @@
 
   // Process reference objects found during marking
   {
-    ReferencePolicy *soft_ref_policy;
-    if (clear_all_softrefs) {
-      soft_ref_policy = new AlwaysClearPolicy();
-    } else {
-#ifdef COMPILER2
-      soft_ref_policy = new LRUMaxHeapPolicy();
-#else
-      soft_ref_policy = new LRUCurrentHeapPolicy();
-#endif // COMPILER2
-    }
-    assert(soft_ref_policy != NULL,"No soft reference policy");
+    ref_processor()->setup_policy(clear_all_softrefs);
     ref_processor()->process_discovered_references(
-      soft_ref_policy, &is_alive, &keep_alive,
-      &follow_stack_closure, NULL);
+      &is_alive, &keep_alive, &follow_stack_closure, NULL);
   }
 
   // Follow system dictionary roots and unload classes
--- a/hotspot/src/share/vm/memory/permGen.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/memory/permGen.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -26,20 +26,24 @@
 #include "incls/_permGen.cpp.incl"
 
 HeapWord* PermGen::mem_allocate_in_gen(size_t size, Generation* gen) {
-  MutexLocker ml(Heap_lock);
   GCCause::Cause next_cause = GCCause::_permanent_generation_full;
   GCCause::Cause prev_cause = GCCause::_no_gc;
+  unsigned int gc_count_before, full_gc_count_before;
+  HeapWord* obj;
 
   for (;;) {
-    HeapWord* obj = gen->allocate(size, false);
-    if (obj != NULL) {
-      return obj;
-    }
-    if (gen->capacity() < _capacity_expansion_limit ||
-        prev_cause != GCCause::_no_gc) {
-      obj = gen->expand_and_allocate(size, false);
-    }
-    if (obj == NULL && prev_cause != GCCause::_last_ditch_collection) {
+    {
+      MutexLocker ml(Heap_lock);
+      if ((obj = gen->allocate(size, false)) != NULL) {
+        return obj;
+      }
+      if (gen->capacity() < _capacity_expansion_limit ||
+          prev_cause != GCCause::_no_gc) {
+        obj = gen->expand_and_allocate(size, false);
+      }
+      if (obj != NULL || prev_cause == GCCause::_last_ditch_collection) {
+        return obj;
+      }
       if (GC_locker::is_active_and_needs_gc()) {
         // If this thread is not in a jni critical section, we stall
         // the requestor until the critical section has cleared and
@@ -61,31 +65,27 @@
           return NULL;
         }
       }
+      // Read the GC count while holding the Heap_lock
+      gc_count_before      = SharedHeap::heap()->total_collections();
+      full_gc_count_before = SharedHeap::heap()->total_full_collections();
+    }
 
-      // Read the GC count while holding the Heap_lock
-      unsigned int gc_count_before      = SharedHeap::heap()->total_collections();
-      unsigned int full_gc_count_before = SharedHeap::heap()->total_full_collections();
-      {
-        MutexUnlocker mu(Heap_lock);  // give up heap lock, execute gets it back
-        VM_GenCollectForPermanentAllocation op(size, gc_count_before, full_gc_count_before,
-                                               next_cause);
-        VMThread::execute(&op);
-        if (!op.prologue_succeeded() || op.gc_locked()) {
-          assert(op.result() == NULL, "must be NULL if gc_locked() is true");
-          continue;  // retry and/or stall as necessary
-        }
-        obj = op.result();
-        assert(obj == NULL || SharedHeap::heap()->is_in_reserved(obj),
-               "result not in heap");
-        if (obj != NULL) {
-          return obj;
-        }
-      }
-      prev_cause = next_cause;
-      next_cause = GCCause::_last_ditch_collection;
-    } else {
+    // Give up heap lock above, VMThread::execute below gets it back
+    VM_GenCollectForPermanentAllocation op(size, gc_count_before, full_gc_count_before,
+                                           next_cause);
+    VMThread::execute(&op);
+    if (!op.prologue_succeeded() || op.gc_locked()) {
+      assert(op.result() == NULL, "must be NULL if gc_locked() is true");
+      continue;  // retry and/or stall as necessary
+    }
+    obj = op.result();
+    assert(obj == NULL || SharedHeap::heap()->is_in_reserved(obj),
+           "result not in heap");
+    if (obj != NULL) {
       return obj;
     }
+    prev_cause = next_cause;
+    next_cause = GCCause::_last_ditch_collection;
   }
 }
 
--- a/hotspot/src/share/vm/memory/referencePolicy.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/memory/referencePolicy.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2003 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2000-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,11 @@
 # include "incls/_referencePolicy.cpp.incl"
 
 LRUCurrentHeapPolicy::LRUCurrentHeapPolicy() {
+  setup();
+}
+
+// Capture state (of-the-VM) information needed to evaluate the policy
+void LRUCurrentHeapPolicy::setup() {
   _max_interval = (Universe::get_heap_free_at_last_gc() / M) * SoftRefLRUPolicyMSPerMB;
   assert(_max_interval >= 0,"Sanity check");
 }
@@ -47,6 +52,11 @@
 /////////////////////// MaxHeap //////////////////////
 
 LRUMaxHeapPolicy::LRUMaxHeapPolicy() {
+  setup();
+}
+
+// Capture state (of-the-VM) information needed to evaluate the policy
+void LRUMaxHeapPolicy::setup() {
   size_t max_heap = MaxHeapSize;
   max_heap -= Universe::get_heap_used_at_last_gc();
   max_heap /= M;
--- a/hotspot/src/share/vm/memory/referencePolicy.hpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/memory/referencePolicy.hpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2000-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,9 +26,11 @@
 // should be cleared.
 
 
-class ReferencePolicy : public ResourceObj {
+class ReferencePolicy : public CHeapObj {
  public:
   virtual bool should_clear_reference(oop p)       { ShouldNotReachHere(); return true; }
+  // Capture state (of-the-VM) information needed to evaluate the policy
+  virtual void setup() { /* do nothing */ }
 };
 
 class NeverClearPolicy : public ReferencePolicy {
@@ -48,6 +50,8 @@
  public:
   LRUCurrentHeapPolicy();
 
+  // Capture state (of-the-VM) information needed to evaluate the policy
+  void setup();
   bool should_clear_reference(oop p);
 };
 
@@ -58,5 +62,7 @@
  public:
   LRUMaxHeapPolicy();
 
+  // Capture state (of-the-VM) information needed to evaluate the policy
+  void setup();
   bool should_clear_reference(oop p);
 };
--- a/hotspot/src/share/vm/memory/referenceProcessor.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/memory/referenceProcessor.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -25,6 +25,11 @@
 # include "incls/_precompiled.incl"
 # include "incls/_referenceProcessor.cpp.incl"
 
+ReferencePolicy* ReferenceProcessor::_always_clear_soft_ref_policy = NULL;
+ReferencePolicy* ReferenceProcessor::_default_soft_ref_policy      = NULL;
+oop              ReferenceProcessor::_sentinelRef = NULL;
+const int        subclasses_of_ref                = REF_PHANTOM - REF_OTHER;
+
 // List of discovered references.
 class DiscoveredList {
 public:
@@ -47,7 +52,9 @@
   }
   bool   empty() const          { return head() == ReferenceProcessor::sentinel_ref(); }
   size_t length()               { return _len; }
-  void   set_length(size_t len) { _len = len; }
+  void   set_length(size_t len) { _len = len;  }
+  void   inc_length(size_t inc) { _len += inc; assert(_len > 0, "Error"); }
+  void   dec_length(size_t dec) { _len -= dec; }
 private:
   // Set value depending on UseCompressedOops. This could be a template class
   // but then we have to fix all the instantiations and declarations that use this class.
@@ -56,10 +63,6 @@
   size_t _len;
 };
 
-oop  ReferenceProcessor::_sentinelRef = NULL;
-
-const int subclasses_of_ref = REF_PHANTOM - REF_OTHER;
-
 void referenceProcessor_init() {
   ReferenceProcessor::init_statics();
 }
@@ -80,6 +83,12 @@
   }
   assert(_sentinelRef != NULL && _sentinelRef->is_oop(),
          "Just constructed it!");
+  _always_clear_soft_ref_policy = new AlwaysClearPolicy();
+  _default_soft_ref_policy      = new COMPILER2_PRESENT(LRUMaxHeapPolicy())
+                                      NOT_COMPILER2(LRUCurrentHeapPolicy());
+  if (_always_clear_soft_ref_policy == NULL || _default_soft_ref_policy == NULL) {
+    vm_exit_during_initialization("Could not allocate reference policy object");
+  }
   guarantee(RefDiscoveryPolicy == ReferenceBasedDiscovery ||
             RefDiscoveryPolicy == ReferentBasedDiscovery,
             "Unrecongnized RefDiscoveryPolicy");
@@ -106,6 +115,7 @@
     vm_exit_during_initialization("Could not allocate ReferenceProcessor object");
   }
   rp->set_is_alive_non_header(is_alive_non_header);
+  rp->setup_policy(false /* default soft ref policy */);
   return rp;
 }
 
@@ -192,7 +202,6 @@
 }
 
 void ReferenceProcessor::process_discovered_references(
-  ReferencePolicy*             policy,
   BoolObjectClosure*           is_alive,
   OopClosure*                  keep_alive,
   VoidClosure*                 complete_gc,
@@ -207,7 +216,7 @@
   // Soft references
   {
     TraceTime tt("SoftReference", trace_time, false, gclog_or_tty);
-    process_discovered_reflist(_discoveredSoftRefs, policy, true,
+    process_discovered_reflist(_discoveredSoftRefs, _current_soft_ref_policy, true,
                                is_alive, keep_alive, complete_gc, task_executor);
   }
 
@@ -436,13 +445,13 @@
   // The "allow_null_referent" argument tells us to allow for the possibility
   // of a NULL referent in the discovered Reference object. This typically
   // happens in the case of concurrent collectors that may have done the
-  // discovery concurrently or interleaved with mutator execution.
+  // discovery concurrently, or interleaved, with mutator execution.
   inline void load_ptrs(DEBUG_ONLY(bool allow_null_referent));
 
   // Move to the next discovered reference.
   inline void next();
 
-  // Remove the current reference from the list and move to the next.
+  // Remove the current reference from the list
   inline void remove();
 
   // Make the Reference object active again.
@@ -476,7 +485,6 @@
   inline size_t removed() const   { return _removed; }
   )
 
-private:
   inline void move_to_next();
 
 private:
@@ -553,7 +561,7 @@
     oopDesc::store_heap_oop((oop*)_prev_next, _next);
   }
   NOT_PRODUCT(_removed++);
-  move_to_next();
+  _refs_list.dec_length(1);
 }
 
 inline void DiscoveredListIterator::move_to_next() {
@@ -591,12 +599,13 @@
         gclog_or_tty->print_cr("Dropping reference (" INTPTR_FORMAT ": %s"  ") by policy",
                                iter.obj(), iter.obj()->blueprint()->internal_name());
       }
+      // Remove Reference object from list
+      iter.remove();
       // Make the Reference object active again
       iter.make_active();
       // keep the referent around
       iter.make_referent_alive();
-      // Remove Reference object from list
-      iter.remove();
+      iter.move_to_next();
     } else {
       iter.next();
     }
@@ -629,12 +638,13 @@
                                iter.obj(), iter.obj()->blueprint()->internal_name());
       }
       // The referent is reachable after all.
+      // Remove Reference object from list.
+      iter.remove();
       // Update the referent pointer as necessary: Note that this
       // should not entail any recursive marking because the
       // referent must already have been traversed.
       iter.make_referent_alive();
-      // Remove Reference object from list
-      iter.remove();
+      iter.move_to_next();
     } else {
       iter.next();
     }
@@ -670,6 +680,7 @@
       } else {
         keep_alive->do_oop((oop*)next_addr);
       }
+      iter.move_to_next();
     } else {
       iter.next();
     }
@@ -832,9 +843,9 @@
         }
         java_lang_ref_Reference::set_discovered(move_tail, ref_lists[to_idx].head());
         ref_lists[to_idx].set_head(move_head);
-        ref_lists[to_idx].set_length(ref_lists[to_idx].length() + refs_to_move);
+        ref_lists[to_idx].inc_length(refs_to_move);
         ref_lists[from_idx].set_head(new_head);
-        ref_lists[from_idx].set_length(ref_lists[from_idx].length() - refs_to_move);
+        ref_lists[from_idx].dec_length(refs_to_move);
       } else {
         ++to_idx;
       }
@@ -923,7 +934,6 @@
 void ReferenceProcessor::clean_up_discovered_reflist(DiscoveredList& refs_list) {
   assert(!discovery_is_atomic(), "Else why call this method?");
   DiscoveredListIterator iter(refs_list, NULL, NULL);
-  size_t length = refs_list.length();
   while (iter.has_next()) {
     iter.load_ptrs(DEBUG_ONLY(true /* allow_null_referent */));
     oop next = java_lang_ref_Reference::next(iter.obj());
@@ -941,12 +951,11 @@
       )
       // Remove Reference object from list
       iter.remove();
-      --length;
+      iter.move_to_next();
     } else {
       iter.next();
     }
   }
-  refs_list.set_length(length);
   NOT_PRODUCT(
     if (PrintGCDetails && TraceReferenceGC) {
       gclog_or_tty->print(
@@ -1024,7 +1033,7 @@
     // We have separate lists for enqueueing so no synchronization
     // is necessary.
     refs_list.set_head(obj);
-    refs_list.set_length(refs_list.length() + 1);
+    refs_list.inc_length(1);
     if (_discovered_list_needs_barrier) {
       _bs->write_ref_field((void*)discovered_addr, current_head); guarantee(false, "Needs to be fixed: YSR");
     }
@@ -1090,15 +1099,28 @@
   // reachable.
   if (is_alive_non_header() != NULL) {
     oop referent = java_lang_ref_Reference::referent(obj);
-    // We'd like to assert the following:
-    // assert(referent != NULL, "Refs with null referents already filtered");
-    // However, since this code may be executed concurrently with
-    // mutators, which can clear() the referent, it is not
-    // guaranteed that the referent is non-NULL.
+    // In the case of non-concurrent discovery, the last
+    // disjunct below should hold. It may not hold in the
+    // case of concurrent discovery because mutators may
+    // concurrently clear() a Reference.
+    assert(UseConcMarkSweepGC || UseG1GC || referent != NULL,
+           "Refs with null referents already filtered");
     if (is_alive_non_header()->do_object_b(referent)) {
       return false;  // referent is reachable
     }
   }
+  if (rt == REF_SOFT) {
+    // For soft refs we can decide now if these are not
+    // current candidates for clearing, in which case we
+    // can mark through them now, rather than delaying that
+    // to the reference-processing phase. Since all current
+    // time-stamp policies advance the soft-ref clock only
+    // at a major collection cycle, this is always currently
+    // accurate.
+    if (!_current_soft_ref_policy->should_clear_reference(obj)) {
+      return false;
+    }
+  }
 
   HeapWord* const discovered_addr = java_lang_ref_Reference::discovered_addr(obj);
   const oop  discovered = java_lang_ref_Reference::discovered(obj);
@@ -1168,7 +1190,7 @@
       _bs->write_ref_field((oop*)discovered_addr, current_head);
     }
     list->set_head(obj);
-    list->set_length(list->length() + 1);
+    list->inc_length(1);
   }
 
   // In the MT discovery case, it is currently possible to see
@@ -1209,45 +1231,48 @@
     TraceTime tt("Preclean SoftReferences", PrintGCDetails && PrintReferenceGC,
               false, gclog_or_tty);
     for (int i = 0; i < _num_q; i++) {
+      if (yield->should_return()) {
+        return;
+      }
       preclean_discovered_reflist(_discoveredSoftRefs[i], is_alive,
                                   keep_alive, complete_gc, yield);
     }
   }
-  if (yield->should_return()) {
-    return;
-  }
 
   // Weak references
   {
     TraceTime tt("Preclean WeakReferences", PrintGCDetails && PrintReferenceGC,
               false, gclog_or_tty);
     for (int i = 0; i < _num_q; i++) {
+      if (yield->should_return()) {
+        return;
+      }
       preclean_discovered_reflist(_discoveredWeakRefs[i], is_alive,
                                   keep_alive, complete_gc, yield);
     }
   }
-  if (yield->should_return()) {
-    return;
-  }
 
   // Final references
   {
     TraceTime tt("Preclean FinalReferences", PrintGCDetails && PrintReferenceGC,
               false, gclog_or_tty);
     for (int i = 0; i < _num_q; i++) {
+      if (yield->should_return()) {
+        return;
+      }
       preclean_discovered_reflist(_discoveredFinalRefs[i], is_alive,
                                   keep_alive, complete_gc, yield);
     }
   }
-  if (yield->should_return()) {
-    return;
-  }
 
   // Phantom references
   {
     TraceTime tt("Preclean PhantomReferences", PrintGCDetails && PrintReferenceGC,
               false, gclog_or_tty);
     for (int i = 0; i < _num_q; i++) {
+      if (yield->should_return()) {
+        return;
+      }
       preclean_discovered_reflist(_discoveredPhantomRefs[i], is_alive,
                                   keep_alive, complete_gc, yield);
     }
@@ -1256,9 +1281,12 @@
 
 // Walk the given discovered ref list, and remove all reference objects
 // whose referents are still alive, whose referents are NULL or which
-// are not active (have a non-NULL next field). NOTE: For this to work
-// correctly, refs discovery can not be happening concurrently with this
-// step.
+// are not active (have a non-NULL next field). NOTE: When we are
+// thus precleaning the ref lists (which happens single-threaded today),
+// we do not disable refs discovery to honour the correct semantics of
+// java.lang.Reference. As a result, we need to be careful below
+// that ref removal steps interleave safely with ref discovery steps
+// (in this thread).
 void
 ReferenceProcessor::preclean_discovered_reflist(DiscoveredList&    refs_list,
                                                 BoolObjectClosure* is_alive,
@@ -1266,7 +1294,6 @@
                                                 VoidClosure*       complete_gc,
                                                 YieldClosure*      yield) {
   DiscoveredListIterator iter(refs_list, keep_alive, is_alive);
-  size_t length = refs_list.length();
   while (iter.has_next()) {
     iter.load_ptrs(DEBUG_ONLY(true /* allow_null_referent */));
     oop obj = iter.obj();
@@ -1281,7 +1308,6 @@
       }
       // Remove Reference object from list
       iter.remove();
-      --length;
       // Keep alive its cohort.
       iter.make_referent_alive();
       if (UseCompressedOops) {
@@ -1291,12 +1317,11 @@
         oop* next_addr = (oop*)java_lang_ref_Reference::next_addr(obj);
         keep_alive->do_oop(next_addr);
       }
+      iter.move_to_next();
     } else {
       iter.next();
     }
   }
-  refs_list.set_length(length);
-
   // Close the reachable set
   complete_gc->do_void();
 
--- a/hotspot/src/share/vm/memory/referenceProcessor.hpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/memory/referenceProcessor.hpp	Thu Jan 08 16:34:58 2009 -0800
@@ -23,7 +23,7 @@
  */
 
 // ReferenceProcessor class encapsulates the per-"collector" processing
-// of "weak" references for GC. The interface is useful for supporting
+// of java.lang.Reference objects for GC. The interface is useful for supporting
 // a generational abstraction, in particular when there are multiple
 // generations that are being independently collected -- possibly
 // concurrently and/or incrementally.  Note, however, that the
@@ -75,6 +75,14 @@
   // all collectors but the CMS collector).
   BoolObjectClosure* _is_alive_non_header;
 
+  // Soft ref clearing policies
+  // . the default policy
+  static ReferencePolicy*   _default_soft_ref_policy;
+  // . the "clear all" policy
+  static ReferencePolicy*   _always_clear_soft_ref_policy;
+  // . the current policy below is either one of the above
+  ReferencePolicy*          _current_soft_ref_policy;
+
   // The discovered ref lists themselves
 
   // The MT'ness degree of the queues below
@@ -90,6 +98,12 @@
   DiscoveredList* discovered_soft_refs() { return _discoveredSoftRefs; }
   static oop  sentinel_ref()             { return _sentinelRef; }
   static oop* adr_sentinel_ref()         { return &_sentinelRef; }
+  ReferencePolicy* setup_policy(bool always_clear) {
+    _current_soft_ref_policy = always_clear ?
+      _always_clear_soft_ref_policy : _default_soft_ref_policy;
+    _current_soft_ref_policy->setup();   // snapshot the policy threshold
+    return _current_soft_ref_policy;
+  }
 
  public:
   // Process references with a certain reachability level.
@@ -297,8 +311,7 @@
   bool discover_reference(oop obj, ReferenceType rt);
 
   // Process references found during GC (called by the garbage collector)
-  void process_discovered_references(ReferencePolicy*             policy,
-                                     BoolObjectClosure*           is_alive,
+  void process_discovered_references(BoolObjectClosure*           is_alive,
                                      OopClosure*                  keep_alive,
                                      VoidClosure*                 complete_gc,
                                      AbstractRefProcTaskExecutor* task_executor);
--- a/hotspot/src/share/vm/memory/sharedHeap.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/memory/sharedHeap.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -248,46 +248,6 @@
   perm_gen()->ref_processor_init();
 }
 
-void SharedHeap::fill_region_with_object(MemRegion mr) {
-  // Disable the posting of JVMTI VMObjectAlloc events as we
-  // don't want the filling of tlabs with filler arrays to be
-  // reported to the profiler.
-  NoJvmtiVMObjectAllocMark njm;
-
-  // Disable low memory detector because there is no real allocation.
-  LowMemoryDetectorDisabler lmd_dis;
-
-  // It turns out that post_allocation_setup_array takes a handle, so the
-  // call below contains an implicit conversion.  Best to free that handle
-  // as soon as possible.
-  HandleMark hm;
-
-  size_t word_size = mr.word_size();
-  size_t aligned_array_header_size =
-    align_object_size(typeArrayOopDesc::header_size(T_INT));
-
-  if (word_size >= aligned_array_header_size) {
-    const size_t array_length =
-      pointer_delta(mr.end(), mr.start()) -
-      typeArrayOopDesc::header_size(T_INT);
-    const size_t array_length_words =
-      array_length * (HeapWordSize/sizeof(jint));
-    post_allocation_setup_array(Universe::intArrayKlassObj(),
-                                mr.start(),
-                                mr.word_size(),
-                                (int)array_length_words);
-#ifdef ASSERT
-    HeapWord* elt_words = (mr.start() + typeArrayOopDesc::header_size(T_INT));
-    Copy::fill_to_words(elt_words, array_length, 0xDEAFBABE);
-#endif
-  } else {
-    assert(word_size == (size_t)oopDesc::header_size(), "Unaligned?");
-    post_allocation_setup_obj(SystemDictionary::object_klass(),
-                              mr.start(),
-                              mr.word_size());
-  }
-}
-
 // Some utilities.
 void SharedHeap::print_size_transition(outputStream* out,
                                        size_t bytes_before,
--- a/hotspot/src/share/vm/memory/sharedHeap.hpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/memory/sharedHeap.hpp	Thu Jan 08 16:34:58 2009 -0800
@@ -108,14 +108,6 @@
 
   void set_perm(PermGen* perm_gen) { _perm_gen = perm_gen; }
 
-  // A helper function that fills a region of the heap with
-  // with a single object.
-  static void fill_region_with_object(MemRegion mr);
-
-  // Minimum garbage fill object size
-  static size_t min_fill_size()          { return (size_t)align_object_size(oopDesc::header_size()); }
-  static size_t min_fill_size_in_bytes() { return min_fill_size() * HeapWordSize; }
-
   // This function returns the "GenRemSet" object that allows us to scan
   // generations; at least the perm gen, possibly more in a fully
   // generational heap.
--- a/hotspot/src/share/vm/memory/space.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/memory/space.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -409,19 +409,9 @@
                                         HeapWord* q, size_t deadlength) {
   if (allowed_deadspace_words >= deadlength) {
     allowed_deadspace_words -= deadlength;
-    oop(q)->set_mark(markOopDesc::prototype()->set_marked());
-    const size_t min_int_array_size = typeArrayOopDesc::header_size(T_INT);
-    if (deadlength >= min_int_array_size) {
-      oop(q)->set_klass(Universe::intArrayKlassObj());
-      typeArrayOop(q)->set_length((int)((deadlength - min_int_array_size)
-                                            * (HeapWordSize/sizeof(jint))));
-    } else {
-      assert((int) deadlength == instanceOopDesc::header_size(),
-             "size for smallest fake dead object doesn't match");
-      oop(q)->set_klass(SystemDictionary::object_klass());
-    }
-    assert((int) deadlength == oop(q)->size(),
-           "make sure size for fake dead object match");
+    CollectedHeap::fill_with_object(q, deadlength);
+    oop(q)->set_mark(oop(q)->mark()->set_marked());
+    assert((int) deadlength == oop(q)->size(), "bad filler object size");
     // Recall that we required "q == compaction_top".
     return true;
   } else {
--- a/hotspot/src/share/vm/memory/tenuredGeneration.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/memory/tenuredGeneration.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -387,7 +387,7 @@
               "should contain whole object");
     buf->undo_allocation(obj, word_sz);
   } else {
-    SharedHeap::fill_region_with_object(MemRegion(obj, word_sz));
+    CollectedHeap::fill_with_object(obj, word_sz);
   }
 }
 
--- a/hotspot/src/share/vm/memory/tenuredGeneration.hpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/memory/tenuredGeneration.hpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2001-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/memory/threadLocalAllocBuffer.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/memory/threadLocalAllocBuffer.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -100,8 +100,7 @@
 void ThreadLocalAllocBuffer::make_parsable(bool retire) {
   if (end() != NULL) {
     invariants();
-    MemRegion mr(top(), hard_end());
-    SharedHeap::fill_region_with_object(mr);
+    CollectedHeap::fill_with_object(top(), hard_end());
 
     if (retire || ZeroTLAB) {  // "Reset" the TLAB
       set_start(NULL);
--- a/hotspot/src/share/vm/memory/universe.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/memory/universe.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -49,16 +49,16 @@
 klassOop Universe::_constantPoolCacheKlassObj         = NULL;
 klassOop Universe::_compiledICHolderKlassObj          = NULL;
 klassOop Universe::_systemObjArrayKlassObj            = NULL;
-oop Universe::_int_mirror                             =  NULL;
-oop Universe::_float_mirror                           =  NULL;
-oop Universe::_double_mirror                          =  NULL;
-oop Universe::_byte_mirror                            =  NULL;
-oop Universe::_bool_mirror                            =  NULL;
-oop Universe::_char_mirror                            =  NULL;
-oop Universe::_long_mirror                            =  NULL;
-oop Universe::_short_mirror                           =  NULL;
-oop Universe::_void_mirror                            =  NULL;
-oop Universe::_mirrors[T_VOID+1]                      =  { NULL /*, NULL...*/ };
+oop Universe::_int_mirror                             = NULL;
+oop Universe::_float_mirror                           = NULL;
+oop Universe::_double_mirror                          = NULL;
+oop Universe::_byte_mirror                            = NULL;
+oop Universe::_bool_mirror                            = NULL;
+oop Universe::_char_mirror                            = NULL;
+oop Universe::_long_mirror                            = NULL;
+oop Universe::_short_mirror                           = NULL;
+oop Universe::_void_mirror                            = NULL;
+oop Universe::_mirrors[T_VOID+1]                      = { NULL /*, NULL...*/ };
 oop Universe::_main_thread_group                      = NULL;
 oop Universe::_system_thread_group                    = NULL;
 typeArrayOop Universe::_the_empty_byte_array          = NULL;
@@ -96,7 +96,7 @@
 bool            Universe::_fully_initialized = false;
 
 size_t          Universe::_heap_capacity_at_last_gc;
-size_t          Universe::_heap_used_at_last_gc;
+size_t          Universe::_heap_used_at_last_gc = 0;
 
 CollectedHeap*  Universe::_collectedHeap = NULL;
 address         Universe::_heap_base = NULL;
@@ -257,16 +257,16 @@
         _typeArrayKlassObjs[T_INT]     = _intArrayKlassObj;
         _typeArrayKlassObjs[T_LONG]    = _longArrayKlassObj;
 
-        _methodKlassObj         = methodKlass::create_klass(CHECK);
-        _constMethodKlassObj    = constMethodKlass::create_klass(CHECK);
-        _methodDataKlassObj     = methodDataKlass::create_klass(CHECK);
+        _methodKlassObj             = methodKlass::create_klass(CHECK);
+        _constMethodKlassObj        = constMethodKlass::create_klass(CHECK);
+        _methodDataKlassObj         = methodDataKlass::create_klass(CHECK);
         _constantPoolKlassObj       = constantPoolKlass::create_klass(CHECK);
         _constantPoolCacheKlassObj  = constantPoolCacheKlass::create_klass(CHECK);
 
         _compiledICHolderKlassObj   = compiledICHolderKlass::create_klass(CHECK);
         _systemObjArrayKlassObj     = objArrayKlassKlass::cast(objArrayKlassKlassObj())->allocate_system_objArray_klass(CHECK);
 
-        _the_empty_byte_array      = oopFactory::new_permanent_byteArray(0, CHECK);
+        _the_empty_byte_array       = oopFactory::new_permanent_byteArray(0, CHECK);
         _the_empty_short_array      = oopFactory::new_permanent_shortArray(0, CHECK);
         _the_empty_int_array        = oopFactory::new_permanent_intArray(0, CHECK);
         _the_empty_system_obj_array = oopFactory::new_system_objArray(0, CHECK);
@@ -274,7 +274,6 @@
         _the_array_interfaces_array = oopFactory::new_system_objArray(2, CHECK);
         _vm_exception               = oopFactory::new_symbol("vm exception holder", CHECK);
       } else {
-
         FileMapInfo *mapinfo = FileMapInfo::current_info();
         char* buffer = mapinfo->region_base(CompactingPermGenGen::md);
         void** vtbl_list = (void**)buffer;
--- a/hotspot/src/share/vm/memory/universe.hpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/memory/universe.hpp	Thu Jan 08 16:34:58 2009 -0800
@@ -92,6 +92,7 @@
 
 
 class Universe: AllStatic {
+  // Ugh.  Universe is much too friendly.
   friend class MarkSweep;
   friend class oopDesc;
   friend class ClassLoader;
--- a/hotspot/src/share/vm/oops/arrayOop.hpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/oops/arrayOop.hpp	Thu Jan 08 16:34:58 2009 -0800
@@ -96,19 +96,20 @@
       : typesize_in_bytes/HeapWordSize);
   }
 
-  // This method returns the  maximum length that can passed into
-  // typeArrayOop::object_size(scale, length, header_size) without causing an
-  // overflow. We substract an extra 2*wordSize to guard against double word
-  // alignments.  It gets the scale from the type2aelembytes array.
+  // Return the maximum length of an array of BasicType.  The length can passed
+  // to typeArrayOop::object_size(scale, length, header_size) without causing an
+  // overflow.
   static int32_t max_array_length(BasicType type) {
     assert(type >= 0 && type < T_CONFLICT, "wrong type");
     assert(type2aelembytes(type) != 0, "wrong type");
-    // We use max_jint, since object_size is internally represented by an 'int'
-    // This gives us an upper bound of max_jint words for the size of the oop.
-    int32_t max_words = (max_jint - header_size(type) - 2);
-    int elembytes = type2aelembytes(type);
-    jlong len = ((jlong)max_words * HeapWordSize) / elembytes;
-    return (len > max_jint) ? max_jint : (int32_t)len;
+    const int bytes_per_element = type2aelembytes(type);
+    if (bytes_per_element < HeapWordSize) {
+      return max_jint;
+    }
+
+    const int32_t max_words = align_size_down(max_jint, MinObjAlignment);
+    const int32_t max_element_words = max_words - header_size(type);
+    const int32_t words_per_element = bytes_per_element >> LogHeapWordSize;
+    return max_element_words / words_per_element;
   }
-
 };
--- a/hotspot/src/share/vm/oops/constantPoolOop.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/oops/constantPoolOop.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/oops/oop.inline.hpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/oops/oop.inline.hpp	Thu Jan 08 16:34:58 2009 -0800
@@ -92,7 +92,7 @@
   // This is only to be used during GC, for from-space objects, so no
   // barrier is needed.
   if (UseCompressedOops) {
-    _metadata._compressed_klass = encode_heap_oop_not_null(k);
+    _metadata._compressed_klass = encode_heap_oop(k);  // may be null (parnew overflow handling)
   } else {
     _metadata._klass = (klassOop)k;
   }
--- a/hotspot/src/share/vm/oops/typeArrayKlass.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/oops/typeArrayKlass.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -36,13 +36,14 @@
   return element_type() == tak->element_type();
 }
 
-klassOop typeArrayKlass::create_klass(BasicType type, int scale, TRAPS) {
+klassOop typeArrayKlass::create_klass(BasicType type, int scale,
+                                      const char* name_str, TRAPS) {
   typeArrayKlass o;
 
   symbolHandle sym(symbolOop(NULL));
   // bootstrapping: don't create sym if symbolKlass not created yet
-  if (Universe::symbolKlassObj() != NULL) {
-    sym = oopFactory::new_symbol_handle(external_name(type), CHECK_NULL);
+  if (Universe::symbolKlassObj() != NULL && name_str != NULL) {
+    sym = oopFactory::new_symbol_handle(name_str, CHECK_NULL);
   }
   KlassHandle klassklass (THREAD, Universe::typeArrayKlassKlassObj());
 
--- a/hotspot/src/share/vm/oops/typeArrayKlass.hpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/oops/typeArrayKlass.hpp	Thu Jan 08 16:34:58 2009 -0800
@@ -39,7 +39,11 @@
 
   // klass allocation
   DEFINE_ALLOCATE_PERMANENT(typeArrayKlass);
-  static klassOop create_klass(BasicType type, int scale, TRAPS);
+  static klassOop create_klass(BasicType type, int scale, const char* name_str,
+                               TRAPS);
+  static inline klassOop create_klass(BasicType type, int scale, TRAPS) {
+    return create_klass(type, scale, external_name(type), CHECK_NULL);
+  }
 
   int oop_size(oop obj) const;
   int klass_oop_size() const  { return object_size(); }
--- a/hotspot/src/share/vm/opto/block.hpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/opto/block.hpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/opto/callnode.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/opto/callnode.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -395,7 +395,13 @@
                    OptoReg::regname(OptoReg::c_frame_pointer),
                    regalloc->reg2offset(box_reg));
       }
-      format_helper( regalloc, st, obj, "MON-OBJ[", i, &scobjs );
+      const char* obj_msg = "MON-OBJ[";
+      if (EliminateLocks) {
+        while( !box->is_BoxLock() )  box = box->in(1);
+        if (box->as_BoxLock()->is_eliminated())
+          obj_msg = "MON-OBJ(LOCK ELIMINATED)[";
+      }
+      format_helper( regalloc, st, obj, obj_msg, i, &scobjs );
     }
 
     for (i = 0; i < (uint)scobjs.length(); i++) {
@@ -908,8 +914,9 @@
     add_req(lock->box_node());
     add_req(lock->obj_node());
   } else {
-    add_req(NULL);
-    add_req(NULL);
+    Node* top = Compile::current()->top();
+    add_req(top);
+    add_req(top);
   }
   jvms()->set_scloff(nextmon+MonitorEdges);
   jvms()->set_endoff(req());
@@ -1382,7 +1389,7 @@
     //
     // If we are locking an unescaped object, the lock/unlock is unnecessary
     //
-    ConnectionGraph *cgr = Compile::current()->congraph();
+    ConnectionGraph *cgr = phase->C->congraph();
     PointsToNode::EscapeState es = PointsToNode::GlobalEscape;
     if (cgr != NULL)
       es = cgr->escape_state(obj_node(), phase);
@@ -1450,6 +1457,7 @@
 
           // Mark it eliminated to update any counters
           lock->set_eliminated();
+          lock->set_coarsened();
         }
       } else if (result != NULL && ctrl->is_Region() &&
                  iter->_worklist.member(ctrl)) {
@@ -1484,7 +1492,7 @@
     //
     // If we are unlocking an unescaped object, the lock/unlock is unnecessary.
     //
-    ConnectionGraph *cgr = Compile::current()->congraph();
+    ConnectionGraph *cgr = phase->C->congraph();
     PointsToNode::EscapeState es = PointsToNode::GlobalEscape;
     if (cgr != NULL)
       es = cgr->escape_state(obj_node(), phase);
--- a/hotspot/src/share/vm/opto/callnode.hpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/opto/callnode.hpp	Thu Jan 08 16:34:58 2009 -0800
@@ -780,7 +780,8 @@
 //------------------------------AbstractLockNode-----------------------------------
 class AbstractLockNode: public CallNode {
 private:
- bool _eliminate;    // indicates this lock can be safely eliminated
+  bool _eliminate;    // indicates this lock can be safely eliminated
+  bool _coarsened;    // indicates this lock was coarsened
 #ifndef PRODUCT
   NamedCounter* _counter;
 #endif
@@ -801,6 +802,7 @@
 public:
   AbstractLockNode(const TypeFunc *tf)
     : CallNode(tf, NULL, TypeRawPtr::BOTTOM),
+      _coarsened(false),
       _eliminate(false)
   {
 #ifndef PRODUCT
@@ -819,6 +821,9 @@
   // mark node as eliminated and update the counter if there is one
   void set_eliminated();
 
+  bool is_coarsened()  { return _coarsened; }
+  void set_coarsened() { _coarsened = true; }
+
   // locking does not modify its arguments
   virtual bool        may_modify(const TypePtr *addr_t, PhaseTransform *phase){ return false;}
 
--- a/hotspot/src/share/vm/opto/compile.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/opto/compile.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1532,11 +1532,6 @@
 
   if (failing())  return;
 
-  // get rid of the connection graph since it's information is not
-  // updated by optimizations
-  _congraph = NULL;
-
-
   // Loop transforms on the ideal graph.  Range Check Elimination,
   // peeling, unrolling, etc.
 
@@ -2197,6 +2192,9 @@
 
   case Op_DecodeN:
     assert(!n->in(1)->is_EncodeP(), "should be optimized out");
+    // DecodeN could be pinned on Sparc where it can't be fold into
+    // an address expression, see the code for Op_CastPP above.
+    assert(n->in(0) == NULL || !Matcher::clone_shift_expressions, "no control except on sparc");
     break;
 
   case Op_EncodeP: {
--- a/hotspot/src/share/vm/opto/escape.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/opto/escape.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -199,7 +199,8 @@
   es = ptnode_adr(idx)->escape_state();
 
   // if we have already computed a value, return it
-  if (es != PointsToNode::UnknownEscape)
+  if (es != PointsToNode::UnknownEscape &&
+      ptnode_adr(idx)->node_type() == PointsToNode::JavaObject)
     return es;
 
   // PointsTo() calls n->uncast() which can return a new ideal node.
--- a/hotspot/src/share/vm/opto/locknode.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/opto/locknode.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -44,10 +44,15 @@
   _inmask.Insert(reg);
 }
 
+//-----------------------------hash--------------------------------------------
+uint BoxLockNode::hash() const {
+  return Node::hash() + _slot + (_is_eliminated ? Compile::current()->fixed_slots() : 0);
+}
+
 //------------------------------cmp--------------------------------------------
 uint BoxLockNode::cmp( const Node &n ) const {
   const BoxLockNode &bn = (const BoxLockNode &)n;
-  return bn._slot == _slot;
+  return bn._slot == _slot && bn._is_eliminated == _is_eliminated;
 }
 
 OptoReg::Name BoxLockNode::stack_slot(Node* box_node) {
--- a/hotspot/src/share/vm/opto/locknode.hpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/opto/locknode.hpp	Thu Jan 08 16:34:58 2009 -0800
@@ -36,7 +36,7 @@
   virtual const RegMask &in_RegMask(uint) const;
   virtual const RegMask &out_RegMask() const;
   virtual uint size_of() const;
-  virtual uint hash() const { return Node::hash() + _slot; }
+  virtual uint hash() const;
   virtual uint cmp( const Node &n ) const;
   virtual const class Type *bottom_type() const { return TypeRawPtr::BOTTOM; }
   virtual uint ideal_reg() const { return Op_RegP; }
--- a/hotspot/src/share/vm/opto/macro.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/opto/macro.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -59,7 +59,7 @@
   for (uint i = old_dbg_start; i < oldcall->req(); i++) {
     Node* old_in = oldcall->in(i);
     // Clone old SafePointScalarObjectNodes, adjusting their field contents.
-    if (old_in->is_SafePointScalarObject()) {
+    if (old_in != NULL && old_in->is_SafePointScalarObject()) {
       SafePointScalarObjectNode* old_sosn = old_in->as_SafePointScalarObject();
       uint old_unique = C->unique();
       Node* new_in = old_sosn->clone(jvms_adj, sosn_map);
@@ -1509,21 +1509,63 @@
   if (!alock->is_eliminated()) {
     return false;
   }
-  // Mark the box lock as eliminated if all correspondent locks are eliminated
-  // to construct correct debug info.
-  BoxLockNode* box = alock->box_node()->as_BoxLock();
-  if (!box->is_eliminated()) {
-    bool eliminate = true;
-    for (DUIterator_Fast imax, i = box->fast_outs(imax); i < imax; i++) {
-      Node *lck = box->fast_out(i);
-      if (lck->is_Lock() && !lck->as_AbstractLock()->is_eliminated()) {
-        eliminate = false;
-        break;
-      }
-    }
-    if (eliminate)
-      box->set_eliminated();
-  }
+  if (alock->is_Lock() && !alock->is_coarsened()) {
+      // Create new "eliminated" BoxLock node and use it
+      // in monitor debug info for the same object.
+      BoxLockNode* oldbox = alock->box_node()->as_BoxLock();
+      Node* obj = alock->obj_node();
+      if (!oldbox->is_eliminated()) {
+        BoxLockNode* newbox = oldbox->clone()->as_BoxLock();
+        newbox->set_eliminated();
+        transform_later(newbox);
+        // Replace old box node with new box for all users
+        // of the same object.
+        for (uint i = 0; i < oldbox->outcnt();) {
+
+          bool next_edge = true;
+          Node* u = oldbox->raw_out(i);
+          if (u == alock) {
+            i++;
+            continue; // It will be removed below
+          }
+          if (u->is_Lock() &&
+              u->as_Lock()->obj_node() == obj &&
+              // oldbox could be referenced in debug info also
+              u->as_Lock()->box_node() == oldbox) {
+            assert(u->as_Lock()->is_eliminated(), "sanity");
+            _igvn.hash_delete(u);
+            u->set_req(TypeFunc::Parms + 1, newbox);
+            next_edge = false;
+#ifdef ASSERT
+          } else if (u->is_Unlock() && u->as_Unlock()->obj_node() == obj) {
+            assert(u->as_Unlock()->is_eliminated(), "sanity");
+#endif
+          }
+          // Replace old box in monitor debug info.
+          if (u->is_SafePoint() && u->as_SafePoint()->jvms()) {
+            SafePointNode* sfn = u->as_SafePoint();
+            JVMState* youngest_jvms = sfn->jvms();
+            int max_depth = youngest_jvms->depth();
+            for (int depth = 1; depth <= max_depth; depth++) {
+              JVMState* jvms = youngest_jvms->of_depth(depth);
+              int num_mon  = jvms->nof_monitors();
+              // Loop over monitors
+              for (int idx = 0; idx < num_mon; idx++) {
+                Node* obj_node = sfn->monitor_obj(jvms, idx);
+                Node* box_node = sfn->monitor_box(jvms, idx);
+                if (box_node == oldbox && obj_node == obj) {
+                  int j = jvms->monitor_box_offset(idx);
+                  _igvn.hash_delete(u);
+                  u->set_req(j, newbox);
+                  next_edge = false;
+                }
+              } // for (int idx = 0;
+            } // for (int depth = 1;
+          } // if (u->is_SafePoint()
+          if (next_edge) i++;
+        } // for (uint i = 0; i < oldbox->outcnt();)
+      } // if (!oldbox->is_eliminated())
+  } // if (alock->is_Lock() && !lock->is_coarsened())
 
   #ifndef PRODUCT
   if (PrintEliminateLocks) {
@@ -1562,6 +1604,15 @@
     _igvn.subsume_node(ctrlproj, fallthroughproj);
     _igvn.hash_delete(memproj);
     _igvn.subsume_node(memproj, memproj_fallthrough);
+
+    // Delete FastLock node also if this Lock node is unique user
+    // (a loop peeling may clone a Lock node).
+    Node* flock = alock->as_Lock()->fastlock_node();
+    if (flock->outcnt() == 1) {
+      assert(flock->unique_out() == alock, "sanity");
+      _igvn.hash_delete(flock);
+      _igvn.subsume_node(flock, top());
+    }
   }
 
   // Seach for MemBarRelease node and delete it also.
@@ -1673,6 +1724,13 @@
     if (klass_node == NULL) {
       Node* k_adr = basic_plus_adr(obj, oopDesc::klass_offset_in_bytes());
       klass_node = transform_later( LoadKlassNode::make(_igvn, mem, k_adr, _igvn.type(k_adr)->is_ptr()) );
+#ifdef _LP64
+      if (UseCompressedOops && klass_node->is_DecodeN()) {
+        assert(klass_node->in(1)->Opcode() == Op_LoadNKlass, "sanity");
+        klass_node->in(1)->init_req(0, ctrl);
+      } else
+#endif
+      klass_node->init_req(0, ctrl);
     }
     Node *proto_node = make_load(ctrl, mem, klass_node, Klass::prototype_header_offset_in_bytes() + sizeof(oopDesc), TypeX_X, TypeX_X->basic_type());
 
@@ -1887,7 +1945,7 @@
 bool PhaseMacroExpand::expand_macro_nodes() {
   if (C->macro_count() == 0)
     return false;
-  // attempt to eliminate allocations
+  // First, attempt to eliminate locks
   bool progress = true;
   while (progress) {
     progress = false;
@@ -1895,6 +1953,26 @@
       Node * n = C->macro_node(i-1);
       bool success = false;
       debug_only(int old_macro_count = C->macro_count(););
+      if (n->is_AbstractLock()) {
+        success = eliminate_locking_node(n->as_AbstractLock());
+      } else if (n->Opcode() == Op_Opaque1 || n->Opcode() == Op_Opaque2) {
+        _igvn.add_users_to_worklist(n);
+        _igvn.hash_delete(n);
+        _igvn.subsume_node(n, n->in(1));
+        success = true;
+      }
+      assert(success == (C->macro_count() < old_macro_count), "elimination reduces macro count");
+      progress = progress || success;
+    }
+  }
+  // Next, attempt to eliminate allocations
+  progress = true;
+  while (progress) {
+    progress = false;
+    for (int i = C->macro_count(); i > 0; i--) {
+      Node * n = C->macro_node(i-1);
+      bool success = false;
+      debug_only(int old_macro_count = C->macro_count(););
       switch (n->class_id()) {
       case Node::Class_Allocate:
       case Node::Class_AllocateArray:
@@ -1902,17 +1980,10 @@
         break;
       case Node::Class_Lock:
       case Node::Class_Unlock:
-        success = eliminate_locking_node(n->as_AbstractLock());
+        assert(!n->as_AbstractLock()->is_eliminated(), "sanity");
         break;
       default:
-        if (n->Opcode() == Op_Opaque1 || n->Opcode() == Op_Opaque2) {
-          _igvn.add_users_to_worklist(n);
-          _igvn.hash_delete(n);
-          _igvn.subsume_node(n, n->in(1));
-          success = true;
-        } else {
-          assert(false, "unknown node type in macro list");
-        }
+        assert(false, "unknown node type in macro list");
       }
       assert(success == (C->macro_count() < old_macro_count), "elimination reduces macro count");
       progress = progress || success;
--- a/hotspot/src/share/vm/opto/output.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/opto/output.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -849,10 +849,8 @@
     // Loop over monitors and insert into array
     for(idx = 0; idx < num_mon; idx++) {
       // Grab the node that defines this monitor
-      Node* box_node;
-      Node* obj_node;
-      box_node = sfn->monitor_box(jvms, idx);
-      obj_node = sfn->monitor_obj(jvms, idx);
+      Node* box_node = sfn->monitor_box(jvms, idx);
+      Node* obj_node = sfn->monitor_obj(jvms, idx);
 
       // Create ScopeValue for object
       ScopeValue *scval = NULL;
@@ -890,6 +888,7 @@
 
       OptoReg::Name box_reg = BoxLockNode::stack_slot(box_node);
       Location basic_lock = Location::new_stk_loc(Location::normal,_regalloc->reg2offset(box_reg));
+      while( !box_node->is_BoxLock() )  box_node = box_node->in(1);
       monarray->append(new MonitorValue(scval, basic_lock, box_node->as_BoxLock()->is_eliminated()));
     }
 
--- a/hotspot/src/share/vm/opto/phase.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/opto/phase.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/opto/phase.hpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/opto/phase.hpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/prims/jni.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/prims/jni.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -2173,7 +2173,8 @@
     size_t size = os::vm_allocation_granularity();
     bad_address = os::reserve_memory(size);
     if (bad_address != NULL) {
-      os::protect_memory(bad_address, size, os::MEM_PROT_READ);
+      os::protect_memory(bad_address, size, os::MEM_PROT_READ,
+                         /*is_committed*/false);
     }
   }
   return bad_address;
--- a/hotspot/src/share/vm/prims/jniCheck.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/prims/jniCheck.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2001-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -112,18 +112,6 @@
 static const char * fatal_non_string = "JNI string operation received a non-string";
 
 
-
-// Report a JNI failure caught by -Xcheck:jni.  Perform a core dump.
-// Note: two variations -- one to be called when in VM state (e.g. when
-// within IN_VM macro), one to be called when in NATIVE state.
-
-// When in VM state:
-static void ReportJNIFatalError(JavaThread* thr, const char *msg) {
-  tty->print_cr("FATAL ERROR in native method: %s", msg);
-  thr->print_stack();
-  os::abort(true);
-}
-
 // When in VM state:
 static void ReportJNIWarning(JavaThread* thr, const char *msg) {
   tty->print_cr("WARNING in native method: %s", msg);
--- a/hotspot/src/share/vm/prims/jniCheck.hpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/prims/jniCheck.hpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -22,6 +22,19 @@
  *
  */
 
+extern "C" {
+  // Report a JNI failure caught by -Xcheck:jni.  Perform a core dump.
+  // Note: two variations -- one to be called when in VM state (e.g. when
+  // within IN_VM macro), one to be called when in NATIVE state.
+
+  // When in VM state:
+  static void ReportJNIFatalError(JavaThread* thr, const char *msg) {
+    tty->print_cr("FATAL ERROR in native method: %s", msg);
+    thr->print_stack();
+    os::abort(true);
+  }
+}
+
 //
 // Checked JNI routines that are useful for outside of checked JNI
 //
--- a/hotspot/src/share/vm/prims/jvmtiEnvBase.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/prims/jvmtiEnvBase.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/prims/jvmtiTrace.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/prims/jvmtiTrace.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/runtime/arguments.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/runtime/arguments.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -444,9 +444,9 @@
 }
 
 // Parses a memory size specification string.
-static bool atomll(const char *s, jlong* result) {
-  jlong n = 0;
-  int args_read = sscanf(s, os::jlong_format_specifier(), &n);
+static bool atomull(const char *s, julong* result) {
+  julong n = 0;
+  int args_read = sscanf(s, os::julong_format_specifier(), &n);
   if (args_read != 1) {
     return false;
   }
@@ -460,15 +460,20 @@
   switch (*s) {
     case 'T': case 't':
       *result = n * G * K;
+      // Check for overflow.
+      if (*result/((julong)G * K) != n) return false;
       return true;
     case 'G': case 'g':
       *result = n * G;
+      if (*result/G != n) return false;
       return true;
     case 'M': case 'm':
       *result = n * M;
+      if (*result/M != n) return false;
       return true;
     case 'K': case 'k':
       *result = n * K;
+      if (*result/K != n) return false;
       return true;
     case '\0':
       *result = n;
@@ -478,10 +483,10 @@
   }
 }
 
-Arguments::ArgsRange Arguments::check_memory_size(jlong size, jlong min_size) {
+Arguments::ArgsRange Arguments::check_memory_size(julong size, julong min_size) {
   if (size < min_size) return arg_too_small;
   // Check that size will fit in a size_t (only relevant on 32-bit)
-  if ((julong) size > max_uintx) return arg_too_big;
+  if (size > max_uintx) return arg_too_big;
   return arg_in_range;
 }
 
@@ -522,10 +527,10 @@
 
 
 static bool set_numeric_flag(char* name, char* value, FlagValueOrigin origin) {
-  jlong v;
+  julong v;
   intx intx_v;
   bool is_neg = false;
-  // Check the sign first since atomll() parses only unsigned values.
+  // Check the sign first since atomull() parses only unsigned values.
   if (*value == '-') {
     if (!CommandLineFlags::intxAt(name, &intx_v)) {
       return false;
@@ -533,7 +538,7 @@
     value++;
     is_neg = true;
   }
-  if (!atomll(value, &v)) {
+  if (!atomull(value, &v)) {
     return false;
   }
   intx_v = (intx) v;
@@ -1517,6 +1522,16 @@
     MarkSweepAlwaysCompactCount = 1;  // Move objects every gc.
   }
 
+  if (UseParallelOldGC && ParallelOldGCSplitALot) {
+    // Settings to encourage splitting.
+    if (!FLAG_IS_CMDLINE(NewRatio)) {
+      FLAG_SET_CMDLINE(intx, NewRatio, 2);
+    }
+    if (!FLAG_IS_CMDLINE(ScavengeBeforeFullGC)) {
+      FLAG_SET_CMDLINE(bool, ScavengeBeforeFullGC, false);
+    }
+  }
+
   status = status && verify_percentage(GCHeapFreeLimit, "GCHeapFreeLimit");
   status = status && verify_percentage(GCTimeLimit, "GCTimeLimit");
   if (GCTimeLimit == 100) {
@@ -1667,9 +1682,9 @@
 }
 
 Arguments::ArgsRange Arguments::parse_memory_size(const char* s,
-                                                  jlong* long_arg,
-                                                  jlong min_size) {
-  if (!atomll(s, long_arg)) return arg_unreadable;
+                                                  julong* long_arg,
+                                                  julong min_size) {
+  if (!atomull(s, long_arg)) return arg_unreadable;
   return check_memory_size(*long_arg, min_size);
 }
 
@@ -1847,7 +1862,7 @@
       FLAG_SET_CMDLINE(bool, BackgroundCompilation, false);
     // -Xmn for compatibility with other JVM vendors
     } else if (match_option(option, "-Xmn", &tail)) {
-      jlong long_initial_eden_size = 0;
+      julong long_initial_eden_size = 0;
       ArgsRange errcode = parse_memory_size(tail, &long_initial_eden_size, 1);
       if (errcode != arg_in_range) {
         jio_fprintf(defaultStream::error_stream(),
@@ -1859,7 +1874,7 @@
       FLAG_SET_CMDLINE(uintx, NewSize, (size_t) long_initial_eden_size);
     // -Xms
     } else if (match_option(option, "-Xms", &tail)) {
-      jlong long_initial_heap_size = 0;
+      julong long_initial_heap_size = 0;
       ArgsRange errcode = parse_memory_size(tail, &long_initial_heap_size, 1);
       if (errcode != arg_in_range) {
         jio_fprintf(defaultStream::error_stream(),
@@ -1872,7 +1887,7 @@
       set_min_heap_size(initial_heap_size());
     // -Xmx
     } else if (match_option(option, "-Xmx", &tail)) {
-      jlong long_max_heap_size = 0;
+      julong long_max_heap_size = 0;
       ArgsRange errcode = parse_memory_size(tail, &long_max_heap_size, 1);
       if (errcode != arg_in_range) {
         jio_fprintf(defaultStream::error_stream(),
@@ -1905,7 +1920,7 @@
       }
     // -Xss
     } else if (match_option(option, "-Xss", &tail)) {
-      jlong long_ThreadStackSize = 0;
+      julong long_ThreadStackSize = 0;
       ArgsRange errcode = parse_memory_size(tail, &long_ThreadStackSize, 1000);
       if (errcode != arg_in_range) {
         jio_fprintf(defaultStream::error_stream(),
@@ -1921,9 +1936,9 @@
           // HotSpot does not have separate native and Java stacks, ignore silently for compatibility
     // -Xmaxjitcodesize
     } else if (match_option(option, "-Xmaxjitcodesize", &tail)) {
-      jlong long_ReservedCodeCacheSize = 0;
+      julong long_ReservedCodeCacheSize = 0;
       ArgsRange errcode = parse_memory_size(tail, &long_ReservedCodeCacheSize,
-                                            InitialCodeCacheSize);
+                                            (size_t)InitialCodeCacheSize);
       if (errcode != arg_in_range) {
         jio_fprintf(defaultStream::error_stream(),
                     "Invalid maximum code cache size: %s\n",
@@ -2228,7 +2243,7 @@
     } else if (match_option(option, "-XX:TLEFragmentationRatio=", &tail)) {
       // No longer used.
     } else if (match_option(option, "-XX:TLESize=", &tail)) {
-      jlong long_tlab_size = 0;
+      julong long_tlab_size = 0;
       ArgsRange errcode = parse_memory_size(tail, &long_tlab_size, 1);
       if (errcode != arg_in_range) {
         jio_fprintf(defaultStream::error_stream(),
@@ -2283,7 +2298,7 @@
         "-XX:ParCMSPromoteBlocksToClaim in the future\n");
     } else
     if (match_option(option, "-XX:ParallelGCOldGenAllocBufferSize=", &tail)) {
-      jlong old_plab_size = 0;
+      julong old_plab_size = 0;
       ArgsRange errcode = parse_memory_size(tail, &old_plab_size, 1);
       if (errcode != arg_in_range) {
         jio_fprintf(defaultStream::error_stream(),
@@ -2291,13 +2306,13 @@
         describe_range_error(errcode);
         return JNI_EINVAL;
       }
-      FLAG_SET_CMDLINE(uintx, OldPLABSize, (julong)old_plab_size);
+      FLAG_SET_CMDLINE(uintx, OldPLABSize, old_plab_size);
       jio_fprintf(defaultStream::error_stream(),
                   "Please use -XX:OldPLABSize in place of "
                   "-XX:ParallelGCOldGenAllocBufferSize in the future\n");
     } else
     if (match_option(option, "-XX:ParallelGCToSpaceAllocBufferSize=", &tail)) {
-      jlong young_plab_size = 0;
+      julong young_plab_size = 0;
       ArgsRange errcode = parse_memory_size(tail, &young_plab_size, 1);
       if (errcode != arg_in_range) {
         jio_fprintf(defaultStream::error_stream(),
@@ -2305,7 +2320,7 @@
         describe_range_error(errcode);
         return JNI_EINVAL;
       }
-      FLAG_SET_CMDLINE(uintx, YoungPLABSize, (julong)young_plab_size);
+      FLAG_SET_CMDLINE(uintx, YoungPLABSize, young_plab_size);
       jio_fprintf(defaultStream::error_stream(),
                   "Please use -XX:YoungPLABSize in place of "
                   "-XX:ParallelGCToSpaceAllocBufferSize in the future\n");
@@ -2322,7 +2337,12 @@
       return JNI_ERR;
     }
   }
-
+  // Change the default value for flags  which have different default values
+  // when working with older JDKs.
+  if (JDK_Version::current().compare_major(6) <= 0 &&
+      FLAG_IS_DEFAULT(UseVMInterruptibleIO)) {
+    FLAG_SET_DEFAULT(UseVMInterruptibleIO, true);
+  }
   return JNI_OK;
 }
 
--- a/hotspot/src/share/vm/runtime/arguments.hpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/runtime/arguments.hpp	Thu Jan 08 16:34:58 2009 -0800
@@ -339,9 +339,9 @@
   }
   static bool verify_percentage(uintx value, const char* name);
   static void describe_range_error(ArgsRange errcode);
-  static ArgsRange check_memory_size(jlong size, jlong min_size);
-  static ArgsRange parse_memory_size(const char* s, jlong* long_arg,
-                                     jlong min_size);
+  static ArgsRange check_memory_size(julong size, julong min_size);
+  static ArgsRange parse_memory_size(const char* s, julong* long_arg,
+                                     julong min_size);
 
   // methods to build strings from individual args
   static void build_jvm_args(const char* arg);
--- a/hotspot/src/share/vm/runtime/biasedLocking.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/runtime/biasedLocking.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -582,13 +582,19 @@
   if (heuristics == HR_NOT_BIASED) {
     return NOT_BIASED;
   } else if (heuristics == HR_SINGLE_REVOKE) {
-    if (mark->biased_locker() == THREAD) {
+    Klass *k = Klass::cast(obj->klass());
+    markOop prototype_header = k->prototype_header();
+    if (mark->biased_locker() == THREAD &&
+        prototype_header->bias_epoch() == mark->bias_epoch()) {
       // A thread is trying to revoke the bias of an object biased
       // toward it, again likely due to an identity hash code
       // computation. We can again avoid a safepoint in this case
       // since we are only going to walk our own stack. There are no
       // races with revocations occurring in other threads because we
       // reach no safepoints in the revocation path.
+      // Also check the epoch because even if threads match, another thread
+      // can come in with a CAS to steal the bias of an object that has a
+      // stale epoch.
       ResourceMark rm;
       if (TraceBiasedLocking) {
         tty->print_cr("Revoking bias by walking my own stack:");
--- a/hotspot/src/share/vm/runtime/globals.hpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/runtime/globals.hpp	Thu Jan 08 16:34:58 2009 -0800
@@ -342,6 +342,9 @@
   product(bool, UseNUMA, false,                                             \
           "Use NUMA if available")                                          \
                                                                             \
+  product(bool, ForceNUMA, false,                                           \
+          "Force NUMA optimizations on single-node/UMA systems")            \
+                                                                            \
   product(intx, NUMAChunkResizeWeight, 20,                                  \
           "Percentage (0-100) used to weight the current sample when "      \
           "computing exponentially decaying average for "                   \
@@ -622,6 +625,9 @@
   develop(bool, CheckZapUnusedHeapArea, false,                              \
           "Check zapping of unused heap space")                             \
                                                                             \
+  develop(bool, ZapFillerObjects, trueInDebug,                              \
+          "Zap filler objects with 0xDEAFBABE")                             \
+                                                                            \
   develop(bool, PrintVMMessages, true,                                      \
           "Print vm messages on console")                                   \
                                                                             \
@@ -815,7 +821,7 @@
   product(bool, ClassUnloading, true,                                       \
           "Do unloading of classes")                                        \
                                                                             \
-  diagnostic(bool, LinkWellKnownClasses, true,                              \
+  diagnostic(bool, LinkWellKnownClasses, false,                             \
           "Resolve a well known class as soon as its name is seen")         \
                                                                             \
   develop(bool, DisableStartThread, false,                                  \
@@ -1197,11 +1203,12 @@
   product(uintx, ParallelCMSThreads, 0,                                     \
           "Max number of threads CMS will use for concurrent work")         \
                                                                             \
-  develop(bool, ParallelOldMTUnsafeMarkBitMap, false,                       \
-          "Use the Parallel Old MT unsafe in marking the bitmap")           \
-                                                                            \
-  develop(bool, ParallelOldMTUnsafeUpdateLiveData, false,                   \
-          "Use the Parallel Old MT unsafe in update of live size")          \
+  develop(bool, ParallelOldGCSplitALot, false,                              \
+          "Provoke splitting (copying data from a young gen space to"       \
+          "multiple destination spaces)")                                   \
+                                                                            \
+  develop(uintx, ParallelOldGCSplitInterval, 3,                             \
+          "How often to provoke splitting a young gen space")               \
                                                                             \
   develop(bool, TraceRegionTasksQueuing, false,                             \
           "Trace the queuing of the region tasks")                          \
@@ -1474,7 +1481,7 @@
           "CMSPrecleanNumerator:CMSPrecleanDenominator yields convergence"  \
           " ratio")                                                         \
                                                                             \
-  product(bool, CMSPrecleanRefLists1, false,                                \
+  product(bool, CMSPrecleanRefLists1, true,                                 \
           "Preclean ref lists during (initial) preclean phase")             \
                                                                             \
   product(bool, CMSPrecleanRefLists2, false,                                \
@@ -3262,9 +3269,10 @@
   diagnostic(bool, PrintDTraceDOF, false,                                   \
              "Print the DTrace DOF passed to the system for JSDT probes")   \
                                                                             \
-  product(bool, UseVMInterruptibleIO, true,                                 \
+  product(bool, UseVMInterruptibleIO, false,                                \
           "(Unstable, Solaris-specific) Thread interrupt before or with "   \
-          "EINTR for I/O operations results in OS_INTRPT")
+          "EINTR for I/O operations results in OS_INTRPT. The default value"\
+          " of this flag is true for JDK 6 and earliers")
 
 
 /*
--- a/hotspot/src/share/vm/runtime/javaCalls.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/runtime/javaCalls.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -309,8 +309,12 @@
 
   CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops();)
 
-  // Make sure that the arguments have the right type
-  debug_only(args->verify(method, result->get_type(), thread));
+  // Verify the arguments
+
+  if (CheckJNICalls)  {
+    args->verify(method, result->get_type(), thread);
+  }
+  else debug_only(args->verify(method, result->get_type(), thread));
 
   // Ignore call if method is empty
   if (method->is_empty_method()) {
@@ -431,24 +435,26 @@
   return TaggedStackInterpreter ? _parameters : _value;
 }
 
-//--------------------------------------------------------------------------------------
-// Non-Product code
-#ifndef PRODUCT
 
 class SignatureChekker : public SignatureIterator {
  private:
    bool *_is_oop;
    int   _pos;
    BasicType _return_type;
+   intptr_t*   _value;
+   Thread* _thread;
 
  public:
   bool _is_return;
 
-  SignatureChekker(symbolHandle signature, BasicType return_type, bool is_static, bool* is_oop) : SignatureIterator(signature) {
+  SignatureChekker(symbolHandle signature, BasicType return_type, bool is_static, bool* is_oop, intptr_t* value, Thread* thread) : SignatureIterator(signature) {
     _is_oop = is_oop;
     _is_return = false;
     _return_type = return_type;
     _pos = 0;
+    _value = value;
+    _thread = thread;
+
     if (!is_static) {
       check_value(true); // Receiver must be an oop
     }
@@ -489,6 +495,24 @@
       check_return_type(t);
       return;
     }
+
+    // verify handle and the oop pointed to by handle
+    int p = _pos;
+    bool bad = false;
+    // If argument is oop
+    if (_is_oop[p]) {
+      intptr_t v = _value[p];
+      if (v != 0 ) {
+        size_t t = (size_t)v;
+        bad = (t < (size_t)os::vm_page_size() ) || !Handle::raw_resolve((oop *)v)->is_oop_or_null(true);
+        if (CheckJNICalls && bad) {
+          ReportJNIFatalError((JavaThread*)_thread, "Bad JNI oop argument");
+        }
+      }
+      // for the regular debug case.
+      assert(!bad, "Bad JNI oop argument");
+    }
+
     check_value(true);
   }
 
@@ -505,6 +529,7 @@
   void do_array(int begin, int end)    { check_obj(T_OBJECT);        }
 };
 
+
 void JavaCallArguments::verify(methodHandle method, BasicType return_type,
   Thread *thread) {
   guarantee(method->size_of_parameters() == size_of_parameters(), "wrong no. of arguments pushed");
@@ -515,10 +540,9 @@
   // Check that oop information is correct
   symbolHandle signature (thread,  method->signature());
 
-  SignatureChekker sc(signature, return_type, method->is_static(),_is_oop);
+  SignatureChekker sc(signature, return_type, method->is_static(),_is_oop, _value, thread);
   sc.iterate_parameters();
   sc.check_doing_return(true);
   sc.iterate_returntype();
 }
 
-#endif // PRODUCT
--- a/hotspot/src/share/vm/runtime/javaCalls.hpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/runtime/javaCalls.hpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -150,7 +150,7 @@
   int   size_of_parameters() const { return _size; }
 
   // Verify that pushed arguments fits a given method
-  void verify(methodHandle method, BasicType return_type, Thread *thread) PRODUCT_RETURN;
+  void verify(methodHandle method, BasicType return_type, Thread *thread);
 };
 
 // All calls to Java have to go via JavaCalls. Sets up the stack frame
--- a/hotspot/src/share/vm/runtime/os.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/runtime/os.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -932,8 +932,9 @@
   // the mutator thread if such case is encountered. See bug 6546278 for details.
   Thread::muxAcquire(&SerializePageLock, "serialize_thread_states");
   os::protect_memory((char *)os::get_memory_serialize_page(),
-                     os::vm_page_size(), MEM_PROT_READ, /*is_committed*/true );
-  os::unguard_memory((char *)os::get_memory_serialize_page(), os::vm_page_size());
+                     os::vm_page_size(), MEM_PROT_READ);
+  os::protect_memory((char *)os::get_memory_serialize_page(),
+                     os::vm_page_size(), MEM_PROT_RW);
   Thread::muxRelease(&SerializePageLock);
 }
 
--- a/hotspot/src/share/vm/runtime/os.hpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/runtime/os.hpp	Thu Jan 08 16:34:58 2009 -0800
@@ -208,7 +208,7 @@
 
   enum ProtType { MEM_PROT_NONE, MEM_PROT_READ, MEM_PROT_RW, MEM_PROT_RWX };
   static bool   protect_memory(char* addr, size_t bytes, ProtType prot,
-                               bool is_committed = false);
+                               bool is_committed = true);
 
   static bool   guard_memory(char* addr, size_t bytes);
   static bool   unguard_memory(char* addr, size_t bytes);
--- a/hotspot/src/share/vm/runtime/perfMemory.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/runtime/perfMemory.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2001-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/runtime/perfMemory.hpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/runtime/perfMemory.hpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2001-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -556,7 +556,10 @@
           // the caller was at a call site, it's safe to destroy all
           // caller-saved registers, as these entry points do.
           VtableStub* vt_stub = VtableStubs::stub_containing(pc);
-          guarantee(vt_stub != NULL, "unable to find SEGVing vtable stub");
+
+          // If vt_stub is NULL, then return NULL to signal handler to report the SEGV error.
+          if (vt_stub == NULL) return NULL;
+
           if (vt_stub->is_abstract_method_error(pc)) {
             assert(!vt_stub->is_vtable_stub(), "should never see AbstractMethodErrors from vtable-type VtableStubs");
             return StubRoutines::throw_AbstractMethodError_entry();
@@ -565,7 +568,9 @@
           }
         } else {
           CodeBlob* cb = CodeCache::find_blob(pc);
-          guarantee(cb != NULL, "exception happened outside interpreter, nmethods and vtable stubs (1)");
+
+          // If code blob is NULL, then return NULL to signal handler to report the SEGV error.
+          if (cb == NULL) return NULL;
 
           // Exception happened in CodeCache. Must be either:
           // 1. Inline-cache check in C2I handler blob,
@@ -574,7 +579,7 @@
 
           if (!cb->is_nmethod()) {
             guarantee(cb->is_adapter_blob(),
-                      "exception happened outside interpreter, nmethods and vtable stubs (2)");
+                      "exception happened outside interpreter, nmethods and vtable stubs (1)");
             // There is no handler here, so we will simply unwind.
             return StubRoutines::throw_NullPointerException_at_call_entry();
           }
--- a/hotspot/src/share/vm/runtime/synchronizer.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/runtime/synchronizer.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -3363,13 +3363,13 @@
    //   If the wakee is cold then transiently setting it's affinity
    //   to the current CPU is a good idea.
    //   See http://j2se.east/~dice/PERSIST/050624-PullAffinity.txt
+   DTRACE_MONITOR_PROBE(contended__exit, this, object(), Self);
    Trigger->unpark() ;
 
    // Maintain stats and report events to JVMTI
    if (ObjectSynchronizer::_sync_Parks != NULL) {
       ObjectSynchronizer::_sync_Parks->inc() ;
    }
-   DTRACE_MONITOR_PROBE(contended__exit, this, object(), Self);
 }
 
 
--- a/hotspot/src/share/vm/runtime/thread.hpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/runtime/thread.hpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/services/management.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/services/management.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -694,10 +694,10 @@
                -1);
   }
 
-  if (threshold > max_intx) {
-    THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),
-               "Invalid threshold value > max value of size_t",
-               -1);
+  if ((size_t)threshold > max_uintx) {
+    stringStream st;
+    st.print("Invalid valid threshold value. Threshold value (" UINT64_FORMAT ") > max value of size_t (" SIZE_FORMAT ")", (size_t)threshold, max_uintx);
+    THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(), st.as_string(), -1);
   }
 
   MemoryPool* pool = get_memory_pool_from_jobject(obj, CHECK_(0L));
--- a/hotspot/src/share/vm/services/threadService.hpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/services/threadService.hpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/utilities/array.hpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/utilities/array.hpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2005 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2000-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/utilities/constantTag.hpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/utilities/constantTag.hpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/utilities/growableArray.hpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/utilities/growableArray.hpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/utilities/hashtable.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/utilities/hashtable.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2005 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/utilities/macros.hpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/utilities/macros.hpp	Thu Jan 08 16:34:58 2009 -0800
@@ -65,8 +65,10 @@
 // COMPILER2 variant
 #ifdef COMPILER2
 #define COMPILER2_PRESENT(code) code
+#define NOT_COMPILER2(code)
 #else // COMPILER2
 #define COMPILER2_PRESENT(code)
+#define NOT_COMPILER2(code) code
 #endif // COMPILER2
 
 
--- a/hotspot/src/share/vm/utilities/taskqueue.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/utilities/taskqueue.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2001-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/utilities/vmError.cpp	Thu Jan 08 16:26:59 2009 -0800
+++ b/hotspot/src/share/vm/utilities/vmError.cpp	Thu Jan 08 16:34:58 2009 -0800
@@ -332,6 +332,8 @@
 
      // VM version
      st->print_cr("#");
+     JDK_Version::current().to_string(buf, sizeof(buf));
+     st->print_cr("# JRE version: %s", buf);
      st->print_cr("# Java VM: %s (%s %s %s %s)",
                    Abstract_VM_Version::vm_name(),
                    Abstract_VM_Version::vm_release(),
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/6756768/Test6756768.java	Thu Jan 08 16:34:58 2009 -0800
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * @test
+ * @bug 6756768
+ * @summary C1 generates invalid code
+ *
+ * @run main/othervm -Xcomp Test6756768
+ */
+
+class Test6756768a
+{
+    static boolean var_1 = true;
+}
+
+final class Test6756768b
+{
+    static boolean var_24 = false;
+    static int var_25 = 0;
+
+    static boolean var_temp1 = Test6756768a.var_1 = false;
+}
+
+public final class Test6756768 extends Test6756768a
+{
+    final static int var = var_1 ^ (Test6756768b.var_24 ? var_1 : var_1) ? Test6756768b.var_25 : 1;
+
+    static public void main(String[] args) {
+        if (var != 0) {
+            throw new InternalError("var = " + var);
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/6756768/Test6756768_2.java	Thu Jan 08 16:34:58 2009 -0800
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * @test
+ * @bug 6756768
+ * @summary C1 generates invalid code
+ *
+ * @run main/othervm -Xcomp Test6756768_2
+ */
+
+class Test6756768_2a {
+    static int var = ++Test6756768_2.var;
+}
+
+public class Test6756768_2 {
+    static int var = 1;
+
+    static Object d2 = null;
+
+    static void test_static_field() {
+        int v = var;
+        int v2 = Test6756768_2a.var;
+        int v3 = var;
+        var = v3;
+    }
+
+    public static void main(String[] args) {
+        var = 1;
+        test_static_field();
+        if (var != 2) {
+            throw new InternalError();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/6757316/Test6757316.java	Thu Jan 08 16:34:58 2009 -0800
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * @test
+ * @bug 6757316
+ * @summary load_constant() produces a wrong long constant, with high a low words swapped
+ * @run main/othervm -Xcomp Test6757316
+ */
+
+public class Test6757316 {
+    public static void main(String[] args) {
+        long[] arr = {
+            0x11111111aaaaaaaaL,
+            0xaaaaaaaa11111111L,
+            0x11111111aaaaaaaaL,
+            0xaaaaaaaa11111111L
+        };
+        if (arr[0] == arr[1]) {
+            throw new InternalError();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/6758234/Test6758234.java	Thu Jan 08 16:34:58 2009 -0800
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * @test
+ * @bug 6758234
+ * @summary if (k cond (a ? : b: c)) returns reversed answer if k is constant and b and c are longs
+ * @run main/othervm -Xcomp -XX:CompileOnly=Test6758234.main Test6758234
+ */
+
+public class Test6758234 {
+    static int x = 0;
+    static int y = 1;
+
+    public static void main(String[] args) {
+        if (1 != ((x < y) ? 1L : 0)) {
+            throw new InternalError();
+        }
+   }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/6775880/Test.java	Thu Jan 08 16:34:58 2009 -0800
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *