changeset 466:63d1bf926938

Merge
author poonam
date Thu, 04 Dec 2008 17:48:02 -0800
parents dc16daa0329d b22701a8b88f
children 8724fb00c422
files src/share/vm/gc_implementation/concurrentMarkSweep/concurrentGCThread.cpp src/share/vm/gc_implementation/concurrentMarkSweep/concurrentGCThread.hpp
diffstat 147 files changed, 3894 insertions(+), 1478 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Thu Dec 04 17:29:56 2008 -0800
+++ b/.hgtags	Thu Dec 04 17:48:02 2008 -0800
@@ -13,3 +13,4 @@
 e91159f921a58af3698e6479ea1fc5818da66d09 jdk7-b36
 9ee9cf798b59e7d51f8c0a686959f313867a55d6 jdk7-b37
 d9bc824aa078573829bb66572af847e26e1bd12e jdk7-b38
+49ca90d77f34571b0757ebfcb8a7848ef2696b88 jdk7-b39
--- a/make/hotspot_version	Thu Dec 04 17:29:56 2008 -0800
+++ b/make/hotspot_version	Thu Dec 04 17:48:02 2008 -0800
@@ -35,7 +35,7 @@
 
 HS_MAJOR_VER=14
 HS_MINOR_VER=0
-HS_BUILD_NUMBER=06
+HS_BUILD_NUMBER=07
 
 JDK_MAJOR_VER=1
 JDK_MINOR_VER=7
--- a/make/linux/makefiles/top.make	Thu Dec 04 17:29:56 2008 -0800
+++ b/make/linux/makefiles/top.make	Thu Dec 04 17:48:02 2008 -0800
@@ -85,9 +85,9 @@
 
 AD_Dir   = $(GENERATED)/adfiles
 ADLC     = $(AD_Dir)/adlc
-AD_Spec  = $(GAMMADIR)/src/cpu/$(Platform_arch)/vm/$(Platform_arch).ad
+AD_Spec  = $(GAMMADIR)/src/cpu/$(Platform_arch)/vm/$(Platform_arch_model).ad
 AD_Src   = $(GAMMADIR)/src/share/vm/adlc
-AD_Names = ad_$(Platform_arch).hpp ad_$(Platform_arch).cpp
+AD_Names = ad_$(Platform_arch_model).hpp ad_$(Platform_arch_model).cpp
 AD_Files = $(AD_Names:%=$(AD_Dir)/%)
 
 # AD_Files_If_Required/COMPILER1 = ad_stuff
--- a/make/solaris/makefiles/amd64.make	Thu Dec 04 17:29:56 2008 -0800
+++ b/make/solaris/makefiles/amd64.make	Thu Dec 04 17:48:02 2008 -0800
@@ -26,7 +26,6 @@
 CFLAGS += -DVM_LITTLE_ENDIAN
 
 # Not included in includeDB because it has no dependencies
-# Obj_Files += solaris_amd64.o
 Obj_Files += solaris_x86_64.o
 
 #
@@ -38,8 +37,6 @@
 
 # _lwp_create_interpose must have a frame
 OPT_CFLAGS/os_solaris_x86_64.o = -xO1
-# force C++ interpreter to be full optimization
-#OPT_CFLAGS/interpret.o = -fast -O4
 
 # Temporary until SS10 C++ compiler is fixed
 OPT_CFLAGS/generateOptoStub.o = -xO2
@@ -51,8 +48,6 @@
 # gcc
 # The serviceability agent relies on frame pointer (%rbp) to walk thread stack
 CFLAGS += -fno-omit-frame-pointer
-# force C++ interpreter to be full optimization
-#OPT_CFLAGS/interpret.o = -O3
 
 else
 # error
--- a/make/solaris/makefiles/debug.make	Thu Dec 04 17:29:56 2008 -0800
+++ b/make/solaris/makefiles/debug.make	Thu Dec 04 17:48:02 2008 -0800
@@ -30,7 +30,7 @@
 
 ifeq ("${Platform_compiler}", "sparcWorks")
 
-ifeq ($(COMPILER_REV),5.8)
+ifeq ($(COMPILER_REV_NUMERIC),508)
   # SS11 SEGV when compiling with -g and -xarch=v8, using different backend
   DEBUG_CFLAGS/compileBroker.o = $(DEBUG_CFLAGS) -xO0
   DEBUG_CFLAGS/jvmtiTagMap.o   = $(DEBUG_CFLAGS) -xO0
--- a/make/solaris/makefiles/dtrace.make	Thu Dec 04 17:29:56 2008 -0800
+++ b/make/solaris/makefiles/dtrace.make	Thu Dec 04 17:48:02 2008 -0800
@@ -87,17 +87,16 @@
 
 XLIBJVM_DB = 64/$(LIBJVM_DB)
 XLIBJVM_DTRACE = 64/$(LIBJVM_DTRACE)
-XARCH = $(subst sparcv9,v9,$(shell echo $(ISA)))
 
 $(XLIBJVM_DB): $(DTRACE_SRCDIR)/$(JVM_DB).c $(JVMOFFS).h $(LIBJVM_DB_MAPFILE)
 	@echo Making $@
 	$(QUIETLY) mkdir -p 64/ ; \
-	$(CC) $(SYMFLAG) $(ARCHFLAG/$(XARCH)) -D$(TYPE) -I. -I$(GENERATED) \
+	$(CC) $(SYMFLAG) $(ARCHFLAG/$(ISA)) -D$(TYPE) -I. -I$(GENERATED) \
 		$(SHARED_FLAG) $(LFLAGS_JVM_DB) -o $@ $(DTRACE_SRCDIR)/$(JVM_DB).c -lc
 $(XLIBJVM_DTRACE): $(DTRACE_SRCDIR)/$(JVM_DTRACE).c $(DTRACE_SRCDIR)/$(JVM_DTRACE).h $(LIBJVM_DTRACE_MAPFILE)
 	@echo Making $@
 	$(QUIETLY) mkdir -p 64/ ; \
-	$(CC) $(SYMFLAG) $(ARCHFLAG/$(XARCH)) -D$(TYPE) -I. \
+	$(CC) $(SYMFLAG) $(ARCHFLAG/$(ISA)) -D$(TYPE) -I. \
 		$(SHARED_FLAG) $(LFLAGS_JVM_DTRACE) -o $@ $(DTRACE_SRCDIR)/$(JVM_DTRACE).c -lc -lthread -ldoor
 endif # ifneq ("${ISA}","${BUILDARCH}")
 
@@ -116,27 +115,25 @@
 	$(QUIETLY) $(LINK.CC) -z nodefs -o $@ $(DTRACE_SRCDIR)/$(GENOFFS)Main.c \
 		./lib$(GENOFFS).so
 
-# $@.tmp is created first. It's to avoid empty $(JVMOFFS).h produced in error case.
+CONDITIONALLY_UPDATE_JVMOFFS_TARGET = \
+	cmp -s $@ $@.tmp; \
+	case $$? in \
+	0) rm -f $@.tmp;; \
+	*) rm -f $@ && mv $@.tmp $@ && echo Updated $@;; \
+	esac
+
+# $@.tmp is created first to avoid an empty $(JVMOFFS).h if an error occurs.
 $(JVMOFFS).h: $(GENOFFS)
-	$(QUIETLY) LD_LIBRARY_PATH=. ./$(GENOFFS) -header > $@.tmp ; \
-	if [ `diff $@.tmp $@ > /dev/null 2>&1; echo $$?` -ne 0 ] ; \
-	then rm -f $@; mv $@.tmp $@; echo Updated $@ ; \
-	else rm -f $@.tmp; \
-	fi
+	$(QUIETLY) LD_LIBRARY_PATH=. ./$(GENOFFS) -header > $@.tmp
+	$(QUIETLY) $(CONDITIONALLY_UPDATE_JVMOFFS_TARGET)
 
 $(JVMOFFS)Index.h: $(GENOFFS)
-	$(QUIETLY) LD_LIBRARY_PATH=. ./$(GENOFFS) -index > $@.tmp ; \
-	if [ `diff $@.tmp $@ > /dev/null 2>&1; echo $$?` -ne 0 ] ; \
-	then rm -f $@; mv $@.tmp $@; echo Updated $@ ; \
-	else rm -f $@.tmp; \
-	fi
+	$(QUIETLY) LD_LIBRARY_PATH=. ./$(GENOFFS) -index > $@.tmp
+	$(QUIETLY)  $(CONDITIONALLY_UPDATE_JVMOFFS_TARGET)
 
 $(JVMOFFS).cpp: $(GENOFFS) $(JVMOFFS).h $(JVMOFFS)Index.h
-	$(QUIETLY) LD_LIBRARY_PATH=. ./$(GENOFFS) -table > $@.tmp ; \
-	if [ `diff $@.tmp $@ > /dev/null 2>&1; echo $$?` -ne 0 ] ; \
-	then rm -f $@; mv $@.tmp $@; echo Updated $@ ; \
-	else rm -f $@.tmp; \
-	fi
+	$(QUIETLY) LD_LIBRARY_PATH=. ./$(GENOFFS) -table > $@.tmp
+	$(QUIETLY) $(CONDITIONALLY_UPDATE_JVMOFFS_TARGET)
 
 $(JVMOFFS.o): $(JVMOFFS).h $(JVMOFFS).cpp 
 	$(QUIETLY) $(CCC) -c -I. -o $@ $(ARCHFLAG) -D$(TYPE) $(JVMOFFS).cpp
--- a/make/solaris/makefiles/fastdebug.make	Thu Dec 04 17:29:56 2008 -0800
+++ b/make/solaris/makefiles/fastdebug.make	Thu Dec 04 17:48:02 2008 -0800
@@ -37,7 +37,7 @@
 OPT_CFLAGS/SLOWER = -xO2
 
 # Problem with SS12 compiler, dtrace doesn't like the .o files  (bug 6693876)
-ifeq ($(COMPILER_REV), 5.9)
+ifeq ($(COMPILER_REV_NUMERIC), 509)
   # To avoid jvm98 crash
   OPT_CFLAGS/instanceKlass.o = $(OPT_CFLAGS/SLOWER)
   # Not clear this workaround could be skipped in some cases.
@@ -46,47 +46,41 @@
   OPT_CFLAGS/jni.o = $(OPT_CFLAGS/SLOWER)
 endif
 
-ifeq ($(COMPILER_REV), 5.5)
+ifeq ($(COMPILER_REV_NUMERIC), 505)
 # CC 5.5 has bug 4908364 with -xO4  (Fixed in 5.6)
 OPT_CFLAGS/library_call.o = $(OPT_CFLAGS/SLOWER)
-endif # COMPILER_REV == 5.5
+endif # COMPILER_REV_NUMERIC == 505
 
-ifeq ($(shell expr $(COMPILER_REV) \<= 5.4), 1)
+ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \<= 504), 1)
 # Compilation of *_<arch>.cpp can take an hour or more at O3.  Use O2
 # See comments at top of sparc.make.
-OPT_CFLAGS/ad_$(Platform_arch).o = $(OPT_CFLAGS/SLOWER)
-OPT_CFLAGS/dfa_$(Platform_arch).o = $(OPT_CFLAGS/SLOWER)
-endif # COMPILER_REV <= 5.4
+OPT_CFLAGS/ad_$(Platform_arch_model).o = $(OPT_CFLAGS/SLOWER)
+OPT_CFLAGS/dfa_$(Platform_arch_model).o = $(OPT_CFLAGS/SLOWER)
+endif # COMPILER_REV_NUMERIC <= 504
 
-ifeq (${COMPILER_REV}, 5.0)
-# Avoid a compiler bug caused by using -xO<level> -g<level>
-# Since the bug also occurs with -xO0, use an innocuous value (must not be null)
-OPT_CFLAGS/c1_LIROptimizer_i486.o = -c
-endif
-
-ifeq ($(shell expr $(COMPILER_REV) \< 5.5), 1)
-# Same problem with Solaris/x86 compiler (both 5.0 and 5.2) on ad_i486.cpp.
-# CC build time is also too long for ad_i486_{gen,misc}.o
-OPT_CFLAGS/ad_i486.o = -c
-OPT_CFLAGS/ad_i486_gen.o = -c
-OPT_CFLAGS/ad_i486_misc.o = -c
-ifeq ($(Platform_arch), i486)
+ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \< 505), 1)
+# Same problem with Solaris/x86 compiler (both 5.0 and 5.2) on ad_x86_{32,64}.cpp.
+# CC build time is also too long for ad_$(Platform_arch_model)_{gen,misc}.o
+OPT_CFLAGS/ad_$(Platform_arch_model).o = -c
+OPT_CFLAGS/ad_$(Platform_arch_model)_gen.o = -c
+OPT_CFLAGS/ad_$(Platform_arch_model)_misc.o = -c
+ifeq ($(Platform_arch), x86)
 # Same problem for the wrapper roosts: jni.o jvm.o
 OPT_CFLAGS/jni.o = -c
 OPT_CFLAGS/jvm.o = -c
 # Same problem in parse2.o (probably the Big Switch over bytecodes)
 OPT_CFLAGS/parse2.o = -c
-endif # Platform_arch == i486
+endif # Platform_arch == x86
 endif
 
 # Frame size > 100k  if we allow inlining via -g0!
 DEBUG_CFLAGS/bytecodeInterpreter.o = -g
 DEBUG_CFLAGS/bytecodeInterpreterWithChecks.o = -g
-ifeq ($(Platform_arch), i486)
+ifeq ($(Platform_arch), x86)
 # ube explodes on x86
 OPT_CFLAGS/bytecodeInterpreter.o = -xO1
 OPT_CFLAGS/bytecodeInterpreterWithChecks.o =  -xO1
-endif # Platform_arch == i486
+endif # Platform_arch == x86
 
 endif # Platform_compiler == sparcWorks
 
--- a/make/solaris/makefiles/i486.make	Thu Dec 04 17:29:56 2008 -0800
+++ b/make/solaris/makefiles/i486.make	Thu Dec 04 17:48:02 2008 -0800
@@ -35,17 +35,13 @@
 ifeq ("${Platform_compiler}", "sparcWorks")
 
 # _lwp_create_interpose must have a frame
-OPT_CFLAGS/os_solaris_i486.o = -xO1
-# force C++ interpreter to be full optimization
-OPT_CFLAGS/interpret.o = -fast -O4
+OPT_CFLAGS/os_solaris_x86.o = -xO1
 else
 
 ifeq ("${Platform_compiler}", "gcc")
 # gcc
 # _lwp_create_interpose must have a frame
-OPT_CFLAGS/os_solaris_i486.o = -fno-omit-frame-pointer
-# force C++ interpreter to be full optimization
-OPT_CFLAGS/interpret.o = -O3
+OPT_CFLAGS/os_solaris_x86.o = -fno-omit-frame-pointer
 #
 else
 # error
@@ -57,7 +53,7 @@
 
 ifeq ("${Platform_compiler}", "sparcWorks")
 # ILD is gone as of SS11 (5.8), not supported in SS10 (5.7)
-ifeq ($(shell expr $(COMPILER_REV) \< 5.7), 1)
+ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \< 507), 1)
   #
   # Bug in ild causes it to fail randomly. Until we get a fix we can't
   # use ild.
--- a/make/solaris/makefiles/jvmg.make	Thu Dec 04 17:29:56 2008 -0800
+++ b/make/solaris/makefiles/jvmg.make	Thu Dec 04 17:48:02 2008 -0800
@@ -30,7 +30,7 @@
 
 ifeq ("${Platform_compiler}", "sparcWorks")
 
-ifeq ($(COMPILER_REV),5.8)
+ifeq ($(COMPILER_REV_NUMERIC),508)
   # SS11 SEGV when compiling with -g and -xarch=v8, using different backend
   DEBUG_CFLAGS/compileBroker.o = $(DEBUG_CFLAGS) -xO0
   DEBUG_CFLAGS/jvmtiTagMap.o   = $(DEBUG_CFLAGS) -xO0
--- a/make/solaris/makefiles/optimized.make	Thu Dec 04 17:29:56 2008 -0800
+++ b/make/solaris/makefiles/optimized.make	Thu Dec 04 17:48:02 2008 -0800
@@ -33,7 +33,7 @@
 ifeq ("${Platform_compiler}", "sparcWorks")
 
 # Problem with SS12 compiler, dtrace doesn't like the .o files  (bug 6693876)
-ifeq ($(COMPILER_REV),5.9)
+ifeq ($(COMPILER_REV_NUMERIC),509)
   # Not clear this workaround could be skipped in some cases.
   OPT_CFLAGS/vmGCOperations.o = $(OPT_CFLAGS/SLOWER) -g
   OPT_CFLAGS/java.o = $(OPT_CFLAGS/SLOWER) -g
@@ -41,9 +41,9 @@
 endif
 
 # Workaround SS11 bug 6345274 (all platforms) (Fixed in SS11 patch and SS12)
-ifeq ($(COMPILER_REV),5.8))
+ifeq ($(COMPILER_REV_NUMERIC),508))
 OPT_CFLAGS/ciTypeFlow.o = $(OPT_CFLAGS/O2)
-endif # COMPILER_REV == 5.8
+endif # COMPILER_REV_NUMERIC == 508
 
 endif # Platform_compiler == sparcWorks
 
--- a/make/solaris/makefiles/product.make	Thu Dec 04 17:29:56 2008 -0800
+++ b/make/solaris/makefiles/product.make	Thu Dec 04 17:48:02 2008 -0800
@@ -41,7 +41,7 @@
 ifeq ("${Platform_compiler}", "sparcWorks")
 
 # Problem with SS12 compiler, dtrace doesn't like the .o files  (bug 6693876)
-ifeq ($(COMPILER_REV),5.9)
+ifeq ($(COMPILER_REV_NUMERIC),509)
   # Not clear this workaround could be skipped in some cases.
   OPT_CFLAGS/vmGCOperations.o = $(OPT_CFLAGS/SLOWER) -g
   OPT_CFLAGS/java.o = $(OPT_CFLAGS/SLOWER) -g
@@ -49,9 +49,9 @@
 endif
 
 # Workaround SS11 bug 6345274 (all platforms) (Fixed in SS11 patch and SS12)
-ifeq ($(COMPILER_REV),5.8)
+ifeq ($(COMPILER_REV_NUMERIC),508)
 OPT_CFLAGS/ciTypeFlow.o = $(OPT_CFLAGS/O2)
-endif # COMPILER_REV == 5.8
+endif # COMPILER_REV_NUMERIC == 508
 
 endif # Platform_compiler == sparcWorks
 
--- a/make/solaris/makefiles/sparc.make	Thu Dec 04 17:29:56 2008 -0800
+++ b/make/solaris/makefiles/sparc.make	Thu Dec 04 17:48:02 2008 -0800
@@ -26,7 +26,7 @@
 ASFLAGS += $(AS_ARCHFLAG)
 
 ifeq ("${Platform_compiler}", "sparcWorks")
-ifeq ($(shell expr $(COMPILER_REV) \< 5.5), 1)
+ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \< 505), 1)
 # For 5.2 ad_sparc file is compiled with -O2 %%%% remove when adlc is fixed
 OPT_CFLAGS/ad_sparc.o = $(OPT_CFLAGS/SLOWER)
 OPT_CFLAGS/dfa_sparc.o = $(OPT_CFLAGS/SLOWER)
@@ -39,7 +39,7 @@
 OPT_CFLAGS/jniHandles.o = $(OPT_CFLAGS/O2)
 # CC brings an US-II to its knees compiling the vmStructs asserts under -xO4
 OPT_CFLAGS/vmStructs.o = $(OPT_CFLAGS/O2)
-endif
+endif # COMPILER_REV_NUMERIC < 505
 else
 # Options for gcc
 OPT_CFLAGS/ad_sparc.o = $(OPT_CFLAGS/SLOWER)
--- a/make/solaris/makefiles/sparcWorks.make	Thu Dec 04 17:29:56 2008 -0800
+++ b/make/solaris/makefiles/sparcWorks.make	Thu Dec 04 17:48:02 2008 -0800
@@ -41,9 +41,9 @@
 
 # Get the last thing on the line that looks like x.x+ (x is a digit).
 COMPILER_REV := \
-$(shell $(CPP) -V 2>&1 | sed -e 's/^.*\([1-9]\.[0-9][0-9]*\).*/\1/')
+$(shell $(CPP) -V 2>&1 | sed -n 's/^.*[ ,\t]C++[ ,\t]\([1-9]\.[0-9][0-9]*\).*/\1/p')
 C_COMPILER_REV := \
-$(shell $(CC) -V 2>&1 | grep -i "cc:" |  sed -e 's/^.*\([1-9]\.[0-9][0-9]*\).*/\1/')
+$(shell $(CC) -V 2>&1 | sed -n 's/^.*[ ,\t]C[ ,\t]\([1-9]\.[0-9][0-9]*\).*/\1/p')
 
 # Pick which compiler is validated
 ifeq ($(JDK_MINOR_VERSION),6)
@@ -60,17 +60,19 @@
 ENFORCE_COMPILER_REV${ENFORCE_COMPILER_REV} := ${VALIDATED_COMPILER_REV}
 ifneq (${COMPILER_REV},${ENFORCE_COMPILER_REV})
 dummy_target_to_enforce_compiler_rev:=\
-$(info WARNING: You are using CC version ${COMPILER_REV} \
-and should be using version ${ENFORCE_COMPILER_REV})
+$(shell echo >&2 WARNING: You are using CC version ${COMPILER_REV} \
+and should be using version ${ENFORCE_COMPILER_REV}. Set ENFORCE_COMPILER_REV=${COMPILER_REV} to avoid this warning.)
 endif
 
 ENFORCE_C_COMPILER_REV${ENFORCE_C_COMPILER_REV} := ${VALIDATED_C_COMPILER_REV}
 ifneq (${C_COMPILER_REV},${ENFORCE_C_COMPILER_REV})
 dummy_target_to_enforce_c_compiler_rev:=\
-$(info WARNING: You are using cc version ${C_COMPILER_REV} \
-and should be using version ${ENFORCE_C_COMPILER_REV})
+$(shell echo >&2 WARNING: You are using cc version ${C_COMPILER_REV} \
+and should be using version ${ENFORCE_C_COMPILER_REV}. Set ENFORCE_C_COMPILER_REV=${C_COMPILER_REV} to avoid this warning.)
 endif
 
+COMPILER_REV_NUMERIC := $(shell echo $(COMPILER_REV) | awk -F. '{ print $$1 * 100 + $$2 }')
+
 # Fail the build if __fabsf is used.  __fabsf exists only in Solaris 8 2/04
 # and newer; objects with a dependency on this symbol will not run on older
 # Solaris 8.
@@ -120,7 +122,7 @@
 ARCHFLAG_NEW/amd64   = -m64
 
 # Select the ARCHFLAGs and other SS12 (5.9) options
-ifeq ($(shell expr $(COMPILER_REV) \>= 5.9), 1)
+ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \>= 509), 1)
   ARCHFLAG/sparc   = $(ARCHFLAG_NEW/sparc)
   ARCHFLAG/sparcv9 = $(ARCHFLAG_NEW/sparcv9)
   ARCHFLAG/i486    = $(ARCHFLAG_NEW/i486)
@@ -150,7 +152,7 @@
 # Begin current (>=5.6) Forte compiler options #
 #################################################
 
-ifeq ($(shell expr $(COMPILER_REV) \>= 5.6), 1)
+ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \>= 506), 1)
 
 ifeq ("${Platform_arch}", "sparc")
 
@@ -167,7 +169,7 @@
 # Begin current (>=5.5) Forte compiler options #
 #################################################
 
-ifeq ($(shell expr $(COMPILER_REV) \>= 5.5), 1)
+ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \>= 505), 1)
 
 CFLAGS     += $(ARCHFLAG)
 AOUT_FLAGS += $(ARCHFLAG)
@@ -255,7 +257,7 @@
 
 LFLAGS += -mt
 
-endif	# COMPILER_REV >= 5.5
+endif	# COMPILER_REV_NUMERIC >= 505
 
 ######################################
 # End 5.5 Forte compiler options     #
@@ -265,7 +267,7 @@
 # Begin 5.2 Forte compiler options   #
 ######################################
 
-ifeq ($(COMPILER_REV), 5.2)
+ifeq ($(COMPILER_REV_NUMERIC), 502)
 
 CFLAGS     += $(ARCHFLAG)
 AOUT_FLAGS += $(ARCHFLAG)
@@ -324,7 +326,7 @@
 LFLAGS += -library=Crun
 LIBS   += -library=Crun -lCrun
 
-endif	# COMPILER_REV == 5.2
+endif	# COMPILER_REV_NUMERIC == 502
 
 ##################################
 # End 5.2 Forte compiler options #
@@ -333,7 +335,7 @@
 ##################################
 # Begin old 5.1 compiler options #
 ##################################
-ifeq ($(COMPILER_REV), 5.1)
+ifeq ($(COMPILER_REV_NUMERIC), 501)
 
 _JUNK_ := $(shell echo >&2 \
        "*** ERROR: sparkWorks.make incomplete for 5.1 compiler")
@@ -347,7 +349,7 @@
 # Begin old 5.0 compiler options #
 ##################################
 
-ifeq	(${COMPILER_REV}, 5.0)
+ifeq	(${COMPILER_REV_NUMERIC}, 500)
 
 # Had to hoist this higher apparently because of other changes. Must
 # come before -xarch specification.
@@ -379,7 +381,7 @@
 
 ifeq ("${Platform_arch_model}", "x86_32")
 OPT_CFLAGS=-xtarget=pentium $(EXTRA_OPT_CFLAGS)
-ifeq ("${COMPILER_REV}", "5.0")
+ifeq ("${COMPILER_REV_NUMERIC}", "500")
 # SC5.0 tools on x86 are flakey at -xO4
 OPT_CFLAGS+=-xO3
 else
@@ -405,13 +407,13 @@
 PICFLAG/BETTER  = $(PICFLAG/DEFAULT)
 PICFLAG/BYFILE  = $(PICFLAG/$@)$(PICFLAG/DEFAULT$(PICFLAG/$@))
 
-endif	# COMPILER_REV = 5.0
+endif	# COMPILER_REV_NUMERIC = 500
 
 ################################
 # End old 5.0 compiler options #
 ################################
 
-ifeq ("${COMPILER_REV}", "4.2")
+ifeq ("${COMPILER_REV_NUMERIC}", "402")
 # 4.2 COMPILERS SHOULD NO LONGER BE USED
 _JUNK_ := $(shell echo >&2 \
        "*** ERROR: SC4.2 compilers are not supported by this code base!")
@@ -443,7 +445,7 @@
 LINK_MODE/optimized = -Bsymbolic -znodefs
 
 # Have thread local errnos
-ifeq ($(shell expr $(COMPILER_REV) \>= 5.5), 1)
+ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \>= 505), 1)
 CFLAGS += -mt
 else
 CFLAGS += -D_REENTRANT
@@ -460,7 +462,7 @@
 # The -g0 setting allows the C++ frontend to inline, which is a big win.
 
 # Special global options for SS12
-ifeq ($(COMPILER_REV),5.9)
+ifeq ($(COMPILER_REV_NUMERIC),509)
   # There appears to be multiple issues with the new Dwarf2 debug format, so
   #   we tell the compiler to use the older 'stabs' debug format all the time.
   #   Note that this needs to be used in optimized compiles too to be 100%.
@@ -479,8 +481,8 @@
 #DEBUG_CFLAGS += -Qoption ccfe -xglobalstatic
 #FASTDEBUG_CFLAGS += -Qoption ccfe -xglobalstatic
 
-ifeq	(${COMPILER_REV}, 5.2)
-COMPILER_DATE := $(shell $(CPP) -V 2>&1 | awk '{ print $$NF; }')
+ifeq	(${COMPILER_REV_NUMERIC}, 502)
+COMPILER_DATE := $(shell $(CPP) -V 2>&1 | sed -n '/^.*[ ]C++[ ]\([1-9]\.[0-9][0-9]*\)/p' | awk '{ print $$NF; }')
 ifeq	(${COMPILER_DATE}, 2001/01/31)
 # disable -g0 in fastdebug since SC6.1 dated 2001/01/31 seems to be buggy
 # use an innocuous value because it will get -g if it's empty
@@ -493,7 +495,7 @@
 CFLAGS		+= $(CFLAGS_BROWSE)
 
 # ILD is gone as of SS11 (5.8), not supportted in SS10 (5.7)
-ifeq ($(shell expr $(COMPILER_REV) \< 5.7), 1)
+ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \< 507), 1)
   # use ild when debugging (but when optimizing we want reproducible results)
   ILDFLAG = $(ILDFLAG/$(VERSION))
   ILDFLAG/debug     = -xildon
--- a/make/solaris/makefiles/sparcv9.make	Thu Dec 04 17:29:56 2008 -0800
+++ b/make/solaris/makefiles/sparcv9.make	Thu Dec 04 17:48:02 2008 -0800
@@ -26,7 +26,7 @@
 ASFLAGS += $(AS_ARCHFLAG)
 
 ifeq ("${Platform_compiler}", "sparcWorks")
-ifeq ($(shell expr $(COMPILER_REV) \< 5.5), 1)
+ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \< 505), 1)
 # When optimized fully, stubGenerator_sparc.cpp 
 # has bogus code for the routine 
 # StubGenerator::generate_flush_callers_register_windows() 
--- a/make/solaris/makefiles/top.make	Thu Dec 04 17:29:56 2008 -0800
+++ b/make/solaris/makefiles/top.make	Thu Dec 04 17:48:02 2008 -0800
@@ -83,9 +83,9 @@
 
 AD_Dir   = $(GENERATED)/adfiles
 ADLC     = $(AD_Dir)/adlc
-AD_Spec  = $(GAMMADIR)/src/cpu/$(Platform_arch)/vm/$(Platform_arch).ad
+AD_Spec  = $(GAMMADIR)/src/cpu/$(Platform_arch)/vm/$(Platform_arch_model).ad
 AD_Src   = $(GAMMADIR)/src/share/vm/adlc
-AD_Names = ad_$(Platform_arch).hpp ad_$(Platform_arch).cpp
+AD_Names = ad_$(Platform_arch_model).hpp ad_$(Platform_arch_model).cpp
 AD_Files = $(AD_Names:%=$(AD_Dir)/%)
 
 # AD_Files_If_Required/COMPILER1 = ad_stuff
--- a/make/solaris/makefiles/vm.make	Thu Dec 04 17:29:56 2008 -0800
+++ b/make/solaris/makefiles/vm.make	Thu Dec 04 17:48:02 2008 -0800
@@ -101,7 +101,7 @@
 
 ifeq ("${Platform_compiler}", "sparcWorks")
 # The whole megilla:
-ifeq ($(shell expr $(COMPILER_REV) \>= 5.5), 1)
+ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \>= 505), 1)
 # Old Comment: List the libraries in the order the compiler was designed for
 # Not sure what the 'designed for' comment is referring too above.
 #   The order may not be too significant anymore, but I have placed this
--- a/make/windows/makefiles/adlc.make	Thu Dec 04 17:29:56 2008 -0800
+++ b/make/windows/makefiles/adlc.make	Thu Dec 04 17:48:02 2008 -0800
@@ -102,6 +102,12 @@
 adlc.exe: main.obj adlparse.obj archDesc.obj arena.obj dfa.obj dict2.obj filebuff.obj \
           forms.obj formsopt.obj formssel.obj opcodes.obj output_c.obj output_h.obj
 	$(LINK) $(LINK_FLAGS) /subsystem:console /out:$@ $**
+!if "$(MT)" != ""
+# The previous link command created a .manifest file that we want to
+# insert into the linked artifact so we do not need to track it
+# separately.  Use ";#2" for .dll and ";#1" for .exe:
+	$(MT) /manifest $@.manifest /outputresource:$@;#1
+!endif
 
 $(GENERATED_NAMES_IN_INCL): $(Platform_arch_model).ad adlc.exe includeDB.current 
 	rm -f $(GENERATED_NAMES)
--- a/make/windows/makefiles/compile.make	Thu Dec 04 17:29:56 2008 -0800
+++ b/make/windows/makefiles/compile.make	Thu Dec 04 17:48:02 2008 -0800
@@ -30,7 +30,7 @@
 #   /W3       Warning level 3
 #   /Zi       Include debugging information
 #   /WX       Treat any warning error as a fatal error
-#   /MD       Use dynamic multi-threaded runtime (msvcrt.dll or msvc*71.dll)
+#   /MD       Use dynamic multi-threaded runtime (msvcrt.dll or msvc*NN.dll)
 #   /MTd      Use static multi-threaded runtime debug versions
 #   /O1       Optimize for size (/Os), skips /Oi
 #   /O2       Optimize for speed (/Ot), adds /Oi to /O1
@@ -80,8 +80,10 @@
 CPP=ARCH_ERROR
 !endif
 
-# MSC_VER is a 4 digit number that tells us what compiler is being used, it is
-#    generated when the local.make file is created by the script gen_msc_ver.sh.
+# MSC_VER is a 4 digit number that tells us what compiler is being used
+#    and is generated when the local.make file is created by build.make
+#    via the script get_msc_ver.sh
+#
 #    If MSC_VER is set, it overrides the above default setting.
 #    But it should be set.
 #    Possible values:
@@ -89,13 +91,14 @@
 #      1300 and 1310 is VS2003 or VC7
 #      1399 is our fake number for the VS2005 compiler that really isn't 1400
 #      1400 is for VS2005
+#      1500 is for VS2008
 #    Do not confuse this MSC_VER with the predefined macro _MSC_VER that the
 #    compiler provides, when MSC_VER==1399, _MSC_VER will be 1400.
 #    Normally they are the same, but a pre-release of the VS2005 compilers
 #    in the Windows 64bit Platform SDK said it was 1400 when it was really
 #    closer to VS2003 in terms of option spellings, so we use 1399 for that
 #    1400 version that really isn't 1400.
-#    See the file gen_msc_ver.sh for more info.
+#    See the file get_msc_ver.sh for more info.
 !if "x$(MSC_VER)" == "x"
 COMPILER_NAME=$(DEFAULT_COMPILER_NAME)
 !else
@@ -115,6 +118,9 @@
 !if "$(MSC_VER)" == "1400"
 COMPILER_NAME=VS2005
 !endif
+!if "$(MSC_VER)" == "1500"
+COMPILER_NAME=VS2008
+!endif
 !endif
 
 # Add what version of the compiler we think this is to the compile line
@@ -160,7 +166,25 @@
 #    externals at link time. Even with /GS-, you need bufferoverflowU.lib.
 #    NOTE: Currently we decided to not use /GS-
 BUFFEROVERFLOWLIB = bufferoverflowU.lib
-LINK_FLAGS = $(LINK_FLAGS) $(BUFFEROVERFLOWLIB)
+LINK_FLAGS = /manifest $(LINK_FLAGS) $(BUFFEROVERFLOWLIB)
+# Manifest Tool - used in VS2005 and later to adjust manifests stored
+# as resources inside build artifacts.
+MT=mt.exe
+!if "$(BUILDARCH)" == "i486"
+# VS2005 on x86 restricts the use of certain libc functions without this
+CPP_FLAGS=$(CPP_FLAGS) /D _CRT_SECURE_NO_DEPRECATE
+!endif
+!endif
+
+!if "$(COMPILER_NAME)" == "VS2008"
+PRODUCT_OPT_OPTION   = /O2 /Oy-
+FASTDEBUG_OPT_OPTION = /O2 /Oy-
+DEBUG_OPT_OPTION     = /Od
+GX_OPTION = /EHsc
+LINK_FLAGS = /manifest $(LINK_FLAGS)
+# Manifest Tool - used in VS2005 and later to adjust manifests stored
+# as resources inside build artifacts.
+MT=mt.exe
 !if "$(BUILDARCH)" == "i486"
 # VS2005 on x86 restricts the use of certain libc functions without this
 CPP_FLAGS=$(CPP_FLAGS) /D _CRT_SECURE_NO_DEPRECATE
--- a/make/windows/makefiles/debug.make	Thu Dec 04 17:29:56 2008 -0800
+++ b/make/windows/makefiles/debug.make	Thu Dec 04 17:48:02 2008 -0800
@@ -50,6 +50,12 @@
 	$(LINK) @<<
   $(LINK_FLAGS) /out:$@ /implib:$*.lib /def:vm.def $(Obj_Files) $(Res_Files)
 <<
+!if "$(MT)" != ""
+# The previous link command created a .manifest file that we want to
+# insert into the linked artifact so we do not need to track it
+# separately.  Use ";#2" for .dll and ";#1" for .exe:
+	$(MT) /manifest $@.manifest /outputresource:$@;#2
+!endif
 
 !include $(WorkSpace)/make/windows/makefiles/shared.make
 !include $(WorkSpace)/make/windows/makefiles/sa.make
--- a/make/windows/makefiles/defs.make	Thu Dec 04 17:29:56 2008 -0800
+++ b/make/windows/makefiles/defs.make	Thu Dec 04 17:48:02 2008 -0800
@@ -25,7 +25,7 @@
 # The common definitions for hotspot windows builds.
 # Include the top level defs.make under make directory instead of this one.
 # This file is included into make/defs.make.
-# On windows it is only used to construct parameters for 
+# On windows it is only used to construct parameters for
 # make/windows/build.make when make/Makefile is used to build VM.
 
 SLASH_JAVA ?= J:
@@ -69,7 +69,7 @@
 
 JDK_INCLUDE_SUBDIR=win32
 
-# HOTSPOT_RELEASE_VERSION and HOTSPOT_BUILD_VERSION are defined 
+# HOTSPOT_RELEASE_VERSION and HOTSPOT_BUILD_VERSION are defined
 # and added to MAKE_ARGS list in $(GAMMADIR)/make/defs.make.
 
 # next parameters are defined in $(GAMMADIR)/make/defs.make.
@@ -125,7 +125,7 @@
 endif
 
 ifeq ($(BUILD_WIN_SA), 1)
-  ifeq ($(ARCH),ia64)   
+  ifeq ($(ARCH),ia64)
     BUILD_WIN_SA = 0
   endif
 endif
@@ -154,7 +154,7 @@
   EXPORT_LIST += $(EXPORT_JRE_BIN_DIR)/sawindbg.dll
   EXPORT_LIST += $(EXPORT_JRE_BIN_DIR)/sawindbg.pdb
   EXPORT_LIST += $(EXPORT_JRE_BIN_DIR)/sawindbg.map
-  EXPORT_LIST += $(EXPORT_LIB_DIR)/sa-jdi.jar 
+  EXPORT_LIST += $(EXPORT_LIB_DIR)/sa-jdi.jar
   # Must pass this down to nmake.
   MAKE_ARGS += BUILD_WIN_SA=1
 endif
--- a/make/windows/makefiles/fastdebug.make	Thu Dec 04 17:29:56 2008 -0800
+++ b/make/windows/makefiles/fastdebug.make	Thu Dec 04 17:48:02 2008 -0800
@@ -50,6 +50,13 @@
 	$(LINK) @<<
   $(LINK_FLAGS) /out:$@ /implib:$*.lib /def:vm.def $(Obj_Files) $(Res_Files)
 <<
+!if "$(MT)" != ""
+# The previous link command created a .manifest file that we want to
+# insert into the linked artifact so we do not need to track it
+# separately.  Use ";#2" for .dll and ";#1" for .exe:
+	$(MT) /manifest $@.manifest /outputresource:$@;#2
+!endif
+
 
 !include $(WorkSpace)/make/windows/makefiles/shared.make
 !include $(WorkSpace)/make/windows/makefiles/sa.make
--- a/make/windows/makefiles/product.make	Thu Dec 04 17:29:56 2008 -0800
+++ b/make/windows/makefiles/product.make	Thu Dec 04 17:48:02 2008 -0800
@@ -61,6 +61,12 @@
   $(LINK_FLAGS) /out:$@ /implib:$*.lib /def:vm.def $(Obj_Files) $(Res_Files)
 <<
 !endif
+!if "$(MT)" != ""
+# The previous link command created a .manifest file that we want to
+# insert into the linked artifact so we do not need to track it
+# separately.  Use ";#2" for .dll and ";#1" for .exe:
+	$(MT) /manifest $@.manifest /outputresource:$@;#2
+!endif
 
 !include $(WorkSpace)/make/windows/makefiles/shared.make
 !include $(WorkSpace)/make/windows/makefiles/sa.make
--- a/make/windows/makefiles/sa.make	Thu Dec 04 17:29:56 2008 -0800
+++ b/make/windows/makefiles/sa.make	Thu Dec 04 17:48:02 2008 -0800
@@ -92,13 +92,18 @@
 !else
 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)
+!endif
 SASRCFILE = $(AGENT_DIR)/src/os/win32/windbg/sawindbg.cpp
 SA_LFLAGS = $(SA_LINK_FLAGS) /nologo /subsystem:console /map /debug /machine:$(MACHINE)
 
 # Note that we do not keep sawindbj.obj around as it would then
 # get included in the dumpbin command in build_vm_def.sh
 
+# In VS2005 or VS2008 the link command creates a .manifest file that we want
+# to insert into the linked artifact so we do not need to track it separately.
+# Use ";#2" for .dll and ";#1" for .exe in the MT command below:
 $(SAWINDBG): $(SASRCFILE)
 	set INCLUDE=$(SA_INCLUDE)$(INCLUDE)
 	$(CPP) @<<
@@ -109,6 +114,9 @@
 <<
 	set LIB=$(SA_LIB)$(LIB)
 	$(LINK) /out:$@ /DLL sawindbg.obj dbgeng.lib $(SA_LFLAGS)
+!if "$(MT)" != ""
+	$(MT) /manifest $(@F).manifest /outputresource:$(@F);#2
+!endif
 	-@rm -f sawindbg.obj
 
 cleanall :
--- a/make/windows/projectfiles/common/Makefile	Thu Dec 04 17:29:56 2008 -0800
+++ b/make/windows/projectfiles/common/Makefile	Thu Dec 04 17:48:02 2008 -0800
@@ -56,7 +56,8 @@
     $(HOTSPOTWORKSPACE)/src/share/vm/gc_implementation/includeDB_gc_shared \
     $(HOTSPOTWORKSPACE)/src/share/vm/gc_implementation/includeDB_gc_parNew \
     $(HOTSPOTWORKSPACE)/src/share/vm/gc_implementation/includeDB_gc_parallelScavenge \
-    $(HOTSPOTWORKSPACE)/src/share/vm/gc_implementation/includeDB_gc_concurrentMarkSweep
+    $(HOTSPOTWORKSPACE)/src/share/vm/gc_implementation/includeDB_gc_concurrentMarkSweep \
+    $(HOTSPOTWORKSPACE)/src/share/vm/gc_implementation/includeDB_gc_g1
 
 
 IncludeDBs_kernel =$(IncludeDBs_base) \
--- a/src/cpu/sparc/vm/assembler_sparc.cpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/cpu/sparc/vm/assembler_sparc.cpp	Thu Dec 04 17:48:02 2008 -0800
@@ -2615,7 +2615,8 @@
   }
 }
 
-void MacroAssembler::biased_locking_enter(Register obj_reg, Register mark_reg, Register temp_reg,
+void MacroAssembler::biased_locking_enter(Register obj_reg, Register mark_reg,
+                                          Register temp_reg,
                                           Label& done, Label* slow_case,
                                           BiasedLockingCounters* counters) {
   assert(UseBiasedLocking, "why call this otherwise?");
@@ -2691,8 +2692,7 @@
                   markOopDesc::biased_lock_mask_in_place | markOopDesc::age_mask_in_place | markOopDesc::epoch_mask_in_place,
                   mark_reg);
   or3(G2_thread, mark_reg, temp_reg);
-  casx_under_lock(mark_addr.base(), mark_reg, temp_reg,
-                  (address)StubRoutines::Sparc::atomic_memory_operation_lock_addr());
+  casn(mark_addr.base(), mark_reg, temp_reg);
   // If the biasing toward our thread failed, this means that
   // another thread succeeded in biasing it toward itself and we
   // need to revoke that bias. The revocation will occur in the
@@ -2721,8 +2721,7 @@
   load_klass(obj_reg, temp_reg);
   ld_ptr(Address(temp_reg, 0, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()), temp_reg);
   or3(G2_thread, temp_reg, temp_reg);
-  casx_under_lock(mark_addr.base(), mark_reg, temp_reg,
-                  (address)StubRoutines::Sparc::atomic_memory_operation_lock_addr());
+  casn(mark_addr.base(), mark_reg, temp_reg);
   // If the biasing toward our thread failed, this means that
   // another thread succeeded in biasing it toward itself and we
   // need to revoke that bias. The revocation will occur in the
@@ -2752,8 +2751,7 @@
   // bits in this situation. Should attempt to preserve them.
   load_klass(obj_reg, temp_reg);
   ld_ptr(Address(temp_reg, 0, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()), temp_reg);
-  casx_under_lock(mark_addr.base(), mark_reg, temp_reg,
-                  (address)StubRoutines::Sparc::atomic_memory_operation_lock_addr());
+  casn(mark_addr.base(), mark_reg, temp_reg);
   // Fall through to the normal CAS-based lock, because no matter what
   // the result of the above CAS, some thread must have succeeded in
   // removing the bias bit from the object's header.
@@ -2815,8 +2813,10 @@
 // effect).
 
 
-void MacroAssembler::compiler_lock_object(Register Roop, Register Rmark, Register Rbox, Register Rscratch,
-                                          BiasedLockingCounters* counters) {
+void MacroAssembler::compiler_lock_object(Register Roop, Register Rmark,
+                                          Register Rbox, Register Rscratch,
+                                          BiasedLockingCounters* counters,
+                                          bool try_bias) {
    Address mark_addr(Roop, 0, oopDesc::mark_offset_in_bytes());
 
    verify_oop(Roop);
@@ -2838,7 +2838,7 @@
      // Fetch object's markword
      ld_ptr(mark_addr, Rmark);
 
-     if (UseBiasedLocking) {
+     if (try_bias) {
         biased_locking_enter(Roop, Rmark, Rscratch, done, NULL, counters);
      }
 
@@ -2881,7 +2881,7 @@
 
       ld_ptr (mark_addr, Rmark);           // fetch obj->mark
       // Triage: biased, stack-locked, neutral, inflated
-      if (UseBiasedLocking) {
+      if (try_bias) {
         biased_locking_enter(Roop, Rmark, Rscratch, done, NULL, counters);
         // Invariant: if control reaches this point in the emitted stream
         // then Rmark has not been modified.
@@ -2945,7 +2945,7 @@
       ld_ptr (mark_addr, Rmark);           // fetch obj->mark
       // Triage: biased, stack-locked, neutral, inflated
 
-      if (UseBiasedLocking) {
+      if (try_bias) {
         biased_locking_enter(Roop, Rmark, Rscratch, done, NULL, counters);
         // Invariant: if control reaches this point in the emitted stream
         // then Rmark has not been modified.
@@ -3039,7 +3039,9 @@
    bind   (done) ;
 }
 
-void MacroAssembler::compiler_unlock_object(Register Roop, Register Rmark, Register Rbox, Register Rscratch) {
+void MacroAssembler::compiler_unlock_object(Register Roop, Register Rmark,
+                                            Register Rbox, Register Rscratch,
+                                            bool try_bias) {
    Address mark_addr(Roop, 0, oopDesc::mark_offset_in_bytes());
 
    Label done ;
@@ -3050,7 +3052,7 @@
    }
 
    if (EmitSync & 8) {
-     if (UseBiasedLocking) {
+     if (try_bias) {
         biased_locking_exit(mark_addr, Rscratch, done);
      }
 
@@ -3077,7 +3079,7 @@
    // I$ effects.
    Label LStacked ;
 
-   if (UseBiasedLocking) {
+   if (try_bias) {
       // TODO: eliminate redundant LDs of obj->mark
       biased_locking_exit(mark_addr, Rscratch, done);
    }
--- a/src/cpu/sparc/vm/assembler_sparc.hpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/cpu/sparc/vm/assembler_sparc.hpp	Thu Dec 04 17:48:02 2008 -0800
@@ -2220,9 +2220,13 @@
 
   // These set the icc condition code to equal if the lock succeeded
   // and notEqual if it failed and requires a slow case
-  void compiler_lock_object(Register Roop, Register Rmark, Register Rbox, Register Rscratch,
-                              BiasedLockingCounters* counters = NULL);
-  void compiler_unlock_object(Register Roop, Register Rmark, Register Rbox, Register Rscratch);
+  void compiler_lock_object(Register Roop, Register Rmark, Register Rbox,
+                            Register Rscratch,
+                            BiasedLockingCounters* counters = NULL,
+                            bool try_bias = UseBiasedLocking);
+  void compiler_unlock_object(Register Roop, Register Rmark, Register Rbox,
+                              Register Rscratch,
+                              bool try_bias = UseBiasedLocking);
 
   // Biased locking support
   // Upon entry, lock_reg must point to the lock record on the stack,
--- a/src/cpu/sparc/vm/interp_masm_sparc.cpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/cpu/sparc/vm/interp_masm_sparc.cpp	Thu Dec 04 17:48:02 2008 -0800
@@ -906,7 +906,7 @@
 
   // load next super to check
   if (UseCompressedOops) {
-    ld( Rtmp2, arrayOopDesc::base_offset_in_bytes(T_OBJECT), Rtmp3);
+    lduw( Rtmp2, arrayOopDesc::base_offset_in_bytes(T_OBJECT), Rtmp3);
     // Bump array pointer forward one oop
     add( Rtmp2, 4, Rtmp2 );
   } else {
--- a/src/cpu/sparc/vm/sparc.ad	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/cpu/sparc/vm/sparc.ad	Thu Dec 04 17:48:02 2008 -0800
@@ -395,6 +395,7 @@
                   );
 
 reg_class g1_regL(R_G1H,R_G1);
+reg_class g3_regL(R_G3H,R_G3);
 reg_class o2_regL(R_O2H,R_O2);
 reg_class o7_regL(R_O7H,R_O7);
 
@@ -1743,7 +1744,7 @@
 //
 // NOTE: If the platform does not provide any short branch variants, then
 //       this method should return false for offset 0.
-bool Matcher::is_short_branch_offset(int offset) {
+bool Matcher::is_short_branch_offset(int rule, int offset) {
   return false;
 }
 
@@ -1926,18 +1927,23 @@
                        $mem$$base, $mem$$disp, $mem$$index, $dst$$reg);
   %}
 
+  enc_class simple_form3_mem_reg( memory mem, iRegI dst ) %{
+    emit_form3_mem_reg(cbuf, this, $primary, -1,
+                       $mem$$base, $mem$$disp, $mem$$index, $dst$$reg);
+  %}
+
   enc_class form3_mem_reg_little( memory mem, iRegI dst) %{
-    emit_form3_mem_reg_asi(cbuf, this, $primary, $tertiary,
+    emit_form3_mem_reg_asi(cbuf, this, $primary, -1,
                      $mem$$base, $mem$$disp, $mem$$index, $dst$$reg, Assembler::ASI_PRIMARY_LITTLE);
   %}
 
   enc_class form3_mem_prefetch_read( memory mem ) %{
-    emit_form3_mem_reg(cbuf, this, $primary, $tertiary,
+    emit_form3_mem_reg(cbuf, this, $primary, -1,
                        $mem$$base, $mem$$disp, $mem$$index, 0/*prefetch function many-reads*/);
   %}
 
   enc_class form3_mem_prefetch_write( memory mem ) %{
-    emit_form3_mem_reg(cbuf, this, $primary, $tertiary,
+    emit_form3_mem_reg(cbuf, this, $primary, -1,
                        $mem$$base, $mem$$disp, $mem$$index, 2/*prefetch function many-writes*/);
   %}
 
@@ -1945,8 +1951,8 @@
     assert( Assembler::is_simm13($mem$$disp  ), "need disp and disp+4" );
     assert( Assembler::is_simm13($mem$$disp+4), "need disp and disp+4" );
     guarantee($mem$$index == R_G0_enc, "double index?");
-    emit_form3_mem_reg(cbuf, this, $primary, $tertiary, $mem$$base, $mem$$disp+4, R_G0_enc, R_O7_enc );
-    emit_form3_mem_reg(cbuf, this, $primary, $tertiary, $mem$$base, $mem$$disp,   R_G0_enc, $reg$$reg );
+    emit_form3_mem_reg(cbuf, this, $primary, -1, $mem$$base, $mem$$disp+4, R_G0_enc, R_O7_enc );
+    emit_form3_mem_reg(cbuf, this, $primary, -1, $mem$$base, $mem$$disp,   R_G0_enc, $reg$$reg );
     emit3_simm13( cbuf, Assembler::arith_op, $reg$$reg, Assembler::sllx_op3, $reg$$reg, 0x1020 );
     emit3( cbuf, Assembler::arith_op, $reg$$reg, Assembler::or_op3, $reg$$reg, 0, R_O7_enc );
   %}
@@ -1956,14 +1962,14 @@
     assert( Assembler::is_simm13($mem$$disp+4), "need disp and disp+4" );
     guarantee($mem$$index == R_G0_enc, "double index?");
     // Load long with 2 instructions
-    emit_form3_mem_reg(cbuf, this, $primary, $tertiary, $mem$$base, $mem$$disp,   R_G0_enc, $reg$$reg+0 );
-    emit_form3_mem_reg(cbuf, this, $primary, $tertiary, $mem$$base, $mem$$disp+4, R_G0_enc, $reg$$reg+1 );
+    emit_form3_mem_reg(cbuf, this, $primary, -1, $mem$$base, $mem$$disp,   R_G0_enc, $reg$$reg+0 );
+    emit_form3_mem_reg(cbuf, this, $primary, -1, $mem$$base, $mem$$disp+4, R_G0_enc, $reg$$reg+1 );
   %}
 
   //%%% form3_mem_plus_4_reg is a hack--get rid of it
   enc_class form3_mem_plus_4_reg( memory mem, iRegI dst ) %{
     guarantee($mem$$disp, "cannot offset a reg-reg operand by 4");
-    emit_form3_mem_reg(cbuf, this, $primary, $tertiary, $mem$$base, $mem$$disp + 4, $mem$$index, $dst$$reg);
+    emit_form3_mem_reg(cbuf, this, $primary, -1, $mem$$base, $mem$$disp + 4, $mem$$index, $dst$$reg);
   %}
 
   enc_class form3_g0_rs2_rd_move( iRegI rs2, iRegI rd ) %{
@@ -2683,7 +2689,7 @@
     assert(Rbox  != Rscratch, "");
     assert(Rbox  != Rmark, "");
 
-    __ compiler_lock_object(Roop, Rmark, Rbox, Rscratch, _counters);
+    __ compiler_lock_object(Roop, Rmark, Rbox, Rscratch, _counters, UseBiasedLocking && !UseOptoBiasInlining);
 %}
 
 enc_class Fast_Unlock(iRegP oop, iRegP box, o7RegP scratch, iRegP scratch2) %{
@@ -2699,7 +2705,7 @@
     assert(Rbox  != Rscratch, "");
     assert(Rbox  != Rmark, "");
 
-    __ compiler_unlock_object(Roop, Rmark, Rbox, Rscratch);
+    __ compiler_unlock_object(Roop, Rmark, Rbox, Rscratch, UseBiasedLocking && !UseOptoBiasInlining);
   %}
 
   enc_class enc_cas( iRegP mem, iRegP old, iRegP new ) %{
@@ -2711,8 +2717,7 @@
     // casx_under_lock picks 1 of 3 encodings:
     // For 32-bit pointers you get a 32-bit CAS
     // For 64-bit pointers you get a 64-bit CASX
-    __ casx_under_lock(Rmem, Rold, Rnew, // Swap(*Rmem,Rnew) if *Rmem == Rold
-                        (address) StubRoutines::Sparc::atomic_memory_operation_lock_addr());
+    __ casn(Rmem, Rold, Rnew); // Swap(*Rmem,Rnew) if *Rmem == Rold
     __ cmp( Rold, Rnew );
   %}
 
@@ -3761,6 +3766,14 @@
   interface(REG_INTER);
 %}
 
+operand g3RegL() %{
+  constraint(ALLOC_IN_RC(g3_regL));
+  match(iRegL);
+
+  format %{ %}
+  interface(REG_INTER);
+%}
+
 // Int Register safe
 // This is 64bit safe
 operand iRegIsafe() %{
@@ -5062,7 +5075,7 @@
   size(4);
   format %{ "LDF    $src,$dst\t! stkI to regF" %}
   opcode(Assembler::ldf_op3);
-  ins_encode(form3_mem_reg(src, dst));
+  ins_encode(simple_form3_mem_reg(src, dst));
   ins_pipe(floadF_stk);
 %}
 
@@ -5073,7 +5086,7 @@
   size(4);
   format %{ "LDDF   $src,$dst\t! stkL to regD" %}
   opcode(Assembler::lddf_op3);
-  ins_encode(form3_mem_reg(src, dst));
+  ins_encode(simple_form3_mem_reg(src, dst));
   ins_pipe(floadD_stk);
 %}
 
@@ -5084,7 +5097,7 @@
   size(4);
   format %{ "STF    $src,$dst\t! regF to stkI" %}
   opcode(Assembler::stf_op3);
-  ins_encode(form3_mem_reg(dst, src));
+  ins_encode(simple_form3_mem_reg(dst, src));
   ins_pipe(fstoreF_stk_reg);
 %}
 
@@ -5095,7 +5108,7 @@
   size(4);
   format %{ "STDF   $src,$dst\t! regD to stkL" %}
   opcode(Assembler::stdf_op3);
-  ins_encode(form3_mem_reg(dst, src));
+  ins_encode(simple_form3_mem_reg(dst, src));
   ins_pipe(fstoreD_stk_reg);
 %}
 
@@ -5106,7 +5119,7 @@
   format %{ "STW    $src,$dst.hi\t! long\n\t"
             "STW    R_G0,$dst.lo" %}
   opcode(Assembler::stw_op3);
-  ins_encode(form3_mem_reg(dst, src), form3_mem_plus_4_reg(dst, R_G0));
+  ins_encode(simple_form3_mem_reg(dst, src), form3_mem_plus_4_reg(dst, R_G0));
   ins_pipe(lstoreI_stk_reg);
 %}
 
@@ -5117,7 +5130,7 @@
   size(4);
   format %{ "STX    $src,$dst\t! regL to stkD" %}
   opcode(Assembler::stx_op3);
-  ins_encode( form3_mem_reg( dst, src ) );
+  ins_encode(simple_form3_mem_reg( dst, src ) );
   ins_pipe(istore_stk_reg);
 %}
 
@@ -5131,7 +5144,7 @@
   size(4);
   format %{ "LDUW   $src,$dst\t!stk" %}
   opcode(Assembler::lduw_op3);
-  ins_encode( form3_mem_reg( src, dst ) );
+  ins_encode(simple_form3_mem_reg( src, dst ) );
   ins_pipe(iload_mem);
 %}
 
@@ -5143,7 +5156,7 @@
   size(4);
   format %{ "STW    $src,$dst\t!stk" %}
   opcode(Assembler::stw_op3);
-  ins_encode( form3_mem_reg( dst, src ) );
+  ins_encode(simple_form3_mem_reg( dst, src ) );
   ins_pipe(istore_mem_reg);
 %}
 
@@ -5155,7 +5168,7 @@
   size(4);
   format %{ "LDX    $src,$dst\t! long" %}
   opcode(Assembler::ldx_op3);
-  ins_encode( form3_mem_reg( src, dst ) );
+  ins_encode(simple_form3_mem_reg( src, dst ) );
   ins_pipe(iload_mem);
 %}
 
@@ -5167,7 +5180,7 @@
   size(4);
   format %{ "STX    $src,$dst\t! long" %}
   opcode(Assembler::stx_op3);
-  ins_encode( form3_mem_reg( dst, src ) );
+  ins_encode(simple_form3_mem_reg( dst, src ) );
   ins_pipe(istore_mem_reg);
 %}
 
@@ -5179,7 +5192,7 @@
   size(4);
   format %{ "LDX    $src,$dst\t!ptr" %}
   opcode(Assembler::ldx_op3);
-  ins_encode( form3_mem_reg( src, dst ) );
+  ins_encode(simple_form3_mem_reg( src, dst ) );
   ins_pipe(iload_mem);
 %}
 
@@ -5190,7 +5203,7 @@
   size(4);
   format %{ "STX    $src,$dst\t!ptr" %}
   opcode(Assembler::stx_op3);
-  ins_encode( form3_mem_reg( dst, src ) );
+  ins_encode(simple_form3_mem_reg( dst, src ) );
   ins_pipe(istore_mem_reg);
 %}
 #else // _LP64
@@ -5200,7 +5213,7 @@
   ins_cost(MEMORY_REF_COST);
   format %{ "LDUW   $src,$dst\t!ptr" %}
   opcode(Assembler::lduw_op3, Assembler::ldst_op);
-  ins_encode( form3_mem_reg( src, dst ) );
+  ins_encode(simple_form3_mem_reg( src, dst ) );
   ins_pipe(iload_mem);
 %}
 
@@ -5210,7 +5223,7 @@
   ins_cost(MEMORY_REF_COST);
   format %{ "STW    $src,$dst\t!ptr" %}
   opcode(Assembler::stw_op3, Assembler::ldst_op);
-  ins_encode( form3_mem_reg( dst, src ) );
+  ins_encode(simple_form3_mem_reg( dst, src ) );
   ins_pipe(istore_mem_reg);
 %}
 #endif // _LP64
@@ -5273,7 +5286,7 @@
   size(4);
   format %{ "LDSB   $mem,$dst" %}
   opcode(Assembler::ldsb_op3);
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(iload_mask_mem);
 %}
 
@@ -5285,7 +5298,7 @@
   size(4);
   format %{ "LDUB   $mem,$dst" %}
   opcode(Assembler::ldub_op3);
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(iload_mask_mem);
 %}
 
@@ -5297,7 +5310,7 @@
   size(4);
   format %{ "LDUB   $mem,$dst" %}
   opcode(Assembler::ldub_op3);
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(iload_mask_mem);
 %}
 
@@ -5309,7 +5322,7 @@
   size(4);
   format %{ "LDUH   $mem,$dst" %}
   opcode(Assembler::lduh_op3);
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(iload_mask_mem);
 %}
 
@@ -5321,7 +5334,7 @@
   size(4);
   format %{ "LDUH   $mem,$dst" %}
   opcode(Assembler::lduh_op3);
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(iload_mask_mem);
 %}
 
@@ -5333,7 +5346,7 @@
 
   format %{ "LDUW   $mem,$dst" %}
   opcode(Assembler::lduw_op3);
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(iload_mem);
 %}
 
@@ -5344,7 +5357,7 @@
   size(4);
   format %{ "LDX    $mem,$dst\t! long" %}
   opcode(Assembler::ldx_op3);
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(iload_mem);
 %}
 
@@ -5359,7 +5372,7 @@
           "\tSLLX   #32, $dst, $dst\n"
           "\tOR     $dst, R_O7, $dst" %}
   opcode(Assembler::lduw_op3);
-  ins_encode( form3_mem_reg_long_unaligned_marshal( mem, dst ));
+  ins_encode(form3_mem_reg_long_unaligned_marshal( mem, dst ));
   ins_pipe(iload_mem);
 %}
 
@@ -5370,7 +5383,7 @@
   size(4);
   format %{ "LDDF   $mem,$dst\t! packed8B" %}
   opcode(Assembler::lddf_op3);
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(floadD_mem);
 %}
 
@@ -5381,7 +5394,7 @@
   size(4);
   format %{ "LDDF   $mem,$dst\t! packed4C" %}
   opcode(Assembler::lddf_op3);
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(floadD_mem);
 %}
 
@@ -5392,7 +5405,7 @@
   size(4);
   format %{ "LDDF   $mem,$dst\t! packed4S" %}
   opcode(Assembler::lddf_op3);
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(floadD_mem);
 %}
 
@@ -5403,7 +5416,7 @@
   size(4);
   format %{ "LDDF   $mem,$dst\t! packed2I" %}
   opcode(Assembler::lddf_op3);
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(floadD_mem);
 %}
 
@@ -5415,7 +5428,7 @@
   size(4);
   format %{ "LDUW   $mem,$dst\t! range" %}
   opcode(Assembler::lduw_op3);
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(iload_mem);
 %}
 
@@ -5427,7 +5440,7 @@
 
   format %{ "LDF    $mem,$dst\t! for fitos/fitod" %}
   opcode(Assembler::ldf_op3);
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(floadF_mem);
 %}
 
@@ -5514,7 +5527,7 @@
   size(4);
   format %{ "LDSH   $mem,$dst" %}
   opcode(Assembler::ldsh_op3);
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(iload_mask_mem);
 %}
 
@@ -5526,7 +5539,7 @@
   size(4);
   format %{ "LDDF   $mem,$dst" %}
   opcode(Assembler::lddf_op3);
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(floadD_mem);
 %}
 
@@ -5550,7 +5563,7 @@
   size(4);
   format %{ "LDF    $mem,$dst" %}
   opcode(Assembler::ldf_op3);
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(floadF_mem);
 %}
 
@@ -5719,7 +5732,7 @@
   size(4);
   format %{ "STB    $src,$mem\t! byte" %}
   opcode(Assembler::stb_op3);
-  ins_encode( form3_mem_reg( mem, src ) );
+  ins_encode(simple_form3_mem_reg( mem, src ) );
   ins_pipe(istore_mem_reg);
 %}
 
@@ -5730,7 +5743,7 @@
   size(4);
   format %{ "STB    $src,$mem\t! byte" %}
   opcode(Assembler::stb_op3);
-  ins_encode( form3_mem_reg( mem, R_G0 ) );
+  ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
   ins_pipe(istore_mem_zero);
 %}
 
@@ -5741,7 +5754,7 @@
   size(4);
   format %{ "STB    $src,$mem\t! CMS card-mark byte 0" %}
   opcode(Assembler::stb_op3);
-  ins_encode( form3_mem_reg( mem, R_G0 ) );
+  ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
   ins_pipe(istore_mem_zero);
 %}
 
@@ -5753,7 +5766,7 @@
   size(4);
   format %{ "STH    $src,$mem\t! short" %}
   opcode(Assembler::sth_op3);
-  ins_encode( form3_mem_reg( mem, src ) );
+  ins_encode(simple_form3_mem_reg( mem, src ) );
   ins_pipe(istore_mem_reg);
 %}
 
@@ -5764,7 +5777,7 @@
   size(4);
   format %{ "STH    $src,$mem\t! short" %}
   opcode(Assembler::sth_op3);
-  ins_encode( form3_mem_reg( mem, R_G0 ) );
+  ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
   ins_pipe(istore_mem_zero);
 %}
 
@@ -5776,7 +5789,7 @@
   size(4);
   format %{ "STW    $src,$mem" %}
   opcode(Assembler::stw_op3);
-  ins_encode( form3_mem_reg( mem, src ) );
+  ins_encode(simple_form3_mem_reg( mem, src ) );
   ins_pipe(istore_mem_reg);
 %}
 
@@ -5787,7 +5800,7 @@
   size(4);
   format %{ "STX    $src,$mem\t! long" %}
   opcode(Assembler::stx_op3);
-  ins_encode( form3_mem_reg( mem, src ) );
+  ins_encode(simple_form3_mem_reg( mem, src ) );
   ins_pipe(istore_mem_reg);
 %}
 
@@ -5798,7 +5811,7 @@
   size(4);
   format %{ "STW    $src,$mem" %}
   opcode(Assembler::stw_op3);
-  ins_encode( form3_mem_reg( mem, R_G0 ) );
+  ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
   ins_pipe(istore_mem_zero);
 %}
 
@@ -5809,7 +5822,7 @@
   size(4);
   format %{ "STX    $src,$mem" %}
   opcode(Assembler::stx_op3);
-  ins_encode( form3_mem_reg( mem, R_G0 ) );
+  ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
   ins_pipe(istore_mem_zero);
 %}
 
@@ -5821,7 +5834,7 @@
   size(4);
   format %{ "STF    $src,$mem\t! after fstoi/fdtoi" %}
   opcode(Assembler::stf_op3);
-  ins_encode( form3_mem_reg( mem, src ) );
+  ins_encode(simple_form3_mem_reg( mem, src ) );
   ins_pipe(fstoreF_mem_reg);
 %}
 
@@ -5904,7 +5917,7 @@
   size(4);
   format %{ "STDF   $src,$mem" %}
   opcode(Assembler::stdf_op3);
-  ins_encode( form3_mem_reg( mem, src ) );
+  ins_encode(simple_form3_mem_reg( mem, src ) );
   ins_pipe(fstoreD_mem_reg);
 %}
 
@@ -5915,7 +5928,7 @@
   size(4);
   format %{ "STX    $src,$mem" %}
   opcode(Assembler::stx_op3);
-  ins_encode( form3_mem_reg( mem, R_G0 ) );
+  ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
   ins_pipe(fstoreD_mem_zero);
 %}
 
@@ -5927,7 +5940,7 @@
   size(4);
   format %{ "STF    $src,$mem" %}
   opcode(Assembler::stf_op3);
-  ins_encode( form3_mem_reg( mem, src ) );
+  ins_encode(simple_form3_mem_reg( mem, src ) );
   ins_pipe(fstoreF_mem_reg);
 %}
 
@@ -5938,7 +5951,7 @@
   size(4);
   format %{ "STW    $src,$mem\t! storeF0" %}
   opcode(Assembler::stw_op3);
-  ins_encode( form3_mem_reg( mem, R_G0 ) );
+  ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
   ins_pipe(fstoreF_mem_zero);
 %}
 
@@ -5949,7 +5962,7 @@
   size(4);
   format %{ "STDF   $src,$mem\t! packed8B" %}
   opcode(Assembler::stdf_op3);
-  ins_encode( form3_mem_reg( mem, src ) );
+  ins_encode(simple_form3_mem_reg( mem, src ) );
   ins_pipe(fstoreD_mem_reg);
 %}
 
@@ -6004,7 +6017,7 @@
   size(4);
   format %{ "STX    $zero,$mem\t! packed8B" %}
   opcode(Assembler::stx_op3);
-  ins_encode( form3_mem_reg( mem, R_G0 ) );
+  ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
   ins_pipe(fstoreD_mem_zero);
 %}
 
@@ -6015,7 +6028,7 @@
   size(4);
   format %{ "STDF   $src,$mem\t! packed4C" %}
   opcode(Assembler::stdf_op3);
-  ins_encode( form3_mem_reg( mem, src ) );
+  ins_encode(simple_form3_mem_reg( mem, src ) );
   ins_pipe(fstoreD_mem_reg);
 %}
 
@@ -6026,7 +6039,7 @@
   size(4);
   format %{ "STX    $zero,$mem\t! packed4C" %}
   opcode(Assembler::stx_op3);
-  ins_encode( form3_mem_reg( mem, R_G0 ) );
+  ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
   ins_pipe(fstoreD_mem_zero);
 %}
 
@@ -6037,7 +6050,7 @@
   size(4);
   format %{ "STDF   $src,$mem\t! packed2I" %}
   opcode(Assembler::stdf_op3);
-  ins_encode( form3_mem_reg( mem, src ) );
+  ins_encode(simple_form3_mem_reg( mem, src ) );
   ins_pipe(fstoreD_mem_reg);
 %}
 
@@ -6048,7 +6061,7 @@
   size(4);
   format %{ "STX    $zero,$mem\t! packed2I" %}
   opcode(Assembler::stx_op3);
-  ins_encode( form3_mem_reg( mem, R_G0 ) );
+  ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
   ins_pipe(fstoreD_mem_zero);
 %}
 
@@ -6162,7 +6175,7 @@
   ins_cost(MEMORY_REF_COST);
   format %{ "STDF   $src,$stkSlot\t!stk" %}
   opcode(Assembler::stdf_op3);
-  ins_encode(form3_mem_reg(stkSlot, src));
+  ins_encode(simple_form3_mem_reg(stkSlot, src));
   ins_pipe(fstoreD_stk_reg);
 %}
 
@@ -6172,7 +6185,7 @@
   ins_cost(MEMORY_REF_COST);
   format %{ "LDDF   $stkSlot,$dst\t!stk" %}
   opcode(Assembler::lddf_op3);
-  ins_encode(form3_mem_reg(stkSlot, dst));
+  ins_encode(simple_form3_mem_reg(stkSlot, dst));
   ins_pipe(floadD_stk);
 %}
 
@@ -6182,7 +6195,7 @@
   ins_cost(MEMORY_REF_COST);
   format %{ "STF   $src,$stkSlot\t!stk" %}
   opcode(Assembler::stf_op3);
-  ins_encode(form3_mem_reg(stkSlot, src));
+  ins_encode(simple_form3_mem_reg(stkSlot, src));
   ins_pipe(fstoreF_stk_reg);
 %}
 
@@ -6584,7 +6597,7 @@
   size(4);
   format %{ "LDX    $mem,$dst\t! long" %}
   opcode(Assembler::ldx_op3);
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(iload_mem);
 %}
 
@@ -6597,32 +6610,23 @@
   ins_pipe( long_memory_op );
 %}
 
-instruct storeLConditional_bool(iRegP mem_ptr, iRegL oldval, iRegL newval, iRegI res, o7RegI tmp1, flagsReg ccr ) %{
-  match(Set res (StoreLConditional mem_ptr (Binary oldval newval)));
-  effect( USE mem_ptr, KILL ccr, KILL tmp1);
-  // Marshal the register pairs into V9 64-bit registers, then do the compare-and-swap
-  format %{
-            "MOV    $newval,R_O7\n\t"
-            "CASXA  [$mem_ptr],$oldval,R_O7\t! If $oldval==[$mem_ptr] Then store R_O7 into [$mem_ptr], set R_O7=[$mem_ptr] in any case\n\t"
-            "CMP    $oldval,R_O7\t\t! See if we made progress\n\t"
-            "MOV    1,$res\n\t"
-            "MOVne  xcc,R_G0,$res"
-  %}
-  ins_encode( enc_casx(mem_ptr, oldval, newval),
-              enc_lflags_ne_to_boolean(res) );
+// Conditional-store of an int value.
+instruct storeIConditional( iRegP mem_ptr, iRegI oldval, g3RegI newval, flagsReg icc ) %{
+  match(Set icc (StoreIConditional mem_ptr (Binary oldval newval)));
+  effect( KILL newval );
+  format %{ "CASA   [$mem_ptr],$oldval,$newval\t! If $oldval==[$mem_ptr] Then store $newval into [$mem_ptr], set $newval=[$mem_ptr] in any case\n\t"
+            "CMP    $oldval,$newval\t\t! See if we made progress"  %}
+  ins_encode( enc_cas(mem_ptr,oldval,newval) );
   ins_pipe( long_memory_op );
 %}
 
-instruct storeLConditional_flags(iRegP mem_ptr, iRegL oldval, iRegL newval, flagsRegL xcc, o7RegI tmp1, immI0 zero) %{
-  match(Set xcc (CmpI (StoreLConditional mem_ptr (Binary oldval newval)) zero));
-  effect( USE mem_ptr, KILL tmp1);
-  // Marshal the register pairs into V9 64-bit registers, then do the compare-and-swap
-  format %{
-            "MOV    $newval,R_O7\n\t"
-            "CASXA  [$mem_ptr],$oldval,R_O7\t! If $oldval==[$mem_ptr] Then store R_O7 into [$mem_ptr], set R_O7=[$mem_ptr] in any case\n\t"
-            "CMP    $oldval,R_O7\t\t! See if we made progress"
-  %}
-  ins_encode( enc_casx(mem_ptr, oldval, newval));
+// Conditional-store of a long value.
+instruct storeLConditional( iRegP mem_ptr, iRegL oldval, g3RegL newval, flagsRegL xcc ) %{
+  match(Set xcc (StoreLConditional mem_ptr (Binary oldval newval)));
+  effect( KILL newval );
+  format %{ "CASXA  [$mem_ptr],$oldval,$newval\t! If $oldval==[$mem_ptr] Then store $newval into [$mem_ptr], set $newval=[$mem_ptr] in any case\n\t"
+            "CMP    $oldval,$newval\t\t! See if we made progress"  %}
+  ins_encode( enc_cas(mem_ptr,oldval,newval) );
   ins_pipe( long_memory_op );
 %}
 
@@ -7405,6 +7409,34 @@
   ins_pipe(ialu_reg_imm);
 %}
 
+#ifndef _LP64
+
+// Use sp_ptr_RegP to match G2 (TLS register) without spilling.
+instruct orI_reg_castP2X(iRegI dst, iRegI src1, sp_ptr_RegP src2) %{
+  match(Set dst (OrI src1 (CastP2X src2)));
+
+  size(4);
+  format %{ "OR     $src1,$src2,$dst" %}
+  opcode(Assembler::or_op3, Assembler::arith_op);
+  ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) );
+  ins_pipe(ialu_reg_reg);
+%}
+
+#else
+
+instruct orL_reg_castP2X(iRegL dst, iRegL src1, sp_ptr_RegP src2) %{
+  match(Set dst (OrL src1 (CastP2X src2)));
+
+  ins_cost(DEFAULT_COST);
+  size(4);
+  format %{ "OR     $src1,$src2,$dst\t! long" %}
+  opcode(Assembler::or_op3, Assembler::arith_op);
+  ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) );
+  ins_pipe(ialu_reg_reg);
+%}
+
+#endif
+
 // Xor Instructions
 // Register Xor
 instruct xorI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
@@ -7666,7 +7698,7 @@
   format %{ "LDF    $mem,$dst\n\t"
             "FITOD  $dst,$dst" %}
   opcode(Assembler::ldf_op3, Assembler::fitod_opf);
-  ins_encode( form3_mem_reg( mem, dst ), form3_convI2F(dst, dst));
+  ins_encode(simple_form3_mem_reg( mem, dst ), form3_convI2F(dst, dst));
   ins_pipe(floadF_mem);
 %}
 
@@ -7696,7 +7728,7 @@
   format %{ "LDF    $mem,$dst\n\t"
             "FITOS  $dst,$dst" %}
   opcode(Assembler::ldf_op3, Assembler::fitos_opf);
-  ins_encode( form3_mem_reg( mem, dst ), form3_convI2F(dst, dst));
+  ins_encode(simple_form3_mem_reg( mem, dst ), form3_convI2F(dst, dst));
   ins_pipe(floadF_mem);
 %}
 
@@ -7738,7 +7770,7 @@
   size(4);
   format %{ "LDUW   $src,$dst\t! MoveF2I" %}
   opcode(Assembler::lduw_op3);
-  ins_encode( form3_mem_reg( src, dst ) );
+  ins_encode(simple_form3_mem_reg( src, dst ) );
   ins_pipe(iload_mem);
 %}
 
@@ -7750,7 +7782,7 @@
   size(4);
   format %{ "LDF    $src,$dst\t! MoveI2F" %}
   opcode(Assembler::ldf_op3);
-  ins_encode(form3_mem_reg(src, dst));
+  ins_encode(simple_form3_mem_reg(src, dst));
   ins_pipe(floadF_stk);
 %}
 
@@ -7762,7 +7794,7 @@
   size(4);
   format %{ "LDX    $src,$dst\t! MoveD2L" %}
   opcode(Assembler::ldx_op3);
-  ins_encode( form3_mem_reg( src, dst ) );
+  ins_encode(simple_form3_mem_reg( src, dst ) );
   ins_pipe(iload_mem);
 %}
 
@@ -7774,7 +7806,7 @@
   size(4);
   format %{ "LDDF   $src,$dst\t! MoveL2D" %}
   opcode(Assembler::lddf_op3);
-  ins_encode(form3_mem_reg(src, dst));
+  ins_encode(simple_form3_mem_reg(src, dst));
   ins_pipe(floadD_stk);
 %}
 
@@ -7786,7 +7818,7 @@
   size(4);
   format %{ "STF   $src,$dst\t!MoveF2I" %}
   opcode(Assembler::stf_op3);
-  ins_encode(form3_mem_reg(dst, src));
+  ins_encode(simple_form3_mem_reg(dst, src));
   ins_pipe(fstoreF_stk_reg);
 %}
 
@@ -7798,7 +7830,7 @@
   size(4);
   format %{ "STW    $src,$dst\t!MoveI2F" %}
   opcode(Assembler::stw_op3);
-  ins_encode( form3_mem_reg( dst, src ) );
+  ins_encode(simple_form3_mem_reg( dst, src ) );
   ins_pipe(istore_mem_reg);
 %}
 
@@ -7810,7 +7842,7 @@
   size(4);
   format %{ "STDF   $src,$dst\t!MoveD2L" %}
   opcode(Assembler::stdf_op3);
-  ins_encode(form3_mem_reg(dst, src));
+  ins_encode(simple_form3_mem_reg(dst, src));
   ins_pipe(fstoreD_stk_reg);
 %}
 
@@ -7822,7 +7854,7 @@
   size(4);
   format %{ "STX    $src,$dst\t!MoveL2D" %}
   opcode(Assembler::stx_op3);
-  ins_encode( form3_mem_reg( dst, src ) );
+  ins_encode(simple_form3_mem_reg( dst, src ) );
   ins_pipe(istore_mem_reg);
 %}
 
--- a/src/cpu/sparc/vm/stubGenerator_sparc.cpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/cpu/sparc/vm/stubGenerator_sparc.cpp	Thu Dec 04 17:48:02 2008 -0800
@@ -956,7 +956,7 @@
     // Load a little early; will load 1 off the end of the array.
     // Ok for now; revisit if we have other uses of this routine.
     if (UseCompressedOops) {
-      __ ld(L1_ary_ptr,0,L2_super);// Will load a little early
+      __ lduw(L1_ary_ptr,0,L2_super);// Will load a little early
     } else {
       __ ld_ptr(L1_ary_ptr,0,L2_super);// Will load a little early
     }
@@ -973,7 +973,7 @@
 #ifdef  _LP64
       __ subcc(L2_super,L4_ooptmp,Rret);   // Check for match; zero in Rret for a hit
       __ br( Assembler::notEqual, false, Assembler::pt, loop );
-      __ delayed()->ld(L1_ary_ptr,0,L2_super);// Will load a little early
+      __ delayed()->lduw(L1_ary_ptr,0,L2_super);// Will load a little early
 #else
       ShouldNotReachHere();
 #endif
--- a/src/cpu/sparc/vm/templateTable_sparc.cpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/cpu/sparc/vm/templateTable_sparc.cpp	Thu Dec 04 17:48:02 2008 -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/src/cpu/x86/vm/assembler_x86.cpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/cpu/x86/vm/assembler_x86.cpp	Thu Dec 04 17:48:02 2008 -0800
@@ -621,6 +621,10 @@
     debug_only(has_disp32 = true);
     break;
 
+  case 0xF0:                    // Lock
+    assert(os::is_MP(), "only on MP");
+    goto again_after_prefix;
+
   case 0xF3:                    // For SSE
   case 0xF2:                    // For SSE2
     switch (0xFF & *ip++) {
--- a/src/cpu/x86/vm/assembler_x86.hpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/cpu/x86/vm/assembler_x86.hpp	Thu Dec 04 17:48:02 2008 -0800
@@ -1780,7 +1780,8 @@
   // check info (currently consumed only by C1). If
   // swap_reg_contains_mark is true then returns -1 as it is assumed
   // the calling code has already passed any potential faults.
-  int biased_locking_enter(Register lock_reg, Register obj_reg, Register swap_reg, Register tmp_reg,
+  int biased_locking_enter(Register lock_reg, Register obj_reg,
+                           Register swap_reg, Register tmp_reg,
                            bool swap_reg_contains_mark,
                            Label& done, Label* slow_case = NULL,
                            BiasedLockingCounters* counters = NULL);
--- a/src/cpu/x86/vm/register_definitions_x86.cpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/cpu/x86/vm/register_definitions_x86.cpp	Thu Dec 04 17:48:02 2008 -0800
@@ -22,9 +22,6 @@
  *
  */
 
-// make sure the defines don't screw up the declarations later on in this file
-#define DONT_USE_REGISTER_DEFINES
-
 #include "incls/_precompiled.incl"
 #include "incls/_register_definitions_x86.cpp.incl"
 
--- a/src/cpu/x86/vm/x86_32.ad	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/cpu/x86/vm/x86_32.ad	Thu Dec 04 17:48:02 2008 -0800
@@ -495,8 +495,8 @@
 void MachPrologNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
   Compile* C = ra_->C;
   if( C->in_24_bit_fp_mode() ) {
-    tty->print("FLDCW  24 bit fpu control word");
-    tty->print_cr(""); tty->print("\t");
+    st->print("FLDCW  24 bit fpu control word");
+    st->print_cr(""); st->print("\t");
   }
 
   int framesize = C->frame_slots() << LogBytesPerInt;
@@ -510,22 +510,22 @@
   // stack.  But the stack safety zone should account for that.
   // See bugs 4446381, 4468289, 4497237.
   if (C->need_stack_bang(framesize)) {
-    tty->print_cr("# stack bang"); tty->print("\t");
+    st->print_cr("# stack bang"); st->print("\t");
   }
-  tty->print_cr("PUSHL  EBP"); tty->print("\t");
+  st->print_cr("PUSHL  EBP"); st->print("\t");
 
   if( VerifyStackAtCalls ) { // Majik cookie to verify stack depth
-    tty->print("PUSH   0xBADB100D\t# Majik cookie for stack depth check");
-    tty->print_cr(""); tty->print("\t");
+    st->print("PUSH   0xBADB100D\t# Majik cookie for stack depth check");
+    st->print_cr(""); st->print("\t");
     framesize -= wordSize;
   }
 
   if ((C->in_24_bit_fp_mode() || VerifyStackAtCalls ) && framesize < 128 ) {
     if (framesize) {
-      tty->print("SUB    ESP,%d\t# Create frame",framesize);
+      st->print("SUB    ESP,%d\t# Create frame",framesize);
     }
   } else {
-    tty->print("SUB    ESP,%d\t# Create frame",framesize);
+    st->print("SUB    ESP,%d\t# Create frame",framesize);
   }
 }
 #endif
@@ -725,18 +725,19 @@
   return rc_xmm;
 }
 
-static int impl_helper( CodeBuffer *cbuf, bool do_size, bool is_load, int offset, int reg, int opcode, const char *op_str, int size ) {
+static int impl_helper( CodeBuffer *cbuf, bool do_size, bool is_load, int offset, int reg,
+                        int opcode, const char *op_str, int size, outputStream* st ) {
   if( cbuf ) {
     emit_opcode  (*cbuf, opcode );
     encode_RegMem(*cbuf, Matcher::_regEncode[reg], ESP_enc, 0x4, 0, offset, false);
 #ifndef PRODUCT
   } else if( !do_size ) {
-    if( size != 0 ) tty->print("\n\t");
+    if( size != 0 ) st->print("\n\t");
     if( opcode == 0x8B || opcode == 0x89 ) { // MOV
-      if( is_load ) tty->print("%s   %s,[ESP + #%d]",op_str,Matcher::regName[reg],offset);
-      else          tty->print("%s   [ESP + #%d],%s",op_str,offset,Matcher::regName[reg]);
+      if( is_load ) st->print("%s   %s,[ESP + #%d]",op_str,Matcher::regName[reg],offset);
+      else          st->print("%s   [ESP + #%d],%s",op_str,offset,Matcher::regName[reg]);
     } else { // FLD, FST, PUSH, POP
-      tty->print("%s [ESP + #%d]",op_str,offset);
+      st->print("%s [ESP + #%d]",op_str,offset);
     }
 #endif
   }
@@ -746,7 +747,7 @@
 
 // Helper for XMM registers.  Extra opcode bits, limited syntax.
 static int impl_x_helper( CodeBuffer *cbuf, bool do_size, bool is_load,
-                         int offset, int reg_lo, int reg_hi, int size ) {
+                         int offset, int reg_lo, int reg_hi, int size, outputStream* st ) {
   if( cbuf ) {
     if( reg_lo+1 == reg_hi ) { // double move?
       if( is_load && !UseXmmLoadAndClearUpper )
@@ -764,17 +765,17 @@
     encode_RegMem(*cbuf, Matcher::_regEncode[reg_lo], ESP_enc, 0x4, 0, offset, false);
 #ifndef PRODUCT
   } else if( !do_size ) {
-    if( size != 0 ) tty->print("\n\t");
+    if( size != 0 ) st->print("\n\t");
     if( reg_lo+1 == reg_hi ) { // double move?
-      if( is_load ) tty->print("%s %s,[ESP + #%d]",
+      if( is_load ) st->print("%s %s,[ESP + #%d]",
                                UseXmmLoadAndClearUpper ? "MOVSD " : "MOVLPD",
                                Matcher::regName[reg_lo], offset);
-      else          tty->print("MOVSD  [ESP + #%d],%s",
+      else          st->print("MOVSD  [ESP + #%d],%s",
                                offset, Matcher::regName[reg_lo]);
     } else {
-      if( is_load ) tty->print("MOVSS  %s,[ESP + #%d]",
+      if( is_load ) st->print("MOVSS  %s,[ESP + #%d]",
                                Matcher::regName[reg_lo], offset);
-      else          tty->print("MOVSS  [ESP + #%d],%s",
+      else          st->print("MOVSS  [ESP + #%d],%s",
                                offset, Matcher::regName[reg_lo]);
     }
 #endif
@@ -785,7 +786,7 @@
 
 
 static int impl_movx_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo,
-                            int src_hi, int dst_hi, int size ) {
+                            int src_hi, int dst_hi, int size, outputStream* st ) {
   if( UseXmmRegToRegMoveAll ) {//Use movaps,movapd to move between xmm registers
     if( cbuf ) {
       if( (src_lo+1 == src_hi && dst_lo+1 == dst_hi) ) {
@@ -796,11 +797,11 @@
       emit_rm    (*cbuf, 0x3, Matcher::_regEncode[dst_lo], Matcher::_regEncode[src_lo] );
 #ifndef PRODUCT
     } else if( !do_size ) {
-      if( size != 0 ) tty->print("\n\t");
+      if( size != 0 ) st->print("\n\t");
       if( src_lo+1 == src_hi && dst_lo+1 == dst_hi ) { // double move?
-        tty->print("MOVAPD %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
+        st->print("MOVAPD %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
       } else {
-        tty->print("MOVAPS %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
+        st->print("MOVAPS %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
       }
 #endif
     }
@@ -813,11 +814,11 @@
       emit_rm    (*cbuf, 0x3, Matcher::_regEncode[dst_lo], Matcher::_regEncode[src_lo] );
 #ifndef PRODUCT
     } else if( !do_size ) {
-      if( size != 0 ) tty->print("\n\t");
+      if( size != 0 ) st->print("\n\t");
       if( src_lo+1 == src_hi && dst_lo+1 == dst_hi ) { // double move?
-        tty->print("MOVSD  %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
+        st->print("MOVSD  %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
       } else {
-        tty->print("MOVSS  %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
+        st->print("MOVSS  %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
       }
 #endif
     }
@@ -825,28 +826,29 @@
   }
 }
 
-static int impl_mov_helper( CodeBuffer *cbuf, bool do_size, int src, int dst, int size ) {
+static int impl_mov_helper( CodeBuffer *cbuf, bool do_size, int src, int dst, int size, outputStream* st ) {
   if( cbuf ) {
     emit_opcode(*cbuf, 0x8B );
     emit_rm    (*cbuf, 0x3, Matcher::_regEncode[dst], Matcher::_regEncode[src] );
 #ifndef PRODUCT
   } else if( !do_size ) {
-    if( size != 0 ) tty->print("\n\t");
-    tty->print("MOV    %s,%s",Matcher::regName[dst],Matcher::regName[src]);
+    if( size != 0 ) st->print("\n\t");
+    st->print("MOV    %s,%s",Matcher::regName[dst],Matcher::regName[src]);
 #endif
   }
   return size+2;
 }
 
-static int impl_fp_store_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int src_hi, int dst_lo, int dst_hi, int offset, int size ) {
+static int impl_fp_store_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int src_hi, int dst_lo, int dst_hi,
+                                 int offset, int size, outputStream* st ) {
   if( src_lo != FPR1L_num ) {      // Move value to top of FP stack, if not already there
     if( cbuf ) {
       emit_opcode( *cbuf, 0xD9 );  // FLD (i.e., push it)
       emit_d8( *cbuf, 0xC0-1+Matcher::_regEncode[src_lo] );
 #ifndef PRODUCT
     } else if( !do_size ) {
-      if( size != 0 ) tty->print("\n\t");
-      tty->print("FLD    %s",Matcher::regName[src_lo]);
+      if( size != 0 ) st->print("\n\t");
+      st->print("FLD    %s",Matcher::regName[src_lo]);
 #endif
     }
     size += 2;
@@ -864,7 +866,7 @@
     assert( !OptoReg::is_valid(src_hi) && !OptoReg::is_valid(dst_hi), "no non-adjacent float-stores" );
   }
 
-  return impl_helper(cbuf,do_size,false,offset,st_op,op,op_str,size);
+  return impl_helper(cbuf,do_size,false,offset,st_op,op,op_str,size, st);
 }
 
 uint MachSpillCopyNode::implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream* st ) const {
@@ -892,16 +894,16 @@
   if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) {
     if( src_second == dst_first ) { // overlapping stack copy ranges
       assert( src_second_rc == rc_stack && dst_second_rc == rc_stack, "we only expect a stk-stk copy here" );
-      size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_second),ESI_num,0xFF,"PUSH  ",size);
-      size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_second),EAX_num,0x8F,"POP   ",size);
+      size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_second),ESI_num,0xFF,"PUSH  ",size, st);
+      size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_second),EAX_num,0x8F,"POP   ",size, st);
       src_second_rc = dst_second_rc = rc_bad;  // flag as already moved the second bits
     }
     // move low bits
-    size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_first),ESI_num,0xFF,"PUSH  ",size);
-    size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_first),EAX_num,0x8F,"POP   ",size);
+    size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_first),ESI_num,0xFF,"PUSH  ",size, st);
+    size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_first),EAX_num,0x8F,"POP   ",size, st);
     if( src_second_rc == rc_stack && dst_second_rc == rc_stack ) { // mov second bits
-      size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_second),ESI_num,0xFF,"PUSH  ",size);
-      size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_second),EAX_num,0x8F,"POP   ",size);
+      size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_second),ESI_num,0xFF,"PUSH  ",size, st);
+      size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_second),EAX_num,0x8F,"POP   ",size, st);
     }
     return size;
   }
@@ -909,15 +911,15 @@
   // --------------------------------------
   // Check for integer reg-reg copy
   if( src_first_rc == rc_int && dst_first_rc == rc_int )
-    size = impl_mov_helper(cbuf,do_size,src_first,dst_first,size);
+    size = impl_mov_helper(cbuf,do_size,src_first,dst_first,size, st);
 
   // Check for integer store
   if( src_first_rc == rc_int && dst_first_rc == rc_stack )
-    size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_first),src_first,0x89,"MOV ",size);
+    size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_first),src_first,0x89,"MOV ",size, st);
 
   // Check for integer load
   if( dst_first_rc == rc_int && src_first_rc == rc_stack )
-    size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_first),dst_first,0x8B,"MOV ",size);
+    size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_first),dst_first,0x8B,"MOV ",size, st);
 
   // --------------------------------------
   // Check for float reg-reg copy
@@ -951,7 +953,7 @@
 
   // Check for float store
   if( src_first_rc == rc_float && dst_first_rc == rc_stack ) {
-    return impl_fp_store_helper(cbuf,do_size,src_first,src_second,dst_first,dst_second,ra_->reg2offset(dst_first),size);
+    return impl_fp_store_helper(cbuf,do_size,src_first,src_second,dst_first,dst_second,ra_->reg2offset(dst_first),size, st);
   }
 
   // Check for float load
@@ -987,17 +989,17 @@
     assert( (src_second_rc == rc_bad && dst_second_rc == rc_bad) ||
             (src_first+1 == src_second && dst_first+1 == dst_second),
             "no non-adjacent float-moves" );
-    return impl_movx_helper(cbuf,do_size,src_first,dst_first,src_second, dst_second, size);
+    return impl_movx_helper(cbuf,do_size,src_first,dst_first,src_second, dst_second, size, st);
   }
 
   // Check for xmm store
   if( src_first_rc == rc_xmm && dst_first_rc == rc_stack ) {
-    return impl_x_helper(cbuf,do_size,false,ra_->reg2offset(dst_first),src_first, src_second, size);
+    return impl_x_helper(cbuf,do_size,false,ra_->reg2offset(dst_first),src_first, src_second, size, st);
   }
 
   // Check for float xmm load
   if( dst_first_rc == rc_xmm && src_first_rc == rc_stack ) {
-    return impl_x_helper(cbuf,do_size,true ,ra_->reg2offset(src_first),dst_first, dst_second, size);
+    return impl_x_helper(cbuf,do_size,true ,ra_->reg2offset(src_first),dst_first, dst_second, size, st);
   }
 
   // Copy from float reg to xmm reg
@@ -1017,10 +1019,10 @@
     }
     size += 4;
 
-    size = impl_fp_store_helper(cbuf,do_size,src_first,src_second,dst_first,dst_second,0,size);
+    size = impl_fp_store_helper(cbuf,do_size,src_first,src_second,dst_first,dst_second,0,size, st);
 
     // Copy from the temp memory to the xmm reg.
-    size = impl_x_helper(cbuf,do_size,true ,0,dst_first, dst_second, size);
+    size = impl_x_helper(cbuf,do_size,true ,0,dst_first, dst_second, size, st);
 
     if( cbuf ) {
       emit_opcode(*cbuf,0x8D);  // LEA  ESP,[ESP+8]
@@ -1047,15 +1049,15 @@
 
   // Check for second word int-int move
   if( src_second_rc == rc_int && dst_second_rc == rc_int )
-    return impl_mov_helper(cbuf,do_size,src_second,dst_second,size);
+    return impl_mov_helper(cbuf,do_size,src_second,dst_second,size, st);
 
   // Check for second word integer store
   if( src_second_rc == rc_int && dst_second_rc == rc_stack )
-    return impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_second),src_second,0x89,"MOV ",size);
+    return impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_second),src_second,0x89,"MOV ",size, st);
 
   // Check for second word integer load
   if( dst_second_rc == rc_int && src_second_rc == rc_stack )
-    return impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_second),dst_second,0x8B,"MOV ",size);
+    return impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_second),dst_second,0x8B,"MOV ",size, st);
 
 
   Unimplemented();
@@ -1318,7 +1320,11 @@
 //
 // NOTE: If the platform does not provide any short branch variants, then
 //       this method should return false for offset 0.
-bool Matcher::is_short_branch_offset(int offset) {
+bool Matcher::is_short_branch_offset(int rule, int offset) {
+  // the short version of jmpConUCF2 contains multiple branches,
+  // making the reach slightly less
+  if (rule == jmpConUCF2_rule)
+    return (-126 <= offset && offset <= 125);
   return (-128 <= offset && offset <= 127);
 }
 
@@ -3307,7 +3313,7 @@
       // Beware -- there's a subtle invariant that fetch of the markword
       // at [FETCH], below, will never observe a biased encoding (*101b).
       // If this invariant is not held we risk exclusion (safety) failure.
-      if (UseBiasedLocking) {
+      if (UseBiasedLocking && !UseOptoBiasInlining) {
         masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, false, DONE_LABEL, NULL, _counters);
       }
 
@@ -3528,7 +3534,7 @@
 
       // Critically, the biased locking test must have precedence over
       // and appear before the (box->dhw == 0) recursive stack-lock test.
-      if (UseBiasedLocking) {
+      if (UseBiasedLocking && !UseOptoBiasInlining) {
          masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL);
       }
       
@@ -5272,6 +5278,15 @@
   interface(REG_INTER);
 %}
 
+operand eFlagsRegUCF() %{
+  constraint(ALLOC_IN_RC(int_flags));
+  match(RegFlags);
+  predicate(false);
+
+  format %{ "EFLAGS_U_CF" %}
+  interface(REG_INTER);
+%}
+
 // Condition Code Register used by long compare
 operand flagsReg_long_LTGE() %{
   constraint(ALLOC_IN_RC(int_flags));
@@ -5749,12 +5764,12 @@
 
   format %{ "" %}
   interface(COND_INTER) %{
-    equal(0x4);
-    not_equal(0x5);
-    less(0xC);
-    greater_equal(0xD);
-    less_equal(0xE);
-    greater(0xF);
+    equal(0x4, "e");
+    not_equal(0x5, "ne");
+    less(0xC, "l");
+    greater_equal(0xD, "ge");
+    less_equal(0xE, "le");
+    greater(0xF, "g");
   %}
 %}
 
@@ -5766,12 +5781,47 @@
 
   format %{ "" %}
   interface(COND_INTER) %{
-    equal(0x4);
-    not_equal(0x5);
-    less(0x2);
-    greater_equal(0x3);
-    less_equal(0x6);
-    greater(0x7);
+    equal(0x4, "e");
+    not_equal(0x5, "ne");
+    less(0x2, "b");
+    greater_equal(0x3, "nb");
+    less_equal(0x6, "be");
+    greater(0x7, "nbe");
+  %}
+%}
+
+// Floating comparisons that don't require any fixup for the unordered case
+operand cmpOpUCF() %{
+  match(Bool);
+  predicate(n->as_Bool()->_test._test == BoolTest::lt ||
+            n->as_Bool()->_test._test == BoolTest::ge ||
+            n->as_Bool()->_test._test == BoolTest::le ||
+            n->as_Bool()->_test._test == BoolTest::gt);
+  format %{ "" %}
+  interface(COND_INTER) %{
+    equal(0x4, "e");
+    not_equal(0x5, "ne");
+    less(0x2, "b");
+    greater_equal(0x3, "nb");
+    less_equal(0x6, "be");
+    greater(0x7, "nbe");
+  %}
+%}
+
+
+// Floating comparisons that can be fixed up with extra conditional jumps
+operand cmpOpUCF2() %{
+  match(Bool);
+  predicate(n->as_Bool()->_test._test == BoolTest::ne ||
+            n->as_Bool()->_test._test == BoolTest::eq);
+  format %{ "" %}
+  interface(COND_INTER) %{
+    equal(0x4, "e");
+    not_equal(0x5, "ne");
+    less(0x2, "b");
+    greater_equal(0x3, "nb");
+    less_equal(0x6, "be");
+    greater(0x7, "nbe");
   %}
 %}
 
@@ -5796,12 +5846,12 @@
 
   format %{ "" %}
   interface(COND_INTER) %{
-    equal(0x4);
-    not_equal(0x5);
-    less(0xF);
-    greater_equal(0xE);
-    less_equal(0xD);
-    greater(0xC);
+    equal(0x4, "e");
+    not_equal(0x5, "ne");
+    less(0xF, "g");
+    greater_equal(0xE, "le");
+    less_equal(0xD, "ge");
+    greater(0xC, "l");
   %}
 %}
 
@@ -7357,7 +7407,7 @@
   ins_pipe( pipe_cmov_reg );
 %}
 
-instruct cmovI_regU( eRegI dst, eRegI src, eFlagsRegU cr, cmpOpU cop ) %{
+instruct cmovI_regU( cmpOpU cop, eFlagsRegU cr, eRegI dst, eRegI src ) %{
   predicate(VM_Version::supports_cmov() );
   match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
   ins_cost(200);
@@ -7367,6 +7417,15 @@
   ins_pipe( pipe_cmov_reg );
 %}
 
+instruct cmovI_regUCF( cmpOpUCF cop, eFlagsRegUCF cr, eRegI dst, eRegI src ) %{
+  predicate(VM_Version::supports_cmov() );
+  match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
+  ins_cost(200);
+  expand %{
+    cmovI_regU(cop, cr, dst, src);
+  %}
+%}
+
 // Conditional move
 instruct cmovI_mem(cmpOp cop, eFlagsReg cr, eRegI dst, memory src) %{
   predicate(VM_Version::supports_cmov() );
@@ -7379,7 +7438,7 @@
 %}
 
 // Conditional move
-instruct cmovI_memu(cmpOpU cop, eFlagsRegU cr, eRegI dst, memory src) %{
+instruct cmovI_memU(cmpOpU cop, eFlagsRegU cr, eRegI dst, memory src) %{
   predicate(VM_Version::supports_cmov() );
   match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
   ins_cost(250);
@@ -7389,6 +7448,15 @@
   ins_pipe( pipe_cmov_mem );
 %}
 
+instruct cmovI_memUCF(cmpOpUCF cop, eFlagsRegUCF cr, eRegI dst, memory src) %{
+  predicate(VM_Version::supports_cmov() );
+  match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
+  ins_cost(250);
+  expand %{
+    cmovI_memU(cop, cr, dst, src);
+  %}
+%}
+
 // Conditional move
 instruct cmovP_reg(eRegP dst, eRegP src, eFlagsReg cr, cmpOp cop ) %{
   predicate(VM_Version::supports_cmov() );
@@ -7416,7 +7484,7 @@
 %}
 
 // Conditional move
-instruct cmovP_regU(eRegP dst, eRegP src, eFlagsRegU cr, cmpOpU cop ) %{
+instruct cmovP_regU(cmpOpU cop, eFlagsRegU cr, eRegP dst, eRegP src ) %{
   predicate(VM_Version::supports_cmov() );
   match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
   ins_cost(200);
@@ -7426,6 +7494,15 @@
   ins_pipe( pipe_cmov_reg );
 %}
 
+instruct cmovP_regUCF(cmpOpUCF cop, eFlagsRegUCF cr, eRegP dst, eRegP src ) %{
+  predicate(VM_Version::supports_cmov() );
+  match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
+  ins_cost(200);
+  expand %{
+    cmovP_regU(cop, cr, dst, src);
+  %}
+%}
+
 // DISABLED: Requires the ADLC to emit a bottom_type call that
 // correctly meets the two pointer arguments; one is an incoming
 // register but the other is a memory operand.  ALSO appears to
@@ -7555,6 +7632,15 @@
   ins_pipe( pipe_slow );
 %}
 
+instruct fcmovX_regUCF(cmpOpUCF cop, eFlagsRegUCF cr, regX dst, regX src) %{
+  predicate (UseSSE>=1);
+  match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
+  ins_cost(200);
+  expand %{
+    fcmovX_regU(cop, cr, dst, src);
+  %}
+%}
+
 // unsigned version
 instruct fcmovXD_regU(cmpOpU cop, eFlagsRegU cr, regXD dst, regXD src) %{
   predicate (UseSSE>=2);
@@ -7573,6 +7659,15 @@
   ins_pipe( pipe_slow );
 %}
 
+instruct fcmovXD_regUCF(cmpOpUCF cop, eFlagsRegUCF cr, regXD dst, regXD src) %{
+  predicate (UseSSE>=2);
+  match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
+  ins_cost(200);
+  expand %{
+    fcmovXD_regU(cop, cr, dst, src);
+  %}
+%}
+
 instruct cmovL_reg(cmpOp cop, eFlagsReg cr, eRegL dst, eRegL src) %{
   predicate(VM_Version::supports_cmov() );
   match(Set dst (CMoveL (Binary cop cr) (Binary dst src)));
@@ -7595,6 +7690,15 @@
   ins_pipe( pipe_cmov_reg_long );
 %}
 
+instruct cmovL_regUCF(cmpOpUCF cop, eFlagsRegUCF cr, eRegL dst, eRegL src) %{
+  predicate(VM_Version::supports_cmov() );
+  match(Set dst (CMoveL (Binary cop cr) (Binary dst src)));
+  ins_cost(200);
+  expand %{
+    cmovL_regU(cop, cr, dst, src);
+  %}
+%}
+
 //----------Arithmetic Instructions--------------------------------------------
 //----------Addition Instructions----------------------------------------------
 // Integer Addition Instructions
@@ -7826,33 +7930,36 @@
   ins_pipe( pipe_cmpxchg );
 %}
 
-// Conditional-store of a long value
-// Returns a boolean value (0/1) on success.  Implemented with a CMPXCHG8 on Intel.
-// mem_ptr can actually be in either ESI or EDI
-instruct storeLConditional( eRegI res, eSIRegP mem_ptr, eADXRegL oldval, eBCXRegL newval, eFlagsReg cr ) %{
-  match(Set res (StoreLConditional mem_ptr (Binary oldval newval)));
-  effect(KILL cr);
-  // EDX:EAX is killed if there is contention, but then it's also unused.
-  // In the common case of no contention, EDX:EAX holds the new oop address.
-  format %{ "CMPXCHG8 [$mem_ptr],$newval\t# If EDX:EAX==[$mem_ptr] Then store $newval into [$mem_ptr]\n\t"
-            "MOV    $res,0\n\t"
-            "JNE,s  fail\n\t"
-            "MOV    $res,1\n"
-          "fail:" %}
-  ins_encode( enc_cmpxchg8(mem_ptr),
-              enc_flags_ne_to_boolean(res) );
+// Conditional-store of an int value.
+// ZF flag is set on success, reset otherwise.  Implemented with a CMPXCHG on Intel.
+instruct storeIConditional( memory mem, eAXRegI oldval, eRegI newval, eFlagsReg cr ) %{
+  match(Set cr (StoreIConditional mem (Binary oldval newval)));
+  effect(KILL oldval);
+  format %{ "CMPXCHG $mem,$newval\t# If EAX==$mem Then store $newval into $mem" %}
+  ins_encode( lock_prefix, Opcode(0x0F), Opcode(0xB1), RegMem(newval, mem) );
   ins_pipe( pipe_cmpxchg );
 %}
 
-// Conditional-store of a long value
-// ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG8 on Intel.
-// mem_ptr can actually be in either ESI or EDI
-instruct storeLConditional_flags( eSIRegP mem_ptr, eADXRegL oldval, eBCXRegL newval, eFlagsReg cr, immI0 zero ) %{
-  match(Set cr (CmpI (StoreLConditional mem_ptr (Binary oldval newval)) zero));
-  // EDX:EAX is killed if there is contention, but then it's also unused.
-  // In the common case of no contention, EDX:EAX holds the new oop address.
-  format %{ "CMPXCHG8 [$mem_ptr],$newval\t# If EAX==[$mem_ptr] Then store $newval into [$mem_ptr]\n\t" %}
-  ins_encode( enc_cmpxchg8(mem_ptr) );
+// Conditional-store of a long value.
+// ZF flag is set on success, reset otherwise.  Implemented with a CMPXCHG8 on Intel.
+instruct storeLConditional( memory mem, eADXRegL oldval, eBCXRegL newval, eFlagsReg cr ) %{
+  match(Set cr (StoreLConditional mem (Binary oldval newval)));
+  effect(KILL oldval);
+  format %{ "XCHG   EBX,ECX\t# correct order for CMPXCHG8 instruction\n\t"
+            "CMPXCHG8 $mem,ECX:EBX\t# If EDX:EAX==$mem Then store ECX:EBX into $mem\n\t"
+            "XCHG   EBX,ECX"
+  %}
+  ins_encode %{
+    // Note: we need to swap rbx, and rcx before and after the
+    //       cmpxchg8 instruction because the instruction uses
+    //       rcx as the high order word of the new value to store but
+    //       our register encoding uses rbx.
+    __ xchgl(as_Register(EBX_enc), as_Register(ECX_enc));
+    if( os::is_MP() )
+      __ lock();
+    __ cmpxchg8(Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp));
+    __ xchgl(as_Register(EBX_enc), as_Register(ECX_enc));
+  %}
   ins_pipe( pipe_cmpxchg );
 %}
 
@@ -8319,6 +8426,7 @@
   ins_pipe( ialu_reg );
 %}
 
+
 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24.
 // This idiom is used by the compiler for the i2b bytecode.
 instruct i2b(eRegI dst, xRegI src, immI_24 twentyfour, eFlagsReg cr) %{
@@ -8436,6 +8544,18 @@
   ins_pipe( ialu_reg_reg );
 %}
 
+instruct orI_eReg_castP2X(eRegI dst, eRegP src, eFlagsReg cr) %{
+  match(Set dst (OrI dst (CastP2X src)));
+  effect(KILL cr);
+
+  size(2);
+  format %{ "OR     $dst,$src" %}
+  opcode(0x0B);
+  ins_encode( OpcP, RegReg( dst, src) );
+  ins_pipe( ialu_reg_reg );
+%}
+
+
 // Or Register with Immediate
 instruct orI_eReg_imm(eRegI dst, immI src, eFlagsReg cr) %{
   match(Set dst (OrI dst src));
@@ -9200,6 +9320,18 @@
   ins_pipe( pipe_slow );
 %}
 
+instruct cmpD_cc_P6CF(eFlagsRegUCF cr, regD src1, regD src2) %{
+  predicate(VM_Version::supports_cmov() && UseSSE <=1);
+  match(Set cr (CmpD src1 src2));
+  ins_cost(150);
+  format %{ "FLD    $src1\n\t"
+            "FUCOMIP ST,$src2  // P6 instruction" %}
+  opcode(0xDF, 0x05); /* DF E8+i or DF /5 */
+  ins_encode( Push_Reg_D(src1),
+              OpcP, RegOpc(src2));
+  ins_pipe( pipe_slow );
+%}
+
 // Compare & branch
 instruct cmpD_cc(eFlagsRegU cr, regD src1, regD src2, eAXRegI rax) %{
   predicate(UseSSE<=1);
@@ -9264,6 +9396,16 @@
   ins_pipe( pipe_slow );
 %}
 
+instruct cmpXD_ccCF(eFlagsRegUCF cr, regXD dst, regXD src) %{
+  predicate(UseSSE>=2);
+  match(Set cr (CmpD dst src));
+  ins_cost(100);
+  format %{ "COMISD $dst,$src" %}
+  opcode(0x66, 0x0F, 0x2F);
+  ins_encode(OpcP, OpcS, Opcode(tertiary), RegReg(dst, src));
+  ins_pipe( pipe_slow );
+%}
+
 // float compare and set condition codes in EFLAGS by XMM regs
 instruct cmpXD_ccmem(eFlagsRegU cr, regXD dst, memory src, eAXRegI rax) %{
   predicate(UseSSE>=2);
@@ -9280,6 +9422,16 @@
   ins_pipe( pipe_slow );
 %}
 
+instruct cmpXD_ccmemCF(eFlagsRegUCF cr, regXD dst, memory src) %{
+  predicate(UseSSE>=2);
+  match(Set cr (CmpD dst (LoadD src)));
+  ins_cost(100);
+  format %{ "COMISD $dst,$src" %}
+  opcode(0x66, 0x0F, 0x2F);
+  ins_encode(OpcP, OpcS, Opcode(tertiary), RegMem(dst, src));
+  ins_pipe( pipe_slow );
+%}
+
 // Compare into -1,0,1 in XMM
 instruct cmpXD_reg(eRegI dst, regXD src1, regXD src2, eFlagsReg cr) %{
   predicate(UseSSE>=2);
@@ -10167,6 +10319,18 @@
   ins_pipe( pipe_slow );
 %}
 
+instruct cmpF_cc_P6CF(eFlagsRegUCF cr, regF src1, regF src2) %{
+  predicate(VM_Version::supports_cmov() && UseSSE == 0);
+  match(Set cr (CmpF src1 src2));
+  ins_cost(100);
+  format %{ "FLD    $src1\n\t"
+            "FUCOMIP ST,$src2  // P6 instruction" %}
+  opcode(0xDF, 0x05); /* DF E8+i or DF /5 */
+  ins_encode( Push_Reg_D(src1),
+              OpcP, RegOpc(src2));
+  ins_pipe( pipe_slow );
+%}
+
 
 // Compare & branch
 instruct cmpF_cc(eFlagsRegU cr, regF src1, regF src2, eAXRegI rax) %{
@@ -10232,6 +10396,16 @@
   ins_pipe( pipe_slow );
 %}
 
+instruct cmpX_ccCF(eFlagsRegUCF cr, regX dst, regX src) %{
+  predicate(UseSSE>=1);
+  match(Set cr (CmpF dst src));
+  ins_cost(100);
+  format %{ "COMISS $dst,$src" %}
+  opcode(0x0F, 0x2F);
+  ins_encode(OpcP, OpcS, RegReg(dst, src));
+  ins_pipe( pipe_slow );
+%}
+
 // float compare and set condition codes in EFLAGS by XMM regs
 instruct cmpX_ccmem(eFlagsRegU cr, regX dst, memory src, eAXRegI rax) %{
   predicate(UseSSE>=1);
@@ -10248,6 +10422,16 @@
   ins_pipe( pipe_slow );
 %}
 
+instruct cmpX_ccmemCF(eFlagsRegUCF cr, regX dst, memory src) %{
+  predicate(UseSSE>=1);
+  match(Set cr (CmpF dst (LoadF src)));
+  ins_cost(100);
+  format %{ "COMISS $dst,$src" %}
+  opcode(0x0F, 0x2F);
+  ins_encode(OpcP, OpcS, RegMem(dst, src));
+  ins_pipe( pipe_slow );
+%}
+
 // Compare into -1,0,1 in XMM
 instruct cmpX_reg(eRegI dst, regX src1, regX src2, eFlagsReg cr) %{
   predicate(UseSSE>=1);
@@ -12099,6 +12283,19 @@
   ins_pc_relative(1);
 %}
 
+instruct jmpLoopEndUCF(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{
+  match(CountedLoopEnd cop cmp);
+  effect(USE labl);
+
+  ins_cost(200);
+  format %{ "J$cop,u  $labl\t# Loop end" %}
+  size(6);
+  opcode(0x0F, 0x80);
+  ins_encode( Jcc( cop, labl) );
+  ins_pipe( pipe_jcc );
+  ins_pc_relative(1);
+%}
+
 // Jump Direct Conditional - using unsigned comparison
 instruct jmpConU(cmpOpU cop, eFlagsRegU cmp, label labl) %{
   match(If cop cmp);
@@ -12108,8 +12305,63 @@
   format %{ "J$cop,u  $labl" %}
   size(6);
   opcode(0x0F, 0x80);
-  ins_encode( Jcc( cop, labl) );
-  ins_pipe( pipe_jcc );
+  ins_encode(Jcc(cop, labl));
+  ins_pipe(pipe_jcc);
+  ins_pc_relative(1);
+%}
+
+instruct jmpConUCF(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{
+  match(If cop cmp);
+  effect(USE labl);
+
+  ins_cost(200);
+  format %{ "J$cop,u  $labl" %}
+  size(6);
+  opcode(0x0F, 0x80);
+  ins_encode(Jcc(cop, labl));
+  ins_pipe(pipe_jcc);
+  ins_pc_relative(1);
+%}
+
+instruct jmpConUCF2(cmpOpUCF2 cop, eFlagsRegUCF cmp, label labl) %{
+  match(If cop cmp);
+  effect(USE labl);
+
+  ins_cost(200);
+  format %{ $$template
+    if ($cop$$cmpcode == Assembler::notEqual) {
+      $$emit$$"JP,u   $labl\n\t"
+      $$emit$$"J$cop,u   $labl"
+    } else {
+      $$emit$$"JP,u   done\n\t"
+      $$emit$$"J$cop,u   $labl\n\t"
+      $$emit$$"done:"
+    }
+  %}
+  size(12);
+  opcode(0x0F, 0x80);
+  ins_encode %{
+    Label* l = $labl$$label;
+    $$$emit8$primary;
+    emit_cc(cbuf, $secondary, Assembler::parity);
+    int parity_disp = -1;
+    bool ok = false;
+    if ($cop$$cmpcode == Assembler::notEqual) {
+       // the two jumps 6 bytes apart so the jump distances are too
+       parity_disp = l ? (l->loc_pos() - (cbuf.code_size() + 4)) : 0;
+    } else if ($cop$$cmpcode == Assembler::equal) {
+       parity_disp = 6;
+       ok = true;
+    } else {
+       ShouldNotReachHere();
+    }
+    emit_d32(cbuf, parity_disp);
+    $$$emit8$primary;
+    emit_cc(cbuf, $secondary, $cop$$cmpcode);
+    int disp = l ? (l->loc_pos() - (cbuf.code_size() + 4)) : 0;
+    emit_d32(cbuf, disp);
+  %}
+  ins_pipe(pipe_jcc);
   ins_pc_relative(1);
 %}
 
@@ -12208,7 +12460,7 @@
   effect(USE labl);
 
   ins_cost(300);
-  format %{ "J$cop,s  $labl" %}
+  format %{ "J$cop,s  $labl\t# Loop end" %}
   size(2);
   opcode(0x70);
   ins_encode( JccShort( cop, labl) );
@@ -12223,6 +12475,35 @@
   effect(USE labl);
 
   ins_cost(300);
+  format %{ "J$cop,us $labl\t# Loop end" %}
+  size(2);
+  opcode(0x70);
+  ins_encode( JccShort( cop, labl) );
+  ins_pipe( pipe_jcc );
+  ins_pc_relative(1);
+  ins_short_branch(1);
+%}
+
+instruct jmpLoopEndUCF_short(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{
+  match(CountedLoopEnd cop cmp);
+  effect(USE labl);
+
+  ins_cost(300);
+  format %{ "J$cop,us $labl\t# Loop end" %}
+  size(2);
+  opcode(0x70);
+  ins_encode( JccShort( cop, labl) );
+  ins_pipe( pipe_jcc );
+  ins_pc_relative(1);
+  ins_short_branch(1);
+%}
+
+// Jump Direct Conditional - using unsigned comparison
+instruct jmpConU_short(cmpOpU cop, eFlagsRegU cmp, label labl) %{
+  match(If cop cmp);
+  effect(USE labl);
+
+  ins_cost(300);
   format %{ "J$cop,us $labl" %}
   size(2);
   opcode(0x70);
@@ -12232,8 +12513,7 @@
   ins_short_branch(1);
 %}
 
-// Jump Direct Conditional - using unsigned comparison
-instruct jmpConU_short(cmpOpU cop, eFlagsRegU cmp, label labl) %{
+instruct jmpConUCF_short(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{
   match(If cop cmp);
   effect(USE labl);
 
@@ -12247,6 +12527,46 @@
   ins_short_branch(1);
 %}
 
+instruct jmpConUCF2_short(cmpOpUCF2 cop, eFlagsRegUCF cmp, label labl) %{
+  match(If cop cmp);
+  effect(USE labl);
+
+  ins_cost(300);
+  format %{ $$template
+    if ($cop$$cmpcode == Assembler::notEqual) {
+      $$emit$$"JP,u,s   $labl\n\t"
+      $$emit$$"J$cop,u,s   $labl"
+    } else {
+      $$emit$$"JP,u,s   done\n\t"
+      $$emit$$"J$cop,u,s  $labl\n\t"
+      $$emit$$"done:"
+    }
+  %}
+  size(4);
+  opcode(0x70);
+  ins_encode %{
+    Label* l = $labl$$label;
+    emit_cc(cbuf, $primary, Assembler::parity);
+    int parity_disp = -1;
+    if ($cop$$cmpcode == Assembler::notEqual) {
+      parity_disp = l ? (l->loc_pos() - (cbuf.code_size() + 1)) : 0;
+    } else if ($cop$$cmpcode == Assembler::equal) {
+      parity_disp = 2;
+    } else {
+      ShouldNotReachHere();
+    }
+    emit_d8(cbuf, parity_disp);
+    emit_cc(cbuf, $primary, $cop$$cmpcode);
+    int disp = l ? (l->loc_pos() - (cbuf.code_size() + 1)) : 0;
+    emit_d8(cbuf, disp);
+    assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp");
+    assert(-128 <= parity_disp && parity_disp <= 127, "Displacement too large for short jmp");
+  %}
+  ins_pipe(pipe_jcc);
+  ins_pc_relative(1);
+  ins_short_branch(1);
+%}
+
 // ============================================================================
 // Long Compare
 //
--- a/src/cpu/x86/vm/x86_64.ad	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/cpu/x86/vm/x86_64.ad	Thu Dec 04 17:48:02 2008 -0800
@@ -2004,9 +2004,12 @@
 //
 // NOTE: If the platform does not provide any short branch variants, then
 //       this method should return false for offset 0.
-bool Matcher::is_short_branch_offset(int offset)
-{
-  return -0x80 <= offset && offset < 0x80;
+bool Matcher::is_short_branch_offset(int rule, int offset) {
+  // the short version of jmpConUCF2 contains multiple branches,
+  // making the reach slightly less
+  if (rule == jmpConUCF2_rule)
+    return (-126 <= offset && offset <= 125);
+  return (-128 <= offset && offset <= 127);
 }
 
 const bool Matcher::isSimpleConstant64(jlong value) {
@@ -3569,7 +3572,7 @@
         // at [FETCH], below, will never observe a biased encoding (*101b).
         // If this invariant is not held we'll suffer exclusion (safety) failure.
 
-        if (UseBiasedLocking) {
+        if (UseBiasedLocking && !UseOptoBiasInlining) {
           masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, true, DONE_LABEL, NULL, _counters);
           masm.movptr(tmpReg, Address(objReg, 0)) ;        // [FETCH]
         }
@@ -3657,7 +3660,7 @@
     } else {
        Label DONE_LABEL, Stacked, CheckSucc ;
 
-       if (UseBiasedLocking) {
+       if (UseBiasedLocking && !UseOptoBiasInlining) {
          masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL);
        }
         
@@ -5134,6 +5137,15 @@
   interface(REG_INTER);
 %}
 
+operand rFlagsRegUCF() %{
+  constraint(ALLOC_IN_RC(int_flags));
+  match(RegFlags);
+  predicate(false);
+
+  format %{ "RFLAGS_U_CF" %}
+  interface(REG_INTER);
+%}
+
 // Float register operands
 operand regF()
 %{
@@ -5405,12 +5417,12 @@
 
   format %{ "" %}
   interface(COND_INTER) %{
-    equal(0x4);
-    not_equal(0x5);
-    less(0xC);
-    greater_equal(0xD);
-    less_equal(0xE);
-    greater(0xF);
+    equal(0x4, "e");
+    not_equal(0x5, "ne");
+    less(0xC, "l");
+    greater_equal(0xD, "ge");
+    less_equal(0xE, "le");
+    greater(0xF, "g");
   %}
 %}
 
@@ -5423,12 +5435,48 @@
 
   format %{ "" %}
   interface(COND_INTER) %{
-    equal(0x4);
-    not_equal(0x5);
-    less(0x2);
-    greater_equal(0x3);
-    less_equal(0x6);
-    greater(0x7);
+    equal(0x4, "e");
+    not_equal(0x5, "ne");
+    less(0x2, "b");
+    greater_equal(0x3, "nb");
+    less_equal(0x6, "be");
+    greater(0x7, "nbe");
+  %}
+%}
+
+
+// Floating comparisons that don't require any fixup for the unordered case
+operand cmpOpUCF() %{
+  match(Bool);
+  predicate(n->as_Bool()->_test._test == BoolTest::lt ||
+            n->as_Bool()->_test._test == BoolTest::ge ||
+            n->as_Bool()->_test._test == BoolTest::le ||
+            n->as_Bool()->_test._test == BoolTest::gt);
+  format %{ "" %}
+  interface(COND_INTER) %{
+    equal(0x4, "e");
+    not_equal(0x5, "ne");
+    less(0x2, "b");
+    greater_equal(0x3, "nb");
+    less_equal(0x6, "be");
+    greater(0x7, "nbe");
+  %}
+%}
+
+
+// Floating comparisons that can be fixed up with extra conditional jumps
+operand cmpOpUCF2() %{
+  match(Bool);
+  predicate(n->as_Bool()->_test._test == BoolTest::ne ||
+            n->as_Bool()->_test._test == BoolTest::eq);
+  format %{ "" %}
+  interface(COND_INTER) %{
+    equal(0x4, "e");
+    not_equal(0x5, "ne");
+    less(0x2, "b");
+    greater_equal(0x3, "nb");
+    less_equal(0x6, "be");
+    greater(0x7, "nbe");
   %}
 %}
 
@@ -7176,8 +7224,7 @@
   ins_pipe(pipe_cmov_reg);
 %}
 
-instruct cmovI_regU(rRegI dst, rRegI src, rFlagsRegU cr, cmpOpU cop)
-%{
+instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{
   match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
 
   ins_cost(200); // XXX
@@ -7187,9 +7234,16 @@
   ins_pipe(pipe_cmov_reg);
 %}
 
+instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{
+  match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
+  ins_cost(200);
+  expand %{
+    cmovI_regU(cop, cr, dst, src);
+  %}
+%}
+
 // Conditional move
-instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src)
-%{
+instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{
   match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
 
   ins_cost(250); // XXX
@@ -7211,6 +7265,14 @@
   ins_pipe(pipe_cmov_mem);
 %}
 
+instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{
+  match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
+  ins_cost(250);
+  expand %{
+    cmovI_memU(cop, cr, dst, src);
+  %}
+%}
+
 // Conditional move
 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop)
 %{
@@ -7224,7 +7286,7 @@
 %}
 
 // Conditional move
-instruct cmovN_regU(rRegN dst, rRegN src, rFlagsRegU cr, cmpOpU cop)
+instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src)
 %{
   match(Set dst (CMoveN (Binary cop cr) (Binary dst src)));
 
@@ -7235,6 +7297,14 @@
   ins_pipe(pipe_cmov_reg);
 %}
 
+instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{
+  match(Set dst (CMoveN (Binary cop cr) (Binary dst src)));
+  ins_cost(200);
+  expand %{
+    cmovN_regU(cop, cr, dst, src);
+  %}
+%}
+
 // Conditional move
 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop)
 %{
@@ -7248,7 +7318,7 @@
 %}
 
 // Conditional move
-instruct cmovP_regU(rRegP dst, rRegP src, rFlagsRegU cr, cmpOpU cop)
+instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src)
 %{
   match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
 
@@ -7259,6 +7329,14 @@
   ins_pipe(pipe_cmov_reg); // XXX
 %}
 
+instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{
+  match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
+  ins_cost(200);
+  expand %{
+    cmovP_regU(cop, cr, dst, src);
+  %}
+%}
+
 // DISABLED: Requires the ADLC to emit a bottom_type call that
 // correctly meets the two pointer arguments; one is an incoming
 // register but the other is a memory operand.  ALSO appears to
@@ -7319,6 +7397,14 @@
   ins_pipe(pipe_cmov_reg); // XXX
 %}
 
+instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{
+  match(Set dst (CMoveL (Binary cop cr) (Binary dst src)));
+  ins_cost(200);
+  expand %{
+    cmovL_regU(cop, cr, dst, src);
+  %}
+%}
+
 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src)
 %{
   match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src))));
@@ -7330,6 +7416,14 @@
   ins_pipe(pipe_cmov_mem); // XXX
 %}
 
+instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{
+  match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src))));
+  ins_cost(200);
+  expand %{
+    cmovL_memU(cop, cr, dst, src);
+  %}
+%}
+
 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src)
 %{
   match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
@@ -7366,6 +7460,14 @@
   ins_pipe(pipe_slow);
 %}
 
+instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{
+  match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
+  ins_cost(200);
+  expand %{
+    cmovF_regU(cop, cr, dst, src);
+  %}
+%}
+
 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src)
 %{
   match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
@@ -7390,6 +7492,14 @@
   ins_pipe(pipe_slow);
 %}
 
+instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{
+  match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
+  ins_cost(200);
+  expand %{
+    cmovD_regU(cop, cr, dst, src);
+  %}
+%}
+
 //----------Arithmetic Instructions--------------------------------------------
 //----------Addition Instructions----------------------------------------------
 
@@ -7735,7 +7845,7 @@
                            rFlagsReg cr)
 %{
   match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval)));
-
+ 
   format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) "
             "If rax == $heap_top_ptr then store $newval into $heap_top_ptr" %}
   opcode(0x0F, 0xB1);
@@ -7746,53 +7856,40 @@
   ins_pipe(pipe_cmpxchg);
 %}
 
-// Conditional-store of a long value
-// Returns a boolean value (0/1) on success.  Implemented with a
-// CMPXCHG8 on Intel.  mem_ptr can actually be in either RSI or RDI
-
-instruct storeLConditional(rRegI res,
-                           memory mem_ptr,
-                           rax_RegL oldval, rRegL newval,
-                           rFlagsReg cr)
-%{
-  match(Set res (StoreLConditional mem_ptr (Binary oldval newval)));
-  effect(KILL cr);
-
-  format %{ "cmpxchgq $mem_ptr, $newval\t# (long) "
-            "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"
-            "sete    $res\n\t"
-            "movzbl  $res, $res" %}
+// Conditional-store of an int value.
+// ZF flag is set on success, reset otherwise.  Implemented with a CMPXCHG.
+instruct storeIConditional(memory mem, rax_RegI oldval, rRegI newval, rFlagsReg cr)
+%{
+  match(Set cr (StoreIConditional mem (Binary oldval newval)));
+  effect(KILL oldval);
+
+  format %{ "cmpxchgl $mem, $newval\t# If rax == $mem then store $newval into $mem" %}
   opcode(0x0F, 0xB1);
   ins_encode(lock_prefix,
-             REX_reg_mem_wide(newval, mem_ptr),
+             REX_reg_mem(newval, mem),
              OpcP, OpcS,
-             reg_mem(newval, mem_ptr),
-             REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete
-             REX_reg_breg(res, res), // movzbl
-             Opcode(0xF), Opcode(0xB6), reg_reg(res, res));
+             reg_mem(newval, mem));
   ins_pipe(pipe_cmpxchg);
 %}
 
-// Conditional-store of a long value
-// ZF flag is set on success, reset otherwise. Implemented with a
-// CMPXCHG8 on Intel.  mem_ptr can actually be in either RSI or RDI
-instruct storeLConditional_flags(memory mem_ptr,
-                                 rax_RegL oldval, rRegL newval,
-                                 rFlagsReg cr,
-                                 immI0 zero)
-%{
-  match(Set cr (CmpI (StoreLConditional mem_ptr (Binary oldval newval)) zero));
-
-  format %{ "cmpxchgq $mem_ptr, $newval\t# (long) "
-            "If rax == $mem_ptr then store $newval into $mem_ptr" %}
+// Conditional-store of a long value.
+// ZF flag is set on success, reset otherwise.  Implemented with a CMPXCHG.
+instruct storeLConditional(memory mem, rax_RegL oldval, rRegL newval, rFlagsReg cr)
+%{
+  match(Set cr (StoreLConditional mem (Binary oldval newval)));
+  effect(KILL oldval);
+
+  format %{ "cmpxchgq $mem, $newval\t# If rax == $mem then store $newval into $mem" %}
   opcode(0x0F, 0xB1);
   ins_encode(lock_prefix,
-             REX_reg_mem_wide(newval, mem_ptr),
+             REX_reg_mem_wide(newval, mem),
              OpcP, OpcS,
-             reg_mem(newval, mem_ptr));
+             reg_mem(newval, mem));
   ins_pipe(pipe_cmpxchg);
 %}
 
+
+// XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them
 instruct compareAndSwapP(rRegI res,
                          memory mem_ptr,
                          rax_RegP oldval, rRegP newval,
@@ -7816,7 +7913,6 @@
   ins_pipe( pipe_cmpxchg );
 %}
 
-// XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them
 instruct compareAndSwapL(rRegI res,
                          memory mem_ptr,
                          rax_RegL oldval, rRegL newval,
@@ -8766,6 +8862,7 @@
   ins_pipe(ialu_reg);
 %}
 
+
 // Logical Shift Right by 8-bit immediate
 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
 %{
@@ -9475,6 +9572,18 @@
   ins_pipe(ialu_reg_reg);
 %}
 
+// Use any_RegP to match R15 (TLS register) without spilling.
+instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{
+  match(Set dst (OrL dst (CastP2X src)));
+  effect(KILL cr);
+
+  format %{ "orq     $dst, $src\t# long" %}
+  opcode(0x0B);
+  ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
+  ins_pipe(ialu_reg_reg);
+%}
+
+
 // Or Register with Immediate
 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr)
 %{
@@ -9716,6 +9825,17 @@
   ins_pipe(pipe_slow);
 %}
 
+instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{
+  match(Set cr (CmpF src1 src2));
+
+  ins_cost(145);
+  format %{ "ucomiss $src1, $src2" %}
+  ins_encode %{
+    __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister);
+  %}
+  ins_pipe(pipe_slow);
+%}
+
 instruct cmpF_cc_mem(rFlagsRegU cr, regF src1, memory src2)
 %{
   match(Set cr (CmpF src1 (LoadF src2)));
@@ -9733,6 +9853,16 @@
   ins_pipe(pipe_slow);
 %}
 
+instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{
+  match(Set cr (CmpF src1 (LoadF src2)));
+
+  ins_cost(100);
+  format %{ "ucomiss $src1, $src2" %}
+  opcode(0x0F, 0x2E);
+  ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, reg_mem(src1, src2));
+  ins_pipe(pipe_slow);
+%}
+
 instruct cmpF_cc_imm(rFlagsRegU cr, regF src1, immF src2)
 %{
   match(Set cr (CmpF src1 src2));
@@ -9750,6 +9880,16 @@
   ins_pipe(pipe_slow);
 %}
 
+instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src1, immF src2) %{
+  match(Set cr (CmpF src1 src2));
+
+  ins_cost(100);
+  format %{ "ucomiss $src1, $src2" %}
+  opcode(0x0F, 0x2E);
+  ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, load_immF(src1, src2));
+  ins_pipe(pipe_slow);
+%}
+
 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2)
 %{
   match(Set cr (CmpD src1 src2));
@@ -9767,6 +9907,17 @@
   ins_pipe(pipe_slow);
 %}
 
+instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{
+  match(Set cr (CmpD src1 src2));
+
+  ins_cost(100);
+  format %{ "ucomisd $src1, $src2 test" %}
+  ins_encode %{
+    __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister);
+  %}
+  ins_pipe(pipe_slow);
+%}
+
 instruct cmpD_cc_mem(rFlagsRegU cr, regD src1, memory src2)
 %{
   match(Set cr (CmpD src1 (LoadD src2)));
@@ -9784,6 +9935,16 @@
   ins_pipe(pipe_slow);
 %}
 
+instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{
+  match(Set cr (CmpD src1 (LoadD src2)));
+
+  ins_cost(100);
+  format %{ "ucomisd $src1, $src2" %}
+  opcode(0x66, 0x0F, 0x2E);
+  ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, reg_mem(src1, src2));
+  ins_pipe(pipe_slow);
+%}
+
 instruct cmpD_cc_imm(rFlagsRegU cr, regD src1, immD src2)
 %{
   match(Set cr (CmpD src1 src2));
@@ -9801,6 +9962,16 @@
   ins_pipe(pipe_slow);
 %}
 
+instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src1, immD src2) %{
+  match(Set cr (CmpD src1 src2));
+
+  ins_cost(100);
+  format %{ "ucomisd $src1, [$src2]" %}
+  opcode(0x66, 0x0F, 0x2E);
+  ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, load_immD(src1, src2));
+  ins_pipe(pipe_slow);
+%}
+
 // Compare into -1,0,1
 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr)
 %{
@@ -11406,8 +11577,7 @@
 %}
 
 // Jump Direct Conditional - Label defines a relative address from Jcc+1
-instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl)
-%{
+instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl) %{
   match(CountedLoopEnd cop cmp);
   effect(USE labl);
 
@@ -11420,14 +11590,12 @@
   ins_pc_relative(1);
 %}
 
-// Jump Direct Conditional - using unsigned comparison
-instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl)
-%{
-  match(If cop cmp);
+instruct jmpLoopEndUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
+  match(CountedLoopEnd cop cmp);
   effect(USE labl);
 
-  ins_cost(300);
-  format %{ "j$cop,u   $labl" %}
+  ins_cost(200);
+  format %{ "j$cop,u   $labl\t# loop end" %}
   size(6);
   opcode(0x0F, 0x80);
   ins_encode(Jcc(cop, labl));
@@ -11435,6 +11603,73 @@
   ins_pc_relative(1);
 %}
 
+// Jump Direct Conditional - using unsigned comparison
+instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{
+  match(If cop cmp);
+  effect(USE labl);
+
+  ins_cost(300);
+  format %{ "j$cop,u  $labl" %}
+  size(6);
+  opcode(0x0F, 0x80);
+  ins_encode(Jcc(cop, labl));
+  ins_pipe(pipe_jcc);
+  ins_pc_relative(1);
+%}
+
+instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
+  match(If cop cmp);
+  effect(USE labl);
+
+  ins_cost(200);
+  format %{ "j$cop,u  $labl" %}
+  size(6);
+  opcode(0x0F, 0x80);
+  ins_encode(Jcc(cop, labl));
+  ins_pipe(pipe_jcc);
+  ins_pc_relative(1);
+%}
+
+instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{
+  match(If cop cmp);
+  effect(USE labl);
+
+  ins_cost(200);
+  format %{ $$template
+    if ($cop$$cmpcode == Assembler::notEqual) {
+      $$emit$$"jp,u   $labl\n\t"
+      $$emit$$"j$cop,u   $labl"
+    } else {
+      $$emit$$"jp,u   done\n\t"
+      $$emit$$"j$cop,u   $labl\n\t"
+      $$emit$$"done:"
+    }
+  %}
+  size(12);
+  opcode(0x0F, 0x80);
+  ins_encode %{
+    Label* l = $labl$$label;
+    $$$emit8$primary;
+    emit_cc(cbuf, $secondary, Assembler::parity);
+    int parity_disp = -1;
+    if ($cop$$cmpcode == Assembler::notEqual) {
+       // the two jumps 6 bytes apart so the jump distances are too
+       parity_disp = l ? (l->loc_pos() - (cbuf.code_size() + 4)) : 0;
+    } else if ($cop$$cmpcode == Assembler::equal) {
+       parity_disp = 6;
+    } else {
+       ShouldNotReachHere();
+    }
+    emit_d32(cbuf, parity_disp);
+    $$$emit8$primary;
+    emit_cc(cbuf, $secondary, $cop$$cmpcode);
+    int disp = l ? (l->loc_pos() - (cbuf.code_size() + 4)) : 0;
+    emit_d32(cbuf, disp);
+  %}
+  ins_pipe(pipe_jcc);
+  ins_pc_relative(1);
+%}
+
 // ============================================================================
 // The 2nd slow-half of a subtype check.  Scan the subklass's 2ndary
 // superklass array for an instance of the superklass.  Set a hidden
@@ -11505,8 +11740,7 @@
 // specific code section of the file.
 
 // Jump Direct - Label defines a relative address from JMP+1
-instruct jmpDir_short(label labl)
-%{
+instruct jmpDir_short(label labl) %{
   match(Goto);
   effect(USE labl);
 
@@ -11521,8 +11755,7 @@
 %}
 
 // Jump Direct Conditional - Label defines a relative address from Jcc+1
-instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl)
-%{
+instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{
   match(If cop cr);
   effect(USE labl);
 
@@ -11537,13 +11770,12 @@
 %}
 
 // Jump Direct Conditional - Label defines a relative address from Jcc+1
-instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl)
-%{
+instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{
   match(CountedLoopEnd cop cr);
   effect(USE labl);
 
   ins_cost(300);
-  format %{ "j$cop,s   $labl" %}
+  format %{ "j$cop,s   $labl\t# loop end" %}
   size(2);
   opcode(0x70);
   ins_encode(JccShort(cop, labl));
@@ -11553,12 +11785,40 @@
 %}
 
 // Jump Direct Conditional - Label defines a relative address from Jcc+1
-instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl)
-%{
+instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{
   match(CountedLoopEnd cop cmp);
   effect(USE labl);
 
   ins_cost(300);
+  format %{ "j$cop,us  $labl\t# loop end" %}
+  size(2);
+  opcode(0x70);
+  ins_encode(JccShort(cop, labl));
+  ins_pipe(pipe_jcc);
+  ins_pc_relative(1);
+  ins_short_branch(1);
+%}
+
+instruct jmpLoopEndUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
+  match(CountedLoopEnd cop cmp);
+  effect(USE labl);
+
+  ins_cost(300);
+  format %{ "j$cop,us  $labl\t# loop end" %}
+  size(2);
+  opcode(0x70);
+  ins_encode(JccShort(cop, labl));
+  ins_pipe(pipe_jcc);
+  ins_pc_relative(1);
+  ins_short_branch(1);
+%}
+
+// Jump Direct Conditional - using unsigned comparison
+instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{
+  match(If cop cmp);
+  effect(USE labl);
+
+  ins_cost(300);
   format %{ "j$cop,us  $labl" %}
   size(2);
   opcode(0x70);
@@ -11568,9 +11828,7 @@
   ins_short_branch(1);
 %}
 
-// Jump Direct Conditional - using unsigned comparison
-instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl)
-%{
+instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
   match(If cop cmp);
   effect(USE labl);
 
@@ -11584,6 +11842,46 @@
   ins_short_branch(1);
 %}
 
+instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{
+  match(If cop cmp);
+  effect(USE labl);
+
+  ins_cost(300);
+  format %{ $$template
+    if ($cop$$cmpcode == Assembler::notEqual) {
+      $$emit$$"jp,u,s   $labl\n\t"
+      $$emit$$"j$cop,u,s   $labl"
+    } else {
+      $$emit$$"jp,u,s   done\n\t"
+      $$emit$$"j$cop,u,s  $labl\n\t"
+      $$emit$$"done:"
+    }
+  %}
+  size(4);
+  opcode(0x70);
+  ins_encode %{
+    Label* l = $labl$$label;
+    emit_cc(cbuf, $primary, Assembler::parity);
+    int parity_disp = -1;
+    if ($cop$$cmpcode == Assembler::notEqual) {
+      parity_disp = l ? (l->loc_pos() - (cbuf.code_size() + 1)) : 0;
+    } else if ($cop$$cmpcode == Assembler::equal) {
+      parity_disp = 2;
+    } else {
+      ShouldNotReachHere();
+    }
+    emit_d8(cbuf, parity_disp);
+    emit_cc(cbuf, $primary, $cop$$cmpcode);
+    int disp = l ? (l->loc_pos() - (cbuf.code_size() + 1)) : 0;
+    emit_d8(cbuf, disp);
+    assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp");
+    assert(-128 <= parity_disp && parity_disp <= 127, "Displacement too large for short jmp");
+  %}
+  ins_pipe(pipe_jcc);
+  ins_pc_relative(1);
+  ins_short_branch(1);
+%}
+
 // ============================================================================
 // inlined locking and unlocking
 
--- a/src/os/solaris/vm/os_solaris.cpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/os/solaris/vm/os_solaris.cpp	Thu Dec 04 17:48:02 2008 -0800
@@ -3756,7 +3756,6 @@
     int maxClamped     = MIN2(iaLimits.maxPrio, (int)iaInfo->ia_uprilim);
     iaInfo->ia_upri    = scale_to_lwp_priority(iaLimits.minPrio, maxClamped, newPrio);
     iaInfo->ia_uprilim = IA_NOCHANGE;
-    iaInfo->ia_nice    = IA_NOCHANGE;
     iaInfo->ia_mode    = IA_NOCHANGE;
     if (ThreadPriorityVerbose) {
       tty->print_cr ("IA: [%d...%d] %d->%d\n",
--- a/src/os_cpu/linux_x86/vm/linux_x86_32.ad	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/os_cpu/linux_x86/vm/linux_x86_32.ad	Thu Dec 04 17:48:02 2008 -0800
@@ -103,16 +103,16 @@
 // This name is KNOWN by the ADLC and cannot be changed.
 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type
 // for this guy.
-instruct tlsLoadP(eAXRegP dst, eFlagsReg cr) %{
+instruct tlsLoadP(eRegP dst, eFlagsReg cr) %{
   match(Set dst (ThreadLocal));
   effect(DEF dst, KILL cr);
 
-  format %{ "MOV    EAX, Thread::current()" %}
+  format %{ "MOV    $dst, Thread::current()" %}
   ins_encode( linux_tlsencode(dst) );
   ins_pipe( ialu_reg_fat );
 %}
 
-instruct TLS(eAXRegP dst) %{
+instruct TLS(eRegP dst) %{
   match(Set dst (ThreadLocal));
 
   expand %{
--- a/src/os_cpu/solaris_x86/vm/solaris_x86_32.ad	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/os_cpu/solaris_x86/vm/solaris_x86_32.ad	Thu Dec 04 17:48:02 2008 -0800
@@ -110,16 +110,16 @@
 // This name is KNOWN by the ADLC and cannot be changed.
 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type
 // for this guy.
-instruct tlsLoadP(eAXRegP dst, eFlagsReg cr) %{
+instruct tlsLoadP(eRegP dst, eFlagsReg cr) %{
   match(Set dst (ThreadLocal));
   effect(DEF dst, KILL cr);
 
-  format %{ "MOV    EAX, Thread::current()" %}
+  format %{ "MOV    $dst, Thread::current()" %}
   ins_encode( solaris_tlsencode(dst) );
   ins_pipe( ialu_reg_fat );
 %}
 
-instruct TLS(eAXRegP dst) %{
+instruct TLS(eRegP dst) %{
   match(Set dst (ThreadLocal));
 
   expand %{
--- a/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeViewTopComponent.java	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeViewTopComponent.java	Thu Dec 04 17:48:02 2008 -0800
@@ -28,6 +28,7 @@
 import com.sun.hotspot.igv.data.services.InputGraphProvider;
 import java.awt.BorderLayout;
 import java.io.Serializable;
+import javax.swing.SwingUtilities;
 import org.openide.ErrorManager;
 import org.openide.explorer.ExplorerManager;
 import org.openide.explorer.ExplorerUtils;
@@ -151,14 +152,18 @@
     }
 
     public void resultChanged(LookupEvent lookupEvent) {
-        InputGraphProvider p = Lookup.getDefault().lookup(InputGraphProvider.class);
+        final InputGraphProvider p = Lookup.getDefault().lookup(InputGraphProvider.class);
         if (p != null) {
+            SwingUtilities.invokeLater(new Runnable() {
+                public void run() {
             InputGraph graph = p.getGraph();
             if (graph != null) {
                 Group g = graph.getGroup();
                 rootNode.update(graph, g.getMethod());
             }
         }
+            });
+        }
     }
 
     final static class ResolvableHelper implements Serializable {
--- a/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/ControlFlowScene.java	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/ControlFlowScene.java	Thu Dec 04 17:48:02 2008 -0800
@@ -33,7 +33,7 @@
 import java.awt.Rectangle;
 import java.util.ArrayList;
 import java.util.HashSet;
-import java.util.Hashtable;
+import java.util.HashMap;
 import java.util.Set;
 import javax.swing.BorderFactory;
 import org.netbeans.api.visual.action.ActionFactory;
@@ -44,7 +44,6 @@
 import org.netbeans.api.visual.action.WidgetAction;
 import org.netbeans.api.visual.anchor.AnchorFactory;
 import org.netbeans.api.visual.anchor.AnchorShape;
-import com.sun.hotspot.igv.controlflow.HierarchicalGraphLayout;
 import org.netbeans.api.visual.layout.LayoutFactory;
 import org.netbeans.api.visual.router.RouterFactory;
 import org.netbeans.api.visual.widget.LayerWidget;
@@ -61,8 +60,8 @@
  */
 public class ControlFlowScene extends GraphScene<InputBlock, InputBlockEdge> implements SelectProvider, MoveProvider, RectangularSelectDecorator, RectangularSelectProvider {
 
-    private Set<BlockWidget> selection;
-    private Hashtable<InputBlock, BlockWidget> blockMap;
+    private HashSet<BlockWidget> selection;
+    private HashMap<InputBlock, BlockWidget> blockMap;
     private InputGraph oldGraph;
     private LayerWidget edgeLayer;
     private LayerWidget mainLayer;
--- a/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/ControlFlowTopComponent.java	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/ControlFlowTopComponent.java	Thu Dec 04 17:48:02 2008 -0800
@@ -28,6 +28,7 @@
 import java.awt.BorderLayout;
 import java.io.Serializable;
 import javax.swing.JScrollPane;
+import javax.swing.SwingUtilities;
 import org.openide.ErrorManager;
 import org.openide.util.Lookup;
 import org.openide.util.LookupEvent;
@@ -143,13 +144,17 @@
 
     public void resultChanged(LookupEvent lookupEvent) {
 
-        InputGraphProvider p = Lookup.getDefault().lookup(InputGraphProvider.class);
+        final InputGraphProvider p = Lookup.getDefault().lookup(InputGraphProvider.class);
         if (p != null) {
+            SwingUtilities.invokeLater(new Runnable() {
+                public void run() {
             InputGraph g = p.getGraph();
             if (g != null) {
                 scene.setGraph(g);
             }
         }
+            });
+        }
     }
 
     @Override
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/FolderNode.java	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/FolderNode.java	Thu Dec 04 17:48:02 2008 -0800
@@ -24,6 +24,7 @@
 package com.sun.hotspot.igv.coordinator;
 
 import com.sun.hotspot.igv.coordinator.actions.RemoveCookie;
+import com.sun.hotspot.igv.data.ChangedListener;
 import com.sun.hotspot.igv.data.Group;
 import com.sun.hotspot.igv.data.services.GroupOrganizer;
 import com.sun.hotspot.igv.data.InputGraph;
@@ -50,17 +51,24 @@
     private List<String> subFolders;
     private FolderChildren children;
 
-    private static class FolderChildren extends Children.Keys {
+    private static class FolderChildren extends Children.Keys implements ChangedListener<Group> {
 
         private FolderNode parent;
+        private List<Group> registeredGroups;
 
         public void setParent(FolderNode parent) {
             this.parent = parent;
+            this.registeredGroups = new ArrayList<Group>();
         }
 
         @Override
         protected Node[] createNodes(Object arg0) {
 
+            for(Group g : registeredGroups) {
+                g.getChangedEvent().removeListener(this);
+            }
+            registeredGroups.clear();
+
             Pair<String, List<Group>> p = (Pair<String, List<Group>>) arg0;
             if (p.getLeft().length() == 0) {
 
@@ -69,6 +77,8 @@
                     for (InputGraph graph : g.getGraphs()) {
                         curNodes.add(new GraphNode(graph));
                     }
+                    g.getChangedEvent().addListener(this);
+                    registeredGroups.add(g);
                 }
 
                 Node[] result = new Node[curNodes.size()];
@@ -85,7 +95,13 @@
         @Override
         public void addNotify() {
             this.setKeys(parent.structure);
+        }
 
+        public void changed(Group source) {
+            List<Pair<String, List<Group>>> newStructure = new ArrayList<Pair<String, List<Group>>>();
+            for(Pair<String, List<Group>> p : parent.structure) {
+                refreshKey(p);
+            }
         }
     }
 
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/GraphDocument.java	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/GraphDocument.java	Thu Dec 04 17:48:02 2008 -0800
@@ -31,7 +31,7 @@
  *
  * @author Thomas Wuerthinger
  */
-public class GraphDocument extends Properties.Object implements ChangedEventProvider<GraphDocument> {
+public class GraphDocument extends Properties.Entity implements ChangedEventProvider<GraphDocument> {
 
     private List<Group> groups;
     private ChangedEvent<GraphDocument> changedEvent;
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Group.java	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Group.java	Thu Dec 04 17:48:02 2008 -0800
@@ -37,7 +37,7 @@
  *
  * @author Thomas Wuerthinger
  */
-public class Group extends Properties.Object implements ChangedEventProvider<Group> {
+public class Group extends Properties.Entity implements ChangedEventProvider<Group> {
 
     private List<InputGraph> graphs;
     private transient ChangedEvent<Group> changedEvent;
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputGraph.java	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputGraph.java	Thu Dec 04 17:48:02 2008 -0800
@@ -23,26 +23,25 @@
  */
 package com.sun.hotspot.igv.data;
 
-import com.sun.hotspot.igv.data.Properties;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
-import java.util.Hashtable;
+import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
 
 /**
  *
  * @author Thomas Wuerthinger
  */
-public class InputGraph extends Properties.Object {
+public class InputGraph extends Properties.Entity {
 
-    private Map<Integer, InputNode> nodes;
-    private Set<InputEdge> edges;
+    private HashMap<Integer, InputNode> nodes;
+    private ArrayList<InputEdge> edges;
     private Group parent;
-    private Map<String, InputBlock> blocks;
-    private Map<Integer, InputBlock> nodeToBlock;
+    private HashMap<String, InputBlock> blocks;
+    private HashMap<Integer, InputBlock> nodeToBlock;
     private boolean isDifferenceGraph;
 
     public InputGraph(Group parent) {
@@ -61,10 +60,10 @@
     public InputGraph(Group parent, InputGraph last, String name) {
         this.parent = parent;
         setName(name);
-        nodes = new Hashtable<Integer, InputNode>();
-        edges = new HashSet<InputEdge>();
-        blocks = new Hashtable<String, InputBlock>();
-        nodeToBlock = new Hashtable<Integer, InputBlock>();
+        nodes = new HashMap<Integer, InputNode>();
+        edges = new ArrayList<InputEdge>();
+        blocks = new HashMap<String, InputBlock>();
+        nodeToBlock = new HashMap<Integer, InputBlock>();
         if (last != null) {
 
             for (InputNode n : last.getNodes()) {
@@ -182,8 +181,8 @@
         return nodes.remove(index);
     }
 
-    public Set<InputEdge> getEdges() {
-        return Collections.unmodifiableSet(edges);
+    public Collection<InputEdge> getEdges() {
+        return Collections.unmodifiableList(edges);
     }
 
     public void removeEdge(InputEdge c) {
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputMethod.java	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputMethod.java	Thu Dec 04 17:48:02 2008 -0800
@@ -32,7 +32,7 @@
  *
  * @author Thomas Wuerthinger
  */
-public class InputMethod extends Properties.Object {
+public class InputMethod extends Properties.Entity {
 
     private String name;
     private int bci;
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputNode.java	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputNode.java	Thu Dec 04 17:48:02 2008 -0800
@@ -27,7 +27,7 @@
  *
  * @author Thomas Wuerthinger
  */
-public class InputNode extends Properties.Object {
+public class InputNode extends Properties.Entity {
 
     private int id;
 
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Properties.java	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Properties.java	Thu Dec 04 17:48:02 2008 -0800
@@ -26,24 +26,22 @@
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
-import java.util.Map;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+
 /**
  *
  * @author Thomas Wuerthinger
  */
-public class Properties implements Serializable {
+public class Properties implements Serializable, Iterable<Property> {
 
     public static final long serialVersionUID = 1L;
-    private Map<String, Property> map;
+    private String[] map = new String[4];
 
     public Properties() {
-        map = new HashMap<String, Property>(5);
     }
 
     @Override
@@ -54,10 +52,7 @@
 
         Properties p = (Properties) o;
 
-        if (getProperties().size() != p.getProperties().size()) {
-            return false;
-        }
-        for (Property prop : getProperties()) {
+        for (Property prop : this) {
             String value = p.get(prop.getName());
             if (value == null || !value.equals(prop.getValue())) {
                 return false;
@@ -75,32 +70,33 @@
 
     public Properties(String name, String value) {
         this();
-        this.add(new Property(name, value));
+        this.setProperty(name, value);
     }
 
     public Properties(String name, String value, String name1, String value1) {
         this(name, value);
-        this.add(new Property(name1, value1));
+        this.setProperty(name1, value1);
     }
 
     public Properties(String name, String value, String name1, String value1, String name2, String value2) {
         this(name, value, name1, value1);
-        this.add(new Property(name2, value2));
+        this.setProperty(name2, value2);
     }
 
     public Properties(Properties p) {
-        map = new HashMap<String, Property>(p.map);
+        map = new String[p.map.length];
+        System.arraycopy(map, 0, p.map, 0, p.map.length);
     }
 
-    public static class Object implements Provider {
+    public static class Entity implements Provider {
 
         private Properties properties;
 
-        public Object() {
+        public Entity() {
             properties = new Properties();
         }
 
-        public Object(Properties.Object object) {
+        public Entity(Properties.Entity object) {
             properties = new Properties(object.getProperties());
         }
 
@@ -109,6 +105,14 @@
         }
     }
 
+    private String getProperty(String key) {
+        for (int i = 0; i < map.length; i += 2)
+            if (map[i] != null && map[i].equals(key)) {
+                return map[i + 1];
+            }
+        return null;
+    }
+
     public interface PropertyMatcher {
 
         String getName();
@@ -173,13 +177,15 @@
     }
 
     public Property selectSingle(PropertyMatcher matcher) {
-
-        Property p = this.map.get(matcher.getName());
-        if (p == null) {
-            return null;
+        String value = null;
+        for (int i = 0; i < map.length; i += 2) {
+            if (map[i] != null && matcher.getName().equals(map[i]))  {
+                value = map[i + 1];
+                break;
+            }
         }
-        if (matcher.match(p.getValue())) {
-            return p;
+        if (value != null && matcher.match(value)) {
+            return new Property(matcher.getName(), value);
         } else {
             return null;
         }
@@ -194,8 +200,11 @@
     public String toString() {
         StringBuilder sb = new StringBuilder();
         sb.append("[");
-        for (Property p : map.values()) {
-            sb.append(p.toString());
+        for (int i = 0; i < map.length; i += 2) {
+            if (map[i + 1] != null) {
+                String p = map[i + 1];
+                sb.append(map[i] + " = " + map[i + 1] + "; ");
+            }
         }
         return sb.append("]").toString();
     }
@@ -241,41 +250,51 @@
     }
 
     public String get(String key) {
-        Property p = map.get(key);
-        if (p == null) {
-            return null;
-        } else {
-            return p.getValue();
+        for (int i = 0; i < map.length; i += 2) {
+            if (map[i] != null && map[i].equals(key)) {
+                return map[i + 1];
+            }
         }
+        return null;
     }
 
-    public String getProperty(String string) {
-        return get(string);
+    public void setProperty(String name, String value) {
+        for (int i = 0; i < map.length; i += 2) {
+            if (map[i] != null && map[i].equals(name)) {
+                String p = map[i + 1];
+                if (value == null) {
+                    // remove this property
+                    map[i] = null;
+                    map[i + 1] = null;
+                } else {
+                    map[i + 1] = value;
+                }
+                return;
+            }
+        }
+        if (value == null) {
+            return;
+        }
+        for (int i = 0; i < map.length; i += 2) {
+            if (map[i] == null) {
+                map[i] = name;
+                map[i + 1] = value;
+                return;
+            }
+        }
+        String[] newMap = new String[map.length + 4];
+        System.arraycopy(map, 0, newMap, 0, map.length);
+        newMap[map.length] = name;
+        newMap[map.length + 1] = value;
+        map = newMap;
     }
 
-    public Property setProperty(String name, String value) {
-
-        if (value == null) {
-            // remove this property
-            return map.remove(name);
-        } else {
-            Property p = map.get(name);
-            if (p == null) {
-                p = new Property(name, value);
-                map.put(name, p);
-            } else {
-                p.setValue(value);
-            }
-            return p;
-        }
-    }
-
-    public Collection<Property> getProperties() {
-        return Collections.unmodifiableCollection(map.values());
+    public  Iterator<Property> getProperties() {
+        return iterator();
     }
 
     public void add(Properties properties) {
-        for (Property p : properties.getProperties()) {
+        for (Property p : properties) {
             add(p);
         }
     }
@@ -283,6 +302,35 @@
     public void add(Property property) {
         assert property.getName() != null;
         assert property.getValue() != null;
-        map.put(property.getName(), property);
+        setProperty(property.getName(), property.getValue());
+    }
+    class PropertiesIterator implements Iterator<Property>, Iterable<Property> {
+        public Iterator<Property> iterator() {
+                return this;
+        }
+
+        int index;
+
+        public boolean hasNext() {
+            while (index < map.length && map[index + 1] == null)
+                index += 2;
+            return index < map.length;
+        }
+
+        public Property next() {
+            if (index < map.length) {
+                index += 2;
+                return new Property(map[index - 2], map[index - 1]);
+            }
+            return null;
+        }
+
+        public void remove() {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+
+    }
+    public Iterator<Property> iterator() {
+        return new PropertiesIterator();
     }
 }
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Property.java	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Property.java	Thu Dec 04 17:48:02 2008 -0800
@@ -32,18 +32,19 @@
 public class Property implements Serializable {
 
     public static final long serialVersionUID = 1L;
+
     private String name;
     private String value;
 
-    public Property() {
+    private Property() {
         this(null, null);
     }
 
-    public Property(Property p) {
+    private Property(Property p) {
         this(p.getName(), p.getValue());
     }
 
-    public Property(String name) {
+    private Property(String name) {
         this(name, null);
     }
 
@@ -60,16 +61,19 @@
         return value;
     }
 
-    public void setName(String s) {
-        this.name = s;
-    }
-
-    public void setValue(String s) {
-        this.value = s;
-    }
-
     @Override
     public String toString() {
         return name + " = " + value + "; ";
     }
+
+    @Override
+    public boolean equals(Object o) {
+        if (!(o instanceof Property)) return false;
+        Property p2 = (Property)o;
+        return name.equals(p2.name) && value.equals(p2.value);
+    }
+    @Override
+    public int hashCode() {
+        return name.hashCode() + value == null ? 0 : value.hashCode();
+    }
 }
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/Parser.java	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/Parser.java	Thu Dec 04 17:48:02 2008 -0800
@@ -38,6 +38,7 @@
 import com.sun.hotspot.igv.data.serialization.XMLParser.ParseMonitor;
 import com.sun.hotspot.igv.data.serialization.XMLParser.TopElementHandler;
 import java.io.IOException;
+import java.util.HashMap;
 import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;
 import org.xml.sax.XMLReader;
@@ -88,6 +89,18 @@
     private TopElementHandler xmlDocument = new TopElementHandler();
     private boolean difference;
     private GroupCallback groupCallback;
+    private HashMap<String, Integer> idCache = new HashMap<String, Integer>();
+    private int maxId = 0;
+
+    private int lookupID(String i) {
+        Integer id = idCache.get(i);
+        if (id == null) {
+            id = maxId++;
+            idCache.put(i, id);
+        }
+        return id.intValue();
+    }
+
     // <graphDocument>
     private ElementHandler<GraphDocument, Object> topHandler = new ElementHandler<GraphDocument, Object>(TOP_ELEMENT) {
 
@@ -187,13 +200,13 @@
                 previous = null;
             }
             InputGraph curGraph = new InputGraph(getParentObject(), previous, name);
-            getParentObject().addGraph(curGraph);
             this.graph = curGraph;
             return curGraph;
         }
 
         @Override
         protected void end(String text) throws SAXException {
+            getParentObject().addGraph(graph);
             graph.resolveBlockLinks();
         }
     };
@@ -207,7 +220,7 @@
         @Override
         protected InputBlock start() throws SAXException {
             InputGraph graph = getParentObject();
-            String name = readRequiredAttribute(BLOCK_NAME_PROPERTY);
+            String name = readRequiredAttribute(BLOCK_NAME_PROPERTY).intern();
             InputBlock b = new InputBlock(getParentObject(), name);
             graph.addBlock(b);
             return b;
@@ -224,7 +237,7 @@
 
             int id = 0;
             try {
-                id = Integer.parseInt(s);
+                id = lookupID(s);
             } catch (NumberFormatException e) {
                 throw new SAXException(e);
             }
@@ -252,7 +265,7 @@
             String s = readRequiredAttribute(NODE_ID_PROPERTY);
             int id = 0;
             try {
-                id = Integer.parseInt(s);
+                id = lookupID(s);
             } catch (NumberFormatException e) {
                 throw new SAXException(e);
             }
@@ -269,7 +282,7 @@
             String s = readRequiredAttribute(NODE_ID_PROPERTY);
             int id = 0;
             try {
-                id = Integer.parseInt(s);
+                id = lookupID(s);
             } catch (NumberFormatException e) {
                 throw new SAXException(e);
             }
@@ -280,7 +293,7 @@
     private HandoverElementHandler<InputGraph> edgesHandler = new HandoverElementHandler<InputGraph>(EDGES_ELEMENT);
 
     // Local class for edge elements
-    private static class EdgeElementHandler extends ElementHandler<InputEdge, InputGraph> {
+    private class EdgeElementHandler extends ElementHandler<InputEdge, InputGraph> {
 
         public EdgeElementHandler(String name) {
             super(name);
@@ -298,8 +311,8 @@
                     toIndex = Integer.parseInt(toIndexString);
                 }
 
-                from = Integer.parseInt(readRequiredAttribute(FROM_PROPERTY));
-                to = Integer.parseInt(readRequiredAttribute(TO_PROPERTY));
+                from = lookupID(readRequiredAttribute(FROM_PROPERTY));
+                to = lookupID(readRequiredAttribute(TO_PROPERTY));
             } catch (NumberFormatException e) {
                 throw new SAXException(e);
             }
@@ -344,18 +357,16 @@
         }
     };
     // <property>
-    private ElementHandler<Property, Properties.Provider> propertyHandler = new XMLParser.ElementHandler<Property, Properties.Provider>(PROPERTY_ELEMENT, true) {
+    private ElementHandler<String, Properties.Provider> propertyHandler = new XMLParser.ElementHandler<String, Properties.Provider>(PROPERTY_ELEMENT, true) {
 
         @Override
-        public Property start() throws SAXException {
-            String value = "";
-            String name = readRequiredAttribute(PROPERTY_NAME_PROPERTY).intern();
-            return getParentObject().getProperties().setProperty(name, value);
+        public String start() throws SAXException {
+            return readRequiredAttribute(PROPERTY_NAME_PROPERTY).intern();
         }
 
         @Override
         public void end(String text) {
-            getObject().setValue(text.trim().intern());
+            getParentObject().getProperties().setProperty(getObject(), text.trim().intern());
         }
     };
 
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/Printer.java	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/Printer.java	Thu Dec 04 17:48:02 2008 -0800
@@ -67,7 +67,7 @@
 
     private void export(XMLWriter writer, Group g) throws IOException {
         Properties attributes = new Properties();
-        attributes.add(new Property("difference", Boolean.toString(true)));
+        attributes.setProperty("difference", Boolean.toString(true));
         writer.startTag(Parser.GROUP_ELEMENT, attributes);
         writer.writeProperties(g.getProperties());
 
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/XMLParser.java	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/XMLParser.java	Thu Dec 04 17:48:02 2008 -0800
@@ -25,7 +25,7 @@
 
 import com.sun.hotspot.igv.data.Property;
 import com.sun.hotspot.igv.data.Properties;
-import java.util.Hashtable;
+import java.util.HashMap;
 import java.util.Stack;
 import org.xml.sax.Attributes;
 import org.xml.sax.ContentHandler;
@@ -89,7 +89,7 @@
         private Attributes attr;
         private StringBuilder currentText;
         private ParseMonitor monitor;
-        private Hashtable<String, ElementHandler<?, ? super T>> hashtable;
+        private HashMap<String, ElementHandler<?, ? super T>> hashtable;
         private boolean needsText;
         private ElementHandler<P, ?> parentElement;
 
@@ -110,7 +110,7 @@
         }
 
         public ElementHandler(String name, boolean needsText) {
-            this.hashtable = new Hashtable<String, ElementHandler<?, ? super T>>();
+            this.hashtable = new HashMap<String, ElementHandler<?, ? super T>>();
             this.name = name;
             this.needsText = needsText;
         }
@@ -153,7 +153,7 @@
             for (int i = 0; i < length; i++) {
                 String val = attr.getValue(i).intern();
                 String localName = attr.getLocalName(i).intern();
-                p.add(new Property(val, localName));
+                p.setProperty(val, localName);
             }
         }
 
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/XMLWriter.java	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/XMLWriter.java	Thu Dec 04 17:48:02 2008 -0800
@@ -89,7 +89,7 @@
         inner.write("<" + name);
         elementStack.push(name);
 
-        for (Property p : attributes.getProperties()) {
+        for (Property p : attributes) {
             inner.write(" " + p.getName() + "=\"");
             write(p.getValue().toCharArray());
             inner.write("\"");
@@ -101,7 +101,7 @@
     public void simpleTag(String name, Properties attributes) throws IOException {
         inner.write("<" + name);
 
-        for (Property p : attributes.getProperties()) {
+        for (Property p : attributes) {
             inner.write(" " + p.getName() + "=\"");
             write(p.getValue().toCharArray());
             inner.write("\"");
@@ -111,13 +111,13 @@
     }
 
     public void writeProperties(Properties props) throws IOException {
-        if (props.getProperties().size() == 0) {
+        if (props.getProperties().hasNext() == false) {
             return;
         }
 
         startTag(Parser.PROPERTIES_ELEMENT);
 
-        for (Property p : props.getProperties()) {
+        for (Property p : props) {
             startTag(Parser.PROPERTY_ELEMENT, new Properties(Parser.PROPERTY_NAME_PROPERTY, p.getName()));
             this.write(p.getValue().toCharArray());
             endTag();
--- a/src/share/tools/IdealGraphVisualizer/Difference/src/com/sun/hotspot/igv/difference/Difference.java	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Difference/src/com/sun/hotspot/igv/difference/Difference.java	Thu Dec 04 17:48:02 2008 -0800
@@ -29,6 +29,7 @@
 import com.sun.hotspot.igv.data.InputGraph;
 import com.sun.hotspot.igv.data.InputNode;
 import com.sun.hotspot.igv.data.Property;
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
@@ -124,8 +125,8 @@
             inputNodeMap.put(n, n2);
         }
 
-        Set<InputEdge> edgesA = a.getEdges();
-        Set<InputEdge> edgesB = b.getEdges();
+        Collection<InputEdge> edgesA = a.getEdges();
+        Collection<InputEdge> edgesB = b.getEdges();
 
         Set<InputEdge> newEdges = new HashSet<InputEdge>();
 
@@ -182,7 +183,7 @@
         public double getValue() {
 
             double result = 0.0;
-            for (Property p : n1.getProperties().getProperties()) {
+            for (Property p : n1.getProperties()) {
                 double faktor = 1.0;
                 for (String forbidden : IGNORE_PROPERTIES) {
                     if (p.getName().equals(forbidden)) {
@@ -287,34 +288,34 @@
     private static void markAsChanged(InputNode n, InputNode firstNode, InputNode otherNode) {
 
         boolean difference = false;
-        for (Property p : otherNode.getProperties().getProperties()) {
-            String s = firstNode.getProperties().getProperty(p.getName());
+        for (Property p : otherNode.getProperties()) {
+            String s = firstNode.getProperties().get(p.getName());
             if (!p.getValue().equals(s)) {
                 difference = true;
-                n.getProperties().add(new Property(OLD_PREFIX + p.getName(), p.getValue()));
+                n.getProperties().setProperty(OLD_PREFIX + p.getName(), p.getValue());
             }
         }
 
-        for (Property p : firstNode.getProperties().getProperties()) {
-            String s = otherNode.getProperties().getProperty(p.getName());
+        for (Property p : firstNode.getProperties()) {
+            String s = otherNode.getProperties().get(p.getName());
             if (s == null && p.getValue().length() > 0) {
                 difference = true;
-                n.getProperties().add(new Property(OLD_PREFIX + p.getName(), ""));
+                n.getProperties().setProperty(OLD_PREFIX + p.getName(), "");
             }
         }
 
         if (difference) {
-            n.getProperties().add(new Property(PROPERTY_STATE, VALUE_CHANGED));
+            n.getProperties().setProperty(PROPERTY_STATE, VALUE_CHANGED);
         } else {
-            n.getProperties().add(new Property(PROPERTY_STATE, VALUE_SAME));
+            n.getProperties().setProperty(PROPERTY_STATE, VALUE_SAME);
         }
     }
 
     private static void markAsDeleted(InputNode n) {
-        n.getProperties().add(new Property(PROPERTY_STATE, VALUE_DELETED));
+        n.getProperties().setProperty(PROPERTY_STATE, VALUE_DELETED);
     }
 
     private static void markAsNew(InputNode n) {
-        n.getProperties().add(new Property(PROPERTY_STATE, VALUE_NEW));
+        n.getProperties().setProperty(PROPERTY_STATE, VALUE_NEW);
     }
 }
--- a/src/share/tools/IdealGraphVisualizer/Filter/manifest.mf	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Filter/manifest.mf	Thu Dec 04 17:48:02 2008 -0800
@@ -1,6 +1,6 @@
-Manifest-Version: 1.0
-OpenIDE-Module: com.sun.hotspot.igv.filter
-OpenIDE-Module-Layer: com/sun/hotspot/igv/filter/layer.xml
-OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/filter/Bundle.properties
-OpenIDE-Module-Specification-Version: 1.0
-
+Manifest-Version: 1.0
+OpenIDE-Module: com.sun.hotspot.igv.filter
+OpenIDE-Module-Layer: com/sun/hotspot/igv/filter/layer.xml
+OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/filter/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
--- a/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/CustomFilter.java	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/CustomFilter.java	Thu Dec 04 17:48:02 2008 -0800
@@ -25,7 +25,6 @@
 package com.sun.hotspot.igv.filter;
 
 import com.sun.hotspot.igv.graph.Diagram;
-import com.sun.hotspot.igv.data.Property;
 import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStream;
@@ -56,7 +55,7 @@
     public CustomFilter(String name, String code) {
         this.name = name;
         this.code = code;
-        getProperties().add(new Property("name", name));
+        getProperties().setProperty("name", name);
     }
 
     public String getName() {
--- a/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/SplitFilter.java	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/SplitFilter.java	Thu Dec 04 17:48:02 2008 -0800
@@ -56,8 +56,8 @@
             for (OutputSlot os : f.getOutputSlots()) {
                 for (Connection c : os.getConnections()) {
                     InputSlot is = c.getInputSlot();
-                    is.setName(f.getProperties().getProperty("dump_spec"));
-                    String s = f.getProperties().getProperty("short_name");
+                    is.setName(f.getProperties().get("dump_spec"));
+                    String s = f.getProperties().get("short_name");
                     if (s != null) {
                         is.setShortName(s);
                     }
--- a/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Diagram.java	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Diagram.java	Thu Dec 04 17:48:02 2008 -0800
@@ -35,7 +35,7 @@
 import java.util.Comparator;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Hashtable;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -126,7 +126,7 @@
         d.updateBlocks();
 
         Collection<InputNode> nodes = graph.getNodes();
-        Hashtable<Integer, Figure> figureHash = new Hashtable<Integer, Figure>();
+        HashMap<Integer, Figure> figureHash = new HashMap<Integer, Figure>();
         for (InputNode n : nodes) {
             Figure f = d.createFigure();
             f.getSource().addSourceNode(n);
--- a/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Figure.java	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Figure.java	Thu Dec 04 17:48:02 2008 -0800
@@ -42,7 +42,7 @@
  *
  * @author Thomas Wuerthinger
  */
-public class Figure extends Properties.Object implements Source.Provider, Vertex {
+public class Figure extends Properties.Entity implements Source.Provider, Vertex {
 
     public static final int INSET = 6;
     public static final int SLOT_WIDTH = 10;
--- a/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/Graph.java	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/Graph.java	Thu Dec 04 17:48:02 2008 -0800
@@ -26,7 +26,7 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.Hashtable;
+import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Queue;
@@ -37,13 +37,13 @@
  */
 public class Graph<N, E> {
 
-    private Hashtable<Object, Node<N, E>> nodes;
-    private Hashtable<Object, Edge<N, E>> edges;
+    private HashMap<Object, Node<N, E>> nodes;
+    private HashMap<Object, Edge<N, E>> edges;
     private List<Node<N, E>> nodeList;
 
     public Graph() {
-        nodes = new Hashtable<Object, Node<N, E>>();
-        edges = new Hashtable<Object, Edge<N, E>>();
+        nodes = new HashMap<Object, Node<N, E>>();
+        edges = new HashMap<Object, Edge<N, E>>();
         nodeList = new ArrayList<Node<N, E>>();
     }
 
--- a/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/HierarchicalClusterLayoutManager.java	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/HierarchicalClusterLayoutManager.java	Thu Dec 04 17:48:02 2008 -0800
@@ -25,7 +25,7 @@
 
 import java.awt.Point;
 import java.awt.Rectangle;
-import java.util.Hashtable;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Set;
 import java.util.ArrayList;
@@ -69,19 +69,19 @@
 
         assert graph.verify();
 
-        Hashtable<Cluster, List<Vertex>> lists = new Hashtable<Cluster, List<Vertex>>();
-        Hashtable<Cluster, List<Link>> listsConnection = new Hashtable<Cluster, List<Link>>();
-        Hashtable<Cluster, Hashtable<Port, ClusterInputSlotNode>> clusterInputSlotHash = new Hashtable<Cluster, Hashtable<Port, ClusterInputSlotNode>>();
-        Hashtable<Cluster, Hashtable<Port, ClusterOutputSlotNode>> clusterOutputSlotHash = new Hashtable<Cluster, Hashtable<Port, ClusterOutputSlotNode>>();
+        HashMap<Cluster, List<Vertex>> lists = new HashMap<Cluster, List<Vertex>>();
+        HashMap<Cluster, List<Link>> listsConnection = new HashMap<Cluster, List<Link>>();
+        HashMap<Cluster, HashMap<Port, ClusterInputSlotNode>> clusterInputSlotHash = new HashMap<Cluster, HashMap<Port, ClusterInputSlotNode>>();
+        HashMap<Cluster, HashMap<Port, ClusterOutputSlotNode>> clusterOutputSlotHash = new HashMap<Cluster, HashMap<Port, ClusterOutputSlotNode>>();
 
-        Hashtable<Cluster, ClusterNode> clusterNodes = new Hashtable<Cluster, ClusterNode>();
-        Hashtable<Cluster, Set<ClusterInputSlotNode>> clusterInputSlotSet = new Hashtable<Cluster, Set<ClusterInputSlotNode>>();
-        Hashtable<Cluster, Set<ClusterOutputSlotNode>> clusterOutputSlotSet = new Hashtable<Cluster, Set<ClusterOutputSlotNode>>();
+        HashMap<Cluster, ClusterNode> clusterNodes = new HashMap<Cluster, ClusterNode>();
+        HashMap<Cluster, Set<ClusterInputSlotNode>> clusterInputSlotSet = new HashMap<Cluster, Set<ClusterInputSlotNode>>();
+        HashMap<Cluster, Set<ClusterOutputSlotNode>> clusterOutputSlotSet = new HashMap<Cluster, Set<ClusterOutputSlotNode>>();
         Set<Link> clusterEdges = new HashSet<Link>();
         Set<Link> interClusterEdges = new HashSet<Link>();
-        Hashtable<Link, ClusterOutgoingConnection> linkClusterOutgoingConnection = new Hashtable<Link, ClusterOutgoingConnection>();
-        Hashtable<Link, InterClusterConnection> linkInterClusterConnection = new Hashtable<Link, InterClusterConnection>();
-        Hashtable<Link, ClusterIngoingConnection> linkClusterIngoingConnection = new Hashtable<Link, ClusterIngoingConnection>();
+        HashMap<Link, ClusterOutgoingConnection> linkClusterOutgoingConnection = new HashMap<Link, ClusterOutgoingConnection>();
+        HashMap<Link, InterClusterConnection> linkInterClusterConnection = new HashMap<Link, InterClusterConnection>();
+        HashMap<Link, ClusterIngoingConnection> linkClusterIngoingConnection = new HashMap<Link, ClusterIngoingConnection>();
         Set<ClusterNode> clusterNodeSet = new HashSet<ClusterNode>();
 
         Set<Cluster> cluster = graph.getClusters();
@@ -89,8 +89,8 @@
         for (Cluster c : cluster) {
             lists.put(c, new ArrayList<Vertex>());
             listsConnection.put(c, new ArrayList<Link>());
-            clusterInputSlotHash.put(c, new Hashtable<Port, ClusterInputSlotNode>());
-            clusterOutputSlotHash.put(c, new Hashtable<Port, ClusterOutputSlotNode>());
+            clusterInputSlotHash.put(c, new HashMap<Port, ClusterInputSlotNode>());
+            clusterOutputSlotHash.put(c, new HashMap<Port, ClusterOutputSlotNode>());
             clusterOutputSlotSet.put(c, new TreeSet<ClusterOutputSlotNode>());
             clusterInputSlotSet.put(c, new TreeSet<ClusterInputSlotNode>());
             ClusterNode cn = new ClusterNode(c, "" + z);
--- a/src/share/tools/IdealGraphVisualizer/Layout/src/com/sun/hotspot/igv/layout/LayoutGraph.java	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Layout/src/com/sun/hotspot/igv/layout/LayoutGraph.java	Thu Dec 04 17:48:02 2008 -0800
@@ -24,7 +24,7 @@
 package com.sun.hotspot.igv.layout;
 
 import java.util.HashSet;
-import java.util.Hashtable;
+import java.util.HashMap;
 import java.util.Set;
 import java.util.SortedSet;
 import java.util.TreeSet;
@@ -37,9 +37,9 @@
 
     private Set<? extends Link> links;
     private SortedSet<Vertex> vertices;
-    private Hashtable<Vertex, Set<Port>> inputPorts;
-    private Hashtable<Vertex, Set<Port>> outputPorts;
-    private Hashtable<Port, Set<Link>> portLinks;
+    private HashMap<Vertex, Set<Port>> inputPorts;
+    private HashMap<Vertex, Set<Port>> outputPorts;
+    private HashMap<Port, Set<Link>> portLinks;
 
     public LayoutGraph(Set<? extends Link> links) {
         this(links, new HashSet<Vertex>());
@@ -50,9 +50,9 @@
         assert verify();
 
         vertices = new TreeSet<Vertex>();
-        portLinks = new Hashtable<Port, Set<Link>>();
-        inputPorts = new Hashtable<Vertex, Set<Port>>();
-        outputPorts = new Hashtable<Vertex, Set<Port>>();
+        portLinks = new HashMap<Port, Set<Link>>();
+        inputPorts = new HashMap<Vertex, Set<Port>>();
+        outputPorts = new HashMap<Vertex, Set<Port>>();
 
         for (Link l : links) {
             Port p = l.getFrom();
--- a/src/share/tools/IdealGraphVisualizer/README	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/tools/IdealGraphVisualizer/README	Thu Dec 04 17:48:02 2008 -0800
@@ -5,21 +5,16 @@
 was the primary target of the tool.  The tool itself is fairly general
 with only a few modules that contain C2 specific elements.
 
-The tool is built on top of the NetBeans 6.0 rich client
+The tool is built on top of the NetBeans 6.1 rich client
 infrastructure and so requires NetBeans to build.  It currently
 requires Java 6 to run as it needs support for JavaScript for its
 filtering mechanism and assumes it's built into the platform.  It
-should build out of the box whit NetBeans 6 and Java 6 or later.  It's
-possible to run it on 1.5 by including Rhino on the classpath though
-that currently isn't working correctly.  Support for exporting graphs
-as SVG can be enabled by adding batik to the classpath which isn't
-included by default.
-
-It can be built on top of NetBeans 6.1 if you change the required
-modules to be platform8 instead of platform7.  The tool could run on
-JDK 1.5 with some reworking of the how the JavaScript support is
-enabled but currently it requires some tweaking of the setup.  This
-will be fixed in a later setup.
+should build out of the box with NetBeans 6.1 and Java 6 or later.
+It's possible to run it on 1.5 by including Rhino on the classpath
+though that currently isn't working correctly.  Support for exporting
+graphs as SVG can be enabled by adding batik to the classpath which
+isn't included by default.  It can be built on top of NetBeans 6.0 if
+you change the required modules to be platform7 instead of platform8.
 
 The JVM support is controlled by the flag -XX:PrintIdealGraphLevel=#
 where # is:
--- a/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/PropertiesSheet.java	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/PropertiesSheet.java	Thu Dec 04 17:48:02 2008 -0800
@@ -36,11 +36,11 @@
  */
 public class PropertiesSheet {
 
-    public static void initializeSheet(Properties properties, Sheet s) {
+    public static void initializeSheet(final Properties properties, Sheet s) {
 
         Sheet.Set set1 = Sheet.createPropertiesSet();
         set1.setDisplayName("Properties");
-        for (final Property p : properties.getProperties()) {
+        for (final Property p : properties) {
             Node.Property<String> prop = new Node.Property<String>(String.class) {
 
                 @Override
@@ -60,7 +60,7 @@
 
                 @Override
                 public void setValue(String arg0) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
-                    p.setValue(arg0);
+                    properties.setProperty(p.getName(), arg0);
                 }
             };
             prop.setName(p.getName());
--- a/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/RangeSliderModel.java	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/RangeSliderModel.java	Thu Dec 04 17:48:02 2008 -0800
@@ -65,13 +65,19 @@
 
     public RangeSliderModel(List<String> positions) {
         assert positions.size() > 0;
-        this.positions = positions;
         this.changedEvent = new ChangedEvent<RangeSliderModel>(this);
         this.colorChangedEvent = new ChangedEvent<RangeSliderModel>(this);
+        setPositions(positions);
+    }
+
+    protected void setPositions(List<String> positions) {
+        this.positions = positions;
         colors = new ArrayList<Color>();
         for (int i = 0; i < positions.size(); i++) {
             colors.add(Color.black);
         }
+        changedEvent.fire();
+        colorChangedEvent.fire();
     }
 
     public void setColors(List<Color> colors) {
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramScene.java	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramScene.java	Thu Dec 04 17:48:02 2008 -0800
@@ -63,7 +63,7 @@
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Hashtable;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -104,10 +104,10 @@
  */
 public class DiagramScene extends Scene implements ChangedListener<DiagramViewModel> {
 
-    private Hashtable<Figure, FigureWidget> figureWidgets;
-    private Hashtable<Slot, SlotWidget> slotWidgets;
-    private Hashtable<Connection, ConnectionWidget> connectionWidgets;
-    private Hashtable<InputBlock, BlockWidget> blockWidgets;
+    private HashMap<Figure, FigureWidget> figureWidgets;
+    private HashMap<Slot, SlotWidget> slotWidgets;
+    private HashMap<Connection, ConnectionWidget> connectionWidgets;
+    private HashMap<InputBlock, BlockWidget> blockWidgets;
     private Widget hoverWidget;
     private WidgetAction hoverAction;
     private List<FigureWidget> selectedWidgets;
@@ -414,7 +414,7 @@
         this.addChild(selectLayer);
         this.getActions().addAction(ActionFactory.createRectangularSelectAction(rectangularSelectDecorator, selectLayer, rectangularSelectProvider));
 
-        blockWidgets = new Hashtable<InputBlock, BlockWidget>();
+        blockWidgets = new HashMap<InputBlock, BlockWidget>();
 
         boolean b = this.getUndoRedoEnabled();
         this.setUndoRedoEnabled(false);
@@ -543,9 +543,9 @@
         blockLayer.removeChildren();
 
         blockWidgets.clear();
-        figureWidgets = new Hashtable<Figure, FigureWidget>();
-        slotWidgets = new Hashtable<Slot, SlotWidget>();
-        connectionWidgets = new Hashtable<Connection, ConnectionWidget>();
+        figureWidgets = new HashMap<Figure, FigureWidget>();
+        slotWidgets = new HashMap<Slot, SlotWidget>();
+        connectionWidgets = new HashMap<Connection, ConnectionWidget>();
 
         WidgetAction selectAction = new ExtendedSelectAction(selectProvider);
         Diagram d = getModel().getDiagramToView();
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramViewModel.java	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramViewModel.java	Thu Dec 04 17:48:02 2008 -0800
@@ -55,6 +55,7 @@
     private FilterChain filterChain;
     private FilterChain sequenceFilterChain;
     private Diagram diagram;
+    private ChangedEvent<DiagramViewModel> groupChangedEvent;
     private ChangedEvent<DiagramViewModel> diagramChangedEvent;
     private ChangedEvent<DiagramViewModel> viewChangedEvent;
     private ChangedEvent<DiagramViewModel> viewPropertiesChangedEvent;
@@ -67,6 +68,7 @@
         }
     };
 
+    @Override
     public DiagramViewModel copy() {
         DiagramViewModel result = new DiagramViewModel(group, filterChain, sequenceFilterChain);
         result.setData(this);
@@ -79,6 +81,7 @@
         boolean viewChanged = false;
         boolean viewPropertiesChanged = false;
 
+        boolean groupChanged = (group == newModel.group);
         this.group = newModel.group;
         diagramChanged |= (filterChain != newModel.filterChain);
         this.filterChain = newModel.filterChain;
@@ -97,6 +100,10 @@
         viewPropertiesChanged |= (showNodeHull != newModel.showNodeHull);
         this.showNodeHull = newModel.showNodeHull;
 
+        if(groupChanged) {
+            groupChangedEvent.fire();
+        }
+
         if (diagramChanged) {
             diagramChangedEvent.fire();
         }
@@ -143,11 +150,38 @@
         diagramChangedEvent = new ChangedEvent<DiagramViewModel>(this);
         viewChangedEvent = new ChangedEvent<DiagramViewModel>(this);
         viewPropertiesChangedEvent = new ChangedEvent<DiagramViewModel>(this);
+        groupChangedEvent = new ChangedEvent<DiagramViewModel>(this);
+        groupChangedEvent.addListener(groupChangedListener);
+        groupChangedEvent.fire();
 
         filterChain.getChangedEvent().addListener(filterChainChangedListener);
         sequenceFilterChain.getChangedEvent().addListener(filterChainChangedListener);
     }
 
+    private final ChangedListener<DiagramViewModel> groupChangedListener = new ChangedListener<DiagramViewModel>() {
+
+        private Group oldGroup;
+
+        public void changed(DiagramViewModel source) {
+            if(oldGroup != null) {
+                oldGroup.getChangedEvent().removeListener(groupContentChangedListener);
+            }
+            group.getChangedEvent().addListener(groupContentChangedListener);
+            oldGroup = group;
+        }
+    };
+
+
+    private final ChangedListener<Group> groupContentChangedListener = new ChangedListener<Group>() {
+
+        public void changed(Group source) {
+            assert source == group;
+            setPositions(calculateStringList(source));
+            setSelectedNodes(selectedNodes);
+        }
+
+    };
+
     public ChangedEvent<DiagramViewModel> getDiagramChangedEvent() {
         return diagramChangedEvent;
     }
@@ -268,7 +302,10 @@
     }
 
     public InputGraph getSecondGraph() {
-        return group.getGraphs().get(getSecondPosition());
+        List<InputGraph> graphs = group.getGraphs();
+        if (graphs.size() >= getSecondPosition())
+            return group.getGraphs().get(getSecondPosition());
+        return getFirstGraph();
     }
 
     public void selectGraph(InputGraph g) {
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/FindPanel.java	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/FindPanel.java	Thu Dec 04 17:48:02 2008 -0800
@@ -67,7 +67,7 @@
 
         for (Figure f : figures) {
             Properties prop = f.getProperties();
-            for (Property p : prop.getProperties()) {
+            for (Property p : prop) {
                 if (!propertyNames.contains(p.getName())) {
                     propertyNames.add(p.getName());
                 }
--- a/src/share/tools/IdealGraphVisualizer/nbproject/platform.properties	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/tools/IdealGraphVisualizer/nbproject/platform.properties	Thu Dec 04 17:48:02 2008 -0800
@@ -1,16 +1,16 @@
 # Deprecated since 5.0u1; for compatibility with 5.0:
 disabled.clusters=\
     apisupport1,\
+    gsf1,\
     harness,\
-    ide8,\
-    java1,\
-    nb6.0,\
-    profiler2
+    ide9,\
+    java2,\
+    nb6.1,\
+    profiler3
 disabled.modules=\
     org.netbeans.core.execution,\
     org.netbeans.core.multiview,\
     org.netbeans.core.output2,\
-    org.netbeans.modules.applemenu,\
     org.netbeans.modules.autoupdate.services,\
     org.netbeans.modules.autoupdate.ui,\
     org.netbeans.modules.core.kit,\
@@ -24,6 +24,6 @@
     org.openide.execution,\
     org.openide.util.enumerations
 enabled.clusters=\
-    platform7
+    platform8
 nbjdk.active=default
 nbplatform.active=default
--- a/src/share/tools/IdealGraphVisualizer/nbproject/project.properties	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/tools/IdealGraphVisualizer/nbproject/project.properties	Thu Dec 04 17:48:02 2008 -0800
@@ -15,7 +15,6 @@
     ${project.com.sun.hotspot.igv.difference}:\
     ${project.com.sun.hotspot.igv.settings}:\
     ${project.com.sun.hotspot.igv.util}:\
-    ${project.com.sun.hotspot.igv.rhino}:\
     ${project.com.sun.hotspot.igv.svg}:\
     ${project.com.sun.hotspot.connection}:\
     ${project.com.sun.hotspot.igv.servercompilerscheduler}:\
@@ -31,10 +30,10 @@
 project.com.sun.hotspot.igv.graph=Graph
 project.com.sun.hotspot.igv.hierarchicallayout=HierarchicalLayout
 project.com.sun.hotspot.igv.layout=Layout
-project.com.sun.hotspot.igv.rhino=RhinoScriptEngineProxy
 project.com.sun.hotspot.igv.servercompilerscheduler=ServerCompiler
 project.com.sun.hotspot.igv.settings=Settings
 project.com.sun.hotspot.igv.svg=BatikSVGProxy
 project.com.sun.hotspot.igv.view=View
 project.com.sun.hotspot.igv.util=Util
-run.args = -server -J-Xms64m -J-Xmx512m -J-da
+run.args = -J-server -J-Xms64m -J-Xmx1g -J-da
+run.args.extra = -J-server -J-Xms64m -J-Xmx1g -J-da
--- a/src/share/vm/adlc/adlparse.cpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/adlc/adlparse.cpp	Thu Dec 04 17:48:02 2008 -0800
@@ -33,7 +33,6 @@
     _globalNames(archDesc.globalNames()) {
   _AD._syntax_errs = _AD._semantic_errs = 0; // No errors so far this file
   _AD._warnings    = 0;                      // No warnings either
-  _linenum         = 0;                      // Will increment to first line
   _curline         = _ptr = NULL;            // No pointers into buffer yet
 
   _preproc_depth = 0;
@@ -76,7 +75,7 @@
   }
   if (!_AD._quiet_mode)
     fprintf(stderr,"-----------------------------------------------------------------------------\n");
-  _AD._TotalLines += _linenum-1;     // -1 for overshoot in "nextline" routine
+  _AD._TotalLines += linenum()-1;     // -1 for overshoot in "nextline" routine
 
   // Write out information we have stored
   // // UNIXism == fsync(stderr);
@@ -148,7 +147,7 @@
   if( (ident = get_unique_ident(_globalNames,"instruction")) == NULL )
     return;
   instr = new InstructForm(ident); // Create new instruction form
-  instr->_linenum = _linenum;
+  instr->_linenum = linenum();
   _globalNames.Insert(ident, instr); // Add name to the name table
   // Debugging Stuff
   if (_AD._adl_debug > 1)
@@ -404,7 +403,7 @@
   if( (ident = get_unique_ident(_globalNames,"operand")) == NULL )
     return;
   oper = new OperandForm(ident);        // Create new operand form
-  oper->_linenum = _linenum;
+  oper->_linenum = linenum();
   _globalNames.Insert(ident, oper); // Add name to the name table
 
   // Debugging Stuff
@@ -774,7 +773,7 @@
 
   // Create the RegisterForm for the architecture description.
   RegisterForm *regBlock = new RegisterForm();    // Build new Source object
-  regBlock->_linenum = _linenum;
+  regBlock->_linenum = linenum();
   _AD.addForm(regBlock);
 
   skipws();                       // Skip leading whitespace
@@ -847,7 +846,7 @@
   }
 
   EncClass  *encoding = _AD._encode->add_EncClass(ec_name);
-  encoding->_linenum = _linenum;
+  encoding->_linenum = linenum();
 
   skipws();                      // Skip leading whitespace
   // Check for optional parameter list
@@ -905,7 +904,7 @@
   // Prepend location descriptor, for debugging; cf. ADLParser::find_cpp_block
   if (_AD._adlocation_debug) {
     const char* file     = _AD._ADL_file._name;
-    int         line     = _linenum;
+    int         line     = linenum();
     char*       location = (char *)malloc(strlen(file) + 100);
     sprintf(location, "#line %d \"%s\"\n", line, file);
     encoding->add_code(location);
@@ -2776,7 +2775,7 @@
 
   assert(_AD._encode->encClass(ec_name) == NULL, "shouldn't already exist");
   EncClass  *encoding = _AD._encode->add_EncClass(ec_name);
-  encoding->_linenum = _linenum;
+  encoding->_linenum = linenum();
 
   // synthesize the arguments list for the enc_class from the
   // arguments to the instruct definition.
@@ -2852,7 +2851,7 @@
   skipws();
 
   InsEncode *encrule  = new InsEncode(); // Encode class for instruction
-  encrule->_linenum = _linenum;
+  encrule->_linenum = linenum();
   char      *ec_name  = NULL;      // String representation of encode rule
   // identifier is optional.
   while (_curchar != ')') {
@@ -3203,6 +3202,12 @@
   char *greater_equal;
   char *less_equal;
   char *greater;
+  const char *equal_format = "eq";
+  const char *not_equal_format = "ne";
+  const char *less_format = "lt";
+  const char *greater_equal_format = "ge";
+  const char *less_equal_format = "le";
+  const char *greater_format = "gt";
 
   if (_curchar != '%') {
     parse_err(SYNERR, "Missing '%{' for 'cond_interface' block.\n");
@@ -3222,22 +3227,22 @@
       return NULL;
     }
     if ( strcmp(field,"equal") == 0 ) {
-      equal  = interface_field_parse();
+      equal  = interface_field_parse(&equal_format);
     }
     else if ( strcmp(field,"not_equal") == 0 ) {
-      not_equal = interface_field_parse();
+      not_equal = interface_field_parse(&not_equal_format);
     }
     else if ( strcmp(field,"less") == 0 ) {
-      less = interface_field_parse();
+      less = interface_field_parse(&less_format);
     }
     else if ( strcmp(field,"greater_equal") == 0 ) {
-      greater_equal  = interface_field_parse();
+      greater_equal  = interface_field_parse(&greater_equal_format);
     }
     else if ( strcmp(field,"less_equal") == 0 ) {
-      less_equal = interface_field_parse();
+      less_equal = interface_field_parse(&less_equal_format);
     }
     else if ( strcmp(field,"greater") == 0 ) {
-      greater = interface_field_parse();
+      greater = interface_field_parse(&greater_format);
     }
     else {
       parse_err(SYNERR, "Expected keyword, base|index|scale|disp,  or '%}' ending interface.\n");
@@ -3252,14 +3257,18 @@
   next_char();                  // Skip '}'
 
   // Construct desired object and return
-  Interface *inter = new CondInterface(equal, not_equal, less, greater_equal,
-                                       less_equal, greater);
+  Interface *inter = new CondInterface(equal,         equal_format,
+                                       not_equal,     not_equal_format,
+                                       less,          less_format,
+                                       greater_equal, greater_equal_format,
+                                       less_equal,    less_equal_format,
+                                       greater,       greater_format);
   return inter;
 }
 
 
 //------------------------------interface_field_parse--------------------------
-char *ADLParser::interface_field_parse(void) {
+char *ADLParser::interface_field_parse(const char ** format) {
   char *iface_field = NULL;
 
   // Get interface field
@@ -3280,6 +3289,32 @@
     return NULL;
   }
   skipws();
+  if (format != NULL && _curchar == ',') {
+    next_char();
+    skipws();
+    if (_curchar != '"') {
+      parse_err(SYNERR, "Missing '\"' in field format .\n");
+      return NULL;
+    }
+    next_char();
+    char *start = _ptr;       // Record start of the next string
+    while ((_curchar != '"') && (_curchar != '%') && (_curchar != '\n')) {
+      if (_curchar == '\\')  next_char();  // superquote
+      if (_curchar == '\n')  parse_err(SYNERR, "newline in string");  // unimplemented!
+      next_char();
+    }
+    if (_curchar != '"') {
+      parse_err(SYNERR, "Missing '\"' at end of field format .\n");
+      return NULL;
+    }
+    // If a string was found, terminate it and record in FormatRule
+    if ( start != _ptr ) {
+      *_ptr  = '\0';          // Terminate the string
+      *format = start;
+    }
+    next_char();
+    skipws();
+  }
   if (_curchar != ')') {
     parse_err(SYNERR, "Missing ')' after interface field.\n");
     return NULL;
@@ -3342,6 +3377,12 @@
     next_char();                  // Move past the '{'
 
     skipws();
+    if (_curchar == '$') {
+      char* ident = get_rep_var_ident();
+      if (strcmp(ident, "$$template") == 0) return template_parse();
+      parse_err(SYNERR, "Unknown \"%s\" directive in format", ident);
+      return NULL;
+    }
     // Check for the opening '"' inside the format description
     if ( _curchar == '"' ) {
       next_char();              // Move past the initial '"'
@@ -3433,6 +3474,131 @@
 }
 
 
+//------------------------------template_parse-----------------------------------
+FormatRule* ADLParser::template_parse(void) {
+  char       *desc   = NULL;
+  FormatRule *format = (new FormatRule(desc));
+
+  skipws();
+  while ( (_curchar != '%') && (*(_ptr+1) != '}') ) {
+
+    // (1)
+    // Check if there is a string to pass through to output
+    char *start = _ptr;       // Record start of the next string
+    while ((_curchar != '$') && ((_curchar != '%') || (*(_ptr+1) != '}')) ) {
+      // If at the start of a comment, skip past it
+      if( (_curchar == '/') && ((*(_ptr+1) == '/') || (*(_ptr+1) == '*')) ) {
+        skipws_no_preproc();
+      } else {
+        // ELSE advance to the next character, or start of the next line
+        next_char_or_line();
+      }
+    }
+    // If a string was found, terminate it and record in EncClass
+    if ( start != _ptr ) {
+      *_ptr  = '\0';          // Terminate the string
+      // Add flag to _strings list indicating we should check _rep_vars
+      format->_strings.addName(NameList::_signal2);
+      format->_strings.addName(start);
+    }
+
+    // (2)
+    // If we are at a replacement variable,
+    // copy it and record in EncClass
+    if ( _curchar == '$' ) {
+      // Found replacement Variable
+      char *rep_var = get_rep_var_ident_dup();
+      if (strcmp(rep_var, "$emit") == 0) {
+        // switch to normal format parsing
+        next_char();
+        next_char();
+        skipws();
+        // Check for the opening '"' inside the format description
+        if ( _curchar == '"' ) {
+          next_char();              // Move past the initial '"'
+          if( _curchar == '"' ) {   // Handle empty format string case
+            *_ptr = '\0';           // Terminate empty string
+            format->_strings.addName(_ptr);
+          }
+
+          // Collect the parts of the format description
+          // (1) strings that are passed through to tty->print
+          // (2) replacement/substitution variable, preceeded by a '$'
+          // (3) multi-token ANSIY C style strings
+          while ( true ) {
+            if ( _curchar == '%' || _curchar == '\n' ) {
+              parse_err(SYNERR, "missing '\"' at end of format block");
+              return NULL;
+            }
+
+            // (1)
+            // 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 == '\n')  parse_err(SYNERR, "newline in string");  // unimplemented!
+              next_char();
+            }
+            // If a string was found, terminate it and record in FormatRule
+            if ( start != _ptr ) {
+              *_ptr  = '\0';          // Terminate the string
+              format->_strings.addName(start);
+            }
+
+            // (2)
+            // If we are at a replacement variable,
+            // copy it and record in FormatRule
+            if ( _curchar == '$' ) {
+              next_char();          // Move past the '$'
+              char* rep_var = get_ident(); // Nil terminate the variable name
+              rep_var = strdup(rep_var);// Copy the string
+              *_ptr   = _curchar;     // and replace Nil with original character
+              format->_rep_vars.addName(rep_var);
+              // Add flag to _strings list indicating we should check _rep_vars
+              format->_strings.addName(NameList::_signal);
+            }
+
+            // (3)
+            // Allow very long strings to be broken up,
+            // using the ANSI C syntax "foo\n" <newline> "bar"
+            if ( _curchar == '"') {
+              next_char();           // Move past the '"'
+              skipws();              // Skip white space before next string token
+              if ( _curchar != '"') {
+                break;
+              } else {
+                // Found one.  Skip both " and the whitespace in between.
+                next_char();
+              }
+            }
+          } // end while part of format description
+        }
+      } else {
+        // Add flag to _strings list indicating we should check _rep_vars
+        format->_rep_vars.addName(rep_var);
+        // Add flag to _strings list indicating we should check _rep_vars
+        format->_strings.addName(NameList::_signal3);
+      }
+    } // end while part of format description
+  }
+
+  skipws();
+  // Past format description, at '%'
+  if ( _curchar != '%' || *(_ptr+1) != '}' ) {
+    parse_err(SYNERR, "missing '%}' at end of format block");
+    return NULL;
+  }
+  next_char();                  // Move past the '%'
+  next_char();                  // Move past the '}'
+
+  // Debug Stuff
+  if (_AD._adl_debug > 1) fprintf(stderr,"Format Rule: %s\n", desc);
+
+  skipws();
+  return format;
+}
+
+
 //------------------------------effect_parse-----------------------------------
 void ADLParser::effect_parse(InstructForm *instr) {
   char* desc   = NULL;
@@ -3777,7 +3943,7 @@
     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();
@@ -4297,11 +4463,11 @@
 
   va_start(args, fmt);
   if (flag == 1)
-    _AD._syntax_errs += _AD.emit_msg(0, flag, _linenum, fmt, args);
+    _AD._syntax_errs += _AD.emit_msg(0, flag, linenum(), fmt, args);
   else if (flag == 2)
-    _AD._semantic_errs += _AD.emit_msg(0, flag, _linenum, fmt, args);
+    _AD._semantic_errs += _AD.emit_msg(0, flag, linenum(), fmt, args);
   else
-    _AD._warnings += _AD.emit_msg(0, flag, _linenum, fmt, args);
+    _AD._warnings += _AD.emit_msg(0, flag, linenum(), fmt, args);
 
   int error_char = _curchar;
   char* error_ptr = _ptr+1;
@@ -4515,7 +4681,7 @@
 
 //---------------------------next_line-----------------------------------------
 void ADLParser::next_line() {
-  _curline = _buf.get_line(); _linenum++;
+  _curline = _buf.get_line();
 }
 
 //-------------------------is_literal_constant---------------------------------
--- a/src/share/vm/adlc/adlparse.hpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/adlc/adlparse.hpp	Thu Dec 04 17:48:02 2008 -0800
@@ -70,7 +70,6 @@
 protected:
   char     *_curline;           // Start of current line
   char     *_ptr;               // Pointer into current location in File Buffer
-  int       _linenum;           // Count of line numbers seen so far
   char      _curchar;           // Current character from buffer
   FormDict &_globalNames;       // Global names
 
@@ -160,9 +159,10 @@
   Interface     *interface_parse();      // Parse operand interface rule
   Interface     *mem_interface_parse();  // Parse memory interface rule
   Interface     *cond_interface_parse(); // Parse conditional interface rule
-  char          *interface_field_parse();// Parse field contents
+  char          *interface_field_parse(const char** format = NULL);// Parse field contents
 
   FormatRule    *format_parse(void);     // Parse format rule
+  FormatRule    *template_parse(void);     // Parse format rule
   void           effect_parse(InstructForm *instr); // Parse effect rule
   ExpandRule    *expand_parse(InstructForm *instr); // Parse expand rule
   RewriteRule   *rewrite_parse(void);    // Parse rewrite rule
@@ -263,7 +263,7 @@
 
   void parse(void);             // Do the parsing & build forms lists
 
-  int getlines( ) { return _linenum; }
+  int linenum() { return _buf.linenum(); }
 
   static bool is_literal_constant(const char *hex_string);
   static bool is_hex_digit(char digit);
--- a/src/share/vm/adlc/archDesc.cpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/adlc/archDesc.cpp	Thu Dec 04 17:48:02 2008 -0800
@@ -212,9 +212,9 @@
       // Initialize I/O Files
       _ADL_file._name = NULL; _ADL_file._fp = NULL;
       // Machine dependent output files
-      _DFA_file._name    = "dfa_i486.cpp";  _DFA_file._fp = NULL;
-      _HPP_file._name    = "ad_i486.hpp";   _HPP_file._fp = NULL;
-      _CPP_file._name    = "ad_i486.cpp";   _CPP_file._fp = NULL;
+      _DFA_file._name    = NULL;  _DFA_file._fp = NULL;
+      _HPP_file._name    = NULL;  _HPP_file._fp = NULL;
+      _CPP_file._name    = NULL;  _CPP_file._fp = NULL;
       _bug_file._name    = "bugs.out";      _bug_file._fp = NULL;
 
       // Initialize Register & Pipeline Form Pointers
--- a/src/share/vm/adlc/filebuff.cpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/adlc/filebuff.cpp	Thu Dec 04 17:48:02 2008 -0800
@@ -41,6 +41,7 @@
     exit(1);                    // Exit on seek error
   }
   _filepos = ftell(_fp->_fp);      // Reset current file position
+  _linenum = 0;
 
   _bigbuf = new char[_bufferSize]; // Create buffer to hold text for parser
   if( !_bigbuf ) {
@@ -76,6 +77,7 @@
   // Check for end of file & return NULL
   if (_bufeol >= _bufmax) return NULL;
 
+  _linenum++;
   retval = ++_bufeol;      // return character following end of previous line
   if (*retval == '\0') return NULL; // Check for EOF sentinal
   // Search for newline character which must end each line
--- a/src/share/vm/adlc/filebuff.hpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/adlc/filebuff.hpp	Thu Dec 04 17:48:02 2008 -0800
@@ -51,6 +51,7 @@
 
   int   _err;                   // Error flag for file seek/read operations
   long  _filepos;               // Current offset from start of file
+  int   _linenum;
 
   ArchDesc& _AD;                // Reference to Architecture Description
 
@@ -66,6 +67,7 @@
   // This returns a pointer to the start of the current line in the buffer,
   // and increments bufeol and filepos to point at the end of that line.
   char *get_line(void);
+  int linenum() const { return _linenum; }
 
   // 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/src/share/vm/adlc/forms.cpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/adlc/forms.cpp	Thu Dec 04 17:48:02 2008 -0800
@@ -35,6 +35,8 @@
 //------------------------------NameList---------------------------------------
 // reserved user-defined string
 const char  *NameList::_signal   = "$$SIGNAL$$";
+const char  *NameList::_signal2  = "$$SIGNAL2$$";
+const char  *NameList::_signal3  = "$$SIGNAL3$$";
 
 // Constructor and Destructor
 NameList::NameList() : _cur(0), _max(4), _iter(0), _justReset(true) {
--- a/src/share/vm/adlc/forms.hpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/adlc/forms.hpp	Thu Dec 04 17:48:02 2008 -0800
@@ -329,6 +329,8 @@
 
 public:
   static const char *_signal;      // reserved user-defined string
+  static const char *_signal2;      // reserved user-defined string
+  static const char *_signal3;      // reserved user-defined string
   enum               { Not_in_list = -1 };
 
   void  addName(const char *name);
--- a/src/share/vm/adlc/formssel.cpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/adlc/formssel.cpp	Thu Dec 04 17:48:02 2008 -0800
@@ -1574,10 +1574,10 @@
   return Opcode::NOT_AN_OPCODE;
 }
 
-void Opcode::print_opcode(FILE *fp, Opcode::opcode_type desired_opcode) {
+bool Opcode::print_opcode(FILE *fp, Opcode::opcode_type desired_opcode) {
   // Default values previously provided by MachNode::primary()...
-  const char *description = "default_opcode()";
-  const char *value       = "-1";
+  const char *description = NULL;
+  const char *value       = NULL;
   // Check if user provided any opcode definitions
   if( this != NULL ) {
     // Update 'value' if user provided a definition in the instruction
@@ -1599,7 +1599,10 @@
       break;
     }
   }
-  fprintf(fp, "(%s /*%s*/)", value, description);
+  if (value != NULL) {
+    fprintf(fp, "(%s /*%s*/)", value, description);
+  }
+  return value != NULL;
 }
 
 void Opcode::dump() {
@@ -2610,14 +2613,19 @@
 }
 
 //------------------------------CondInterface----------------------------------
-CondInterface::CondInterface(char *equal,      char *not_equal,
-                             char *less,       char *greater_equal,
-                             char *less_equal, char *greater)
+CondInterface::CondInterface(const char* equal,         const char* equal_format,
+                             const char* not_equal,     const char* not_equal_format,
+                             const char* less,          const char* less_format,
+                             const char* greater_equal, const char* greater_equal_format,
+                             const char* less_equal,    const char* less_equal_format,
+                             const char* greater,       const char* greater_format)
   : Interface("COND_INTER"),
-    _equal(equal), _not_equal(not_equal),
-    _less(less), _greater_equal(greater_equal),
-    _less_equal(less_equal), _greater(greater) {
-      //
+    _equal(equal),                 _equal_format(equal_format),
+    _not_equal(not_equal),         _not_equal_format(not_equal_format),
+    _less(less),                   _less_format(less_format),
+    _greater_equal(greater_equal), _greater_equal_format(greater_equal_format),
+    _less_equal(less_equal),       _less_equal_format(less_equal_format),
+    _greater(greater),             _greater_format(greater_format) {
 }
 CondInterface::~CondInterface() {
   // not owner of any character arrays
@@ -3316,7 +3324,7 @@
     "Load8B" ,"Load4B" ,"Load8C" ,"Load4C" ,"Load2C" ,"Load8S", "Load4S","Load2S",
     "LoadRange", "LoadKlass", "LoadNKlass", "LoadL_unaligned", "LoadD_unaligned",
     "LoadPLocked", "LoadLLocked",
-    "StorePConditional", "StoreLConditional",
+    "StorePConditional", "StoreIConditional", "StoreLConditional",
     "CompareAndSwapI", "CompareAndSwapL", "CompareAndSwapP", "CompareAndSwapN",
     "StoreCM",
     "ClearArray"
--- a/src/share/vm/adlc/formssel.hpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/adlc/formssel.hpp	Thu Dec 04 17:48:02 2008 -0800
@@ -397,7 +397,7 @@
   void output(FILE *fp);
 
   // --------------------------- FILE *output_routines
-  void print_opcode(FILE *fp, Opcode::opcode_type desired_opcode);
+  bool print_opcode(FILE *fp, Opcode::opcode_type desired_opcode);
 };
 
 //------------------------------InsEncode--------------------------------------
@@ -779,10 +779,20 @@
   const char *_greater_equal;
   const char *_less_equal;
   const char *_greater;
+  const char *_equal_format;
+  const char *_not_equal_format;
+  const char *_less_format;
+  const char *_greater_equal_format;
+  const char *_less_equal_format;
+  const char *_greater_format;
 
   // Public Methods
-  CondInterface(char *equal, char *not_equal, char *less, char *greater_equal,
-                char *less_equal, char *greater);
+  CondInterface(const char* equal,         const char* equal_format,
+                const char* not_equal,     const char* not_equal_format,
+                const char* less,          const char* less_format,
+                const char* greater_equal, const char* greater_equal_format,
+                const char* less_equal,    const char* less_equal_format,
+                const char* greater,       const char* greater_format);
   ~CondInterface();
 
   void dump();
--- a/src/share/vm/adlc/output_c.cpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/adlc/output_c.cpp	Thu Dec 04 17:48:02 2008 -0800
@@ -1619,6 +1619,7 @@
       }
 
       // Iterate over the new instruction's operands
+      int prev_pos = -1;
       for( expand_instr->reset(); (opid = expand_instr->iter()) != NULL; ) {
         // Use 'parameter' at current position in list of new instruction's formals
         // instead of 'opid' when looking up info internal to new_inst
@@ -1642,6 +1643,18 @@
           // ins = (InstructForm *) _globalNames[new_id];
           exp_pos = node->operand_position_format(opid);
           assert(exp_pos != -1, "Bad expand rule");
+          if (prev_pos > exp_pos && expand_instruction->_matrule != NULL) {
+            // For the add_req calls below to work correctly they need
+            // to added in the same order that a match would add them.
+            // This means that they would need to be in the order of
+            // the components list instead of the formal parameters.
+            // This is a sort of hidden invariant that previously
+            // wasn't checked and could lead to incorrectly
+            // constructed nodes.
+            syntax_err(node->_linenum, "For expand in %s to work, parameter declaration order in %s must follow matchrule\n",
+                       node->_ident, new_inst->_ident);
+          }
+          prev_pos = exp_pos;
 
           new_pos = new_inst->operand_position(parameter,Component::USE);
           if (new_pos != -1) {
@@ -2306,7 +2319,12 @@
     _processing_noninput = false;
     // A replacement variable, originally '$'
     if ( Opcode::as_opcode_type(rep_var) != Opcode::NOT_AN_OPCODE ) {
-      _inst._opcode->print_opcode(_fp, Opcode::as_opcode_type(rep_var) );
+      if (!_inst._opcode->print_opcode(_fp, Opcode::as_opcode_type(rep_var) )) {
+        // Missing opcode
+        _AD.syntax_err( _inst._linenum,
+                        "Missing $%s opcode definition in %s, used by encoding %s\n",
+                        rep_var, _inst._ident, _encoding._name);
+      }
     }
     else {
       // Lookup its position in parameter list
@@ -2348,7 +2366,13 @@
       else if( Opcode::as_opcode_type(inst_rep_var) != Opcode::NOT_AN_OPCODE ) {
         // else check if "primary", "secondary", "tertiary"
         assert( _constant_status == LITERAL_ACCESSED, "Must be processing a literal constant parameter");
-        _inst._opcode->print_opcode(_fp, Opcode::as_opcode_type(inst_rep_var) );
+        if (!_inst._opcode->print_opcode(_fp, Opcode::as_opcode_type(inst_rep_var) )) {
+          // Missing opcode
+          _AD.syntax_err( _inst._linenum,
+                          "Missing $%s opcode definition in %s\n",
+                          rep_var, _inst._ident);
+
+        }
         _constant_status = LITERAL_OUTPUT;
       }
       else if((_AD.get_registers() != NULL ) && (_AD.get_registers()->getRegDef(inst_rep_var) != NULL)) {
--- a/src/share/vm/adlc/output_h.cpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/adlc/output_h.cpp	Thu Dec 04 17:48:02 2008 -0800
@@ -355,17 +355,19 @@
 // ---------------------------------------------------------------------------
 
 // Generate the format rule for condition codes
-static void defineCCodeDump(FILE *fp, int i) {
-  fprintf(fp, "         if( _c%d == BoolTest::eq ) st->print(\"eq\");\n",i);
-  fprintf(fp, "    else if( _c%d == BoolTest::ne ) st->print(\"ne\");\n",i);
-  fprintf(fp, "    else if( _c%d == BoolTest::le ) st->print(\"le\");\n",i);
-  fprintf(fp, "    else if( _c%d == BoolTest::ge ) st->print(\"ge\");\n",i);
-  fprintf(fp, "    else if( _c%d == BoolTest::lt ) st->print(\"lt\");\n",i);
-  fprintf(fp, "    else if( _c%d == BoolTest::gt ) st->print(\"gt\");\n",i);
+static void defineCCodeDump(OperandForm* oper, FILE *fp, int i) {
+  assert(oper != NULL, "what");
+  CondInterface* cond = oper->_interface->is_CondInterface();
+  fprintf(fp, "         if( _c%d == BoolTest::eq ) st->print(\"%s\");\n",i,cond->_equal_format);
+  fprintf(fp, "    else if( _c%d == BoolTest::ne ) st->print(\"%s\");\n",i,cond->_not_equal_format);
+  fprintf(fp, "    else if( _c%d == BoolTest::le ) st->print(\"%s\");\n",i,cond->_less_equal_format);
+  fprintf(fp, "    else if( _c%d == BoolTest::ge ) st->print(\"%s\");\n",i,cond->_greater_equal_format);
+  fprintf(fp, "    else if( _c%d == BoolTest::lt ) st->print(\"%s\");\n",i,cond->_less_format);
+  fprintf(fp, "    else if( _c%d == BoolTest::gt ) st->print(\"%s\");\n",i,cond->_greater_format);
 }
 
 // Output code that dumps constant values, increment "i" if type is constant
-static uint dump_spec_constant(FILE *fp, const char *ideal_type, uint i) {
+static uint dump_spec_constant(FILE *fp, const char *ideal_type, uint i, OperandForm* oper) {
   if (!strcmp(ideal_type, "ConI")) {
     fprintf(fp,"   st->print(\"#%%d\", _c%d);\n", i);
     ++i;
@@ -375,7 +377,7 @@
     ++i;
   }
   else if (!strcmp(ideal_type, "ConN")) {
-    fprintf(fp,"    _c%d->dump();\n", i);
+    fprintf(fp,"    _c%d->dump_on(st);\n", i);
     ++i;
   }
   else if (!strcmp(ideal_type, "ConL")) {
@@ -391,7 +393,7 @@
     ++i;
   }
   else if (!strcmp(ideal_type, "Bool")) {
-    defineCCodeDump(fp,i);
+    defineCCodeDump(oper, fp,i);
     ++i;
   }
 
@@ -476,7 +478,7 @@
   }
   // ALWAYS! Provide a special case output for condition codes.
   if( oper.is_ideal_bool() ) {
-    defineCCodeDump(fp,0);
+    defineCCodeDump(&oper, fp,0);
   }
   fprintf(fp,"}\n");
 
@@ -549,7 +551,7 @@
   }
   // ALWAYS! Provide a special case output for condition codes.
   if( oper.is_ideal_bool() ) {
-    defineCCodeDump(fp,0);
+    defineCCodeDump(&oper, fp,0);
   }
   fprintf(fp, "}\n");
   fprintf(fp, "#endif\n");
@@ -583,10 +585,53 @@
     while( (string = inst._format->_strings.iter()) != NULL ) {
       fprintf(fp,"    ");
       // Check if this is a standard string or a replacement variable
-      if( string != NameList::_signal )  // Normal string.  Pass through.
+      if( string == NameList::_signal ) { // Replacement variable
+        const char* rep_var =  inst._format->_rep_vars.iter();
+        inst.rep_var_format( fp, rep_var);
+      } else if( string == NameList::_signal3 ) { // Replacement variable in raw text
+        const char* rep_var =  inst._format->_rep_vars.iter();
+        const Form *form   = inst._localNames[rep_var];
+        if (form == NULL) {
+          fprintf(stderr, "unknown replacement variable in format statement: '%s'\n", rep_var);
+          assert(false, "ShouldNotReachHere()");
+        }
+        OpClassForm *opc   = form->is_opclass();
+        assert( opc, "replacement variable was not found in local names");
+        // Lookup the index position of the replacement variable
+        int idx  = inst.operand_position_format(rep_var);
+        if ( idx == -1 ) {
+          assert( strcmp(opc->_ident,"label")==0, "Unimplemented");
+          assert( false, "ShouldNotReachHere()");
+        }
+
+        if (inst.is_noninput_operand(idx)) {
+          assert( false, "ShouldNotReachHere()");
+        } else {
+          // Output the format call for this operand
+          fprintf(fp,"opnd_array(%d)",idx);
+        }
+        rep_var =  inst._format->_rep_vars.iter();
+        inst._format->_strings.iter();
+        if ( strcmp(rep_var,"$constant") == 0 && opc->is_operand()) {
+          Form::DataType constant_type = form->is_operand()->is_base_constant(globals);
+          if ( constant_type == Form::idealD ) {
+            fprintf(fp,"->constantD()");
+          } else if ( constant_type == Form::idealF ) {
+            fprintf(fp,"->constantF()");
+          } else if ( constant_type == Form::idealL ) {
+            fprintf(fp,"->constantL()");
+          } else {
+            fprintf(fp,"->constant()");
+          }
+        } else if ( strcmp(rep_var,"$cmpcode") == 0) {
+            fprintf(fp,"->ccode()");
+        } else {
+          assert( false, "ShouldNotReachHere()");
+        }
+      } else if( string == NameList::_signal2 ) // Raw program text
+        fputs(inst._format->_strings.iter(), fp);
+      else
         fprintf(fp,"st->print(\"%s\");\n", string);
-      else                      // Replacement variable
-        inst.rep_var_format( fp, inst._format->_rep_vars.iter() );
     } // Done with all format strings
   } // Done generating the user-defined portion of the format
 
@@ -1404,7 +1449,7 @@
       oper->_components.reset();
       if ((comp = oper->_components.iter()) == NULL) {
         assert(num_consts == 1, "Bad component list detected.\n");
-        i = dump_spec_constant( fp, type, i );
+        i = dump_spec_constant( fp, type, i, oper );
         // Check that type actually matched
         assert( i != 0, "Non-constant operand lacks component list.");
       } // end if NULL
@@ -1414,7 +1459,7 @@
         oper->_components.reset();
         while((comp = oper->_components.iter()) != NULL) {
           type = comp->base_type(_globalNames);
-          i = dump_spec_constant( fp, type, i );
+          i = dump_spec_constant( fp, type, i, NULL );
         }
       }
       // finish line (3)
--- a/src/share/vm/c1/c1_IR.cpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/c1/c1_IR.cpp	Thu Dec 04 17:48:02 2008 -0800
@@ -574,12 +574,23 @@
     TRACE_LINEAR_SCAN(3, tty->print_cr("backward branch"));
     assert(is_visited(cur), "block must be visisted when block is active");
     assert(parent != NULL, "must have parent");
-    assert(parent->number_of_sux() == 1, "loop end blocks must have one successor (critical edges are split)");
 
     cur->set(BlockBegin::linear_scan_loop_header_flag);
     cur->set(BlockBegin::backward_branch_target_flag);
 
     parent->set(BlockBegin::linear_scan_loop_end_flag);
+
+    // When a loop header is also the start of an exception handler, then the backward branch is
+    // an exception edge. Because such edges are usually critical edges which cannot be split, the
+    // loop must be excluded here from processing.
+    if (cur->is_set(BlockBegin::exception_entry_flag)) {
+      // Make sure that dominators are correct in this weird situation
+      _iterative_dominators = true;
+      return;
+    }
+    assert(parent->number_of_sux() == 1 && parent->sux_at(0) == cur,
+           "loop end blocks must have one successor (critical edges are split)");
+
     _loop_end_blocks.append(parent);
     return;
   }
--- a/src/share/vm/ci/ciEnv.cpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/ci/ciEnv.cpp	Thu Dec 04 17:48:02 2008 -0800
@@ -484,11 +484,16 @@
   } else if (tag.is_double()) {
     return ciConstant((jdouble)cpool->double_at(index));
   } else if (tag.is_string() || tag.is_unresolved_string()) {
-    oop string = cpool->string_at(index, THREAD);
-    if (HAS_PENDING_EXCEPTION) {
-      CLEAR_PENDING_EXCEPTION;
-      record_out_of_memory_failure();
-      return ciConstant();
+    oop string = NULL;
+    if (cpool->is_pseudo_string_at(index)) {
+      string = cpool->pseudo_string_at(index);
+    } else {
+      string = cpool->string_at(index, THREAD);
+      if (HAS_PENDING_EXCEPTION) {
+        CLEAR_PENDING_EXCEPTION;
+        record_out_of_memory_failure();
+        return ciConstant();
+      }
     }
     ciObject* constant = get_object(string);
     assert (constant->is_instance(), "must be an instance, or not? ");
--- a/src/share/vm/classfile/classFileParser.cpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/classfile/classFileParser.cpp	Thu Dec 04 17:48:02 2008 -0800
@@ -168,11 +168,23 @@
           // Got utf8 string, guarantee utf8_length+1 bytes, set stream position forward.
           cfs->guarantee_more(utf8_length+1, CHECK);  // utf8 string, tag/access_flags
           cfs->skip_u1_fast(utf8_length);
+
           // Before storing the symbol, make sure it's legal
           if (_need_verify) {
             verify_legal_utf8((unsigned char*)utf8_buffer, utf8_length, CHECK);
           }
 
+          if (AnonymousClasses && has_cp_patch_at(index)) {
+            Handle patch = clear_cp_patch_at(index);
+            guarantee_property(java_lang_String::is_instance(patch()),
+                               "Illegal utf8 patch at %d in class file %s",
+                               index, CHECK);
+            char* str = java_lang_String::as_utf8_string(patch());
+            // (could use java_lang_String::as_symbol instead, but might as well batch them)
+            utf8_buffer = (u1*) str;
+            utf8_length = (int) strlen(str);
+          }
+
           unsigned int hash;
           symbolOop result = SymbolTable::lookup_only((char*)utf8_buffer, utf8_length, hash);
           if (result == NULL) {
@@ -245,7 +257,7 @@
         int klass_ref_index = cp->klass_ref_index_at(index);
         int name_and_type_ref_index = cp->name_and_type_ref_index_at(index);
         check_property(valid_cp_range(klass_ref_index, length) &&
-                       cp->tag_at(klass_ref_index).is_klass_reference(),
+                       is_klass_reference(cp, klass_ref_index),
                        "Invalid constant pool index %u in class file %s",
                        klass_ref_index,
                        CHECK_(nullHandle));
@@ -326,16 +338,46 @@
     } // end of switch
   } // end of for
 
+  if (_cp_patches != NULL) {
+    // need to treat this_class specially...
+    assert(AnonymousClasses, "");
+    int this_class_index;
+    {
+      cfs->guarantee_more(8, CHECK_(nullHandle));  // flags, this_class, super_class, infs_len
+      u1* mark = cfs->current();
+      u2 flags         = cfs->get_u2_fast();
+      this_class_index = cfs->get_u2_fast();
+      cfs->set_current(mark);  // revert to mark
+    }
+
+    for (index = 1; index < length; index++) {          // Index 0 is unused
+      if (has_cp_patch_at(index)) {
+        guarantee_property(index != this_class_index,
+                           "Illegal constant pool patch to self at %d in class file %s",
+                           index, CHECK_(nullHandle));
+        patch_constant_pool(cp, index, cp_patch_at(index), CHECK_(nullHandle));
+      }
+    }
+    // Ensure that all the patches have been used.
+    for (index = 0; index < _cp_patches->length(); index++) {
+      guarantee_property(!has_cp_patch_at(index),
+                         "Unused constant pool patch at %d in class file %s",
+                         index, CHECK_(nullHandle));
+    }
+  }
+
   if (!_need_verify) {
     return cp;
   }
 
   // second verification pass - checks the strings are of the right format.
+  // but not yet to the other entries
   for (index = 1; index < length; index++) {
     jbyte tag = cp->tag_at(index).value();
     switch (tag) {
       case JVM_CONSTANT_UnresolvedClass: {
         symbolHandle class_name(THREAD, cp->unresolved_klass_at(index));
+        // check the name, even if _cp_patches will overwrite it
         verify_legal_class_name(class_name, CHECK_(nullHandle));
         break;
       }
@@ -378,6 +420,73 @@
 }
 
 
+void ClassFileParser::patch_constant_pool(constantPoolHandle cp, int index, Handle patch, TRAPS) {
+  assert(AnonymousClasses, "");
+  BasicType patch_type = T_VOID;
+  switch (cp->tag_at(index).value()) {
+
+  case JVM_CONSTANT_UnresolvedClass :
+    // Patching a class means pre-resolving it.
+    // The name in the constant pool is ignored.
+    if (patch->klass() == SystemDictionary::class_klass()) { // %%% java_lang_Class::is_instance
+      guarantee_property(!java_lang_Class::is_primitive(patch()),
+                         "Illegal class patch at %d in class file %s",
+                         index, CHECK);
+      cp->klass_at_put(index, java_lang_Class::as_klassOop(patch()));
+    } else {
+      guarantee_property(java_lang_String::is_instance(patch()),
+                         "Illegal class patch at %d in class file %s",
+                         index, CHECK);
+      symbolHandle name = java_lang_String::as_symbol(patch(), CHECK);
+      cp->unresolved_klass_at_put(index, name());
+    }
+    break;
+
+  case JVM_CONSTANT_UnresolvedString :
+    // Patching a string means pre-resolving it.
+    // The spelling in the constant pool is ignored.
+    // The constant reference may be any object whatever.
+    // If it is not a real interned string, the constant is referred
+    // to as a "pseudo-string", and must be presented to the CP
+    // explicitly, because it may require scavenging.
+    cp->pseudo_string_at_put(index, patch());
+    break;
+
+  case JVM_CONSTANT_Integer : patch_type = T_INT;    goto patch_prim;
+  case JVM_CONSTANT_Float :   patch_type = T_FLOAT;  goto patch_prim;
+  case JVM_CONSTANT_Long :    patch_type = T_LONG;   goto patch_prim;
+  case JVM_CONSTANT_Double :  patch_type = T_DOUBLE; goto patch_prim;
+  patch_prim:
+    {
+      jvalue value;
+      BasicType value_type = java_lang_boxing_object::get_value(patch(), &value);
+      guarantee_property(value_type == patch_type,
+                         "Illegal primitive patch at %d in class file %s",
+                         index, CHECK);
+      switch (value_type) {
+      case T_INT:    cp->int_at_put(index,   value.i); break;
+      case T_FLOAT:  cp->float_at_put(index, value.f); break;
+      case T_LONG:   cp->long_at_put(index,  value.j); break;
+      case T_DOUBLE: cp->double_at_put(index, value.d); break;
+      default:       assert(false, "");
+      }
+    }
+    break;
+
+  default:
+    // %%% TODO: put method handles into CONSTANT_InterfaceMethodref, etc.
+    guarantee_property(!has_cp_patch_at(index),
+                       "Illegal unexpected patch at %d in class file %s",
+                       index, CHECK);
+    return;
+  }
+
+  // On fall-through, mark the patch as used.
+  clear_cp_patch_at(index);
+}
+
+
+
 class NameSigHash: public ResourceObj {
  public:
   symbolOop     _name;       // name
@@ -448,25 +557,32 @@
   int index;
   for (index = 0; index < length; index++) {
     u2 interface_index = cfs->get_u2(CHECK_(nullHandle));
+    KlassHandle interf;
     check_property(
       valid_cp_range(interface_index, cp->length()) &&
-        cp->tag_at(interface_index).is_unresolved_klass(),
+      is_klass_reference(cp, interface_index),
       "Interface name has bad constant pool index %u in class file %s",
       interface_index, CHECK_(nullHandle));
-    symbolHandle unresolved_klass (THREAD, cp->klass_name_at(interface_index));
-
-    // Don't need to check legal name because it's checked when parsing constant pool.
-    // But need to make sure it's not an array type.
-    guarantee_property(unresolved_klass->byte_at(0) != JVM_SIGNATURE_ARRAY,
-                       "Bad interface name in class file %s", CHECK_(nullHandle));
-
-    vmtimer->suspend();  // do not count recursive loading twice
-    // Call resolve_super so classcircularity is checked
-    klassOop k = SystemDictionary::resolve_super_or_fail(class_name,
-                  unresolved_klass, class_loader, protection_domain,
-                  false, CHECK_(nullHandle));
-    KlassHandle interf (THREAD, k);
-    vmtimer->resume();
+    if (cp->tag_at(interface_index).is_klass()) {
+      interf = KlassHandle(THREAD, cp->resolved_klass_at(interface_index));
+    } else {
+      symbolHandle unresolved_klass (THREAD, cp->klass_name_at(interface_index));
+
+      // Don't need to check legal name because it's checked when parsing constant pool.
+      // But need to make sure it's not an array type.
+      guarantee_property(unresolved_klass->byte_at(0) != JVM_SIGNATURE_ARRAY,
+                         "Bad interface name in class file %s", CHECK_(nullHandle));
+
+      vmtimer->suspend();  // do not count recursive loading twice
+      // Call resolve_super so classcircularity is checked
+      klassOop k = SystemDictionary::resolve_super_or_fail(class_name,
+                    unresolved_klass, class_loader, protection_domain,
+                    false, CHECK_(nullHandle));
+      interf = KlassHandle(THREAD, k);
+      vmtimer->resume();
+
+      cp->klass_at_put(interface_index, interf()); // eagerly resolve
+    }
 
     if (!Klass::cast(interf())->is_interface()) {
       THROW_MSG_(vmSymbols::java_lang_IncompatibleClassChangeError(), "Implementing class", nullHandle);
@@ -877,8 +993,7 @@
                          "Illegal exception table handler in class file %s", CHECK_(nullHandle));
       if (catch_type_index != 0) {
         guarantee_property(valid_cp_range(catch_type_index, cp->length()) &&
-                          (cp->tag_at(catch_type_index).is_klass() ||
-                           cp->tag_at(catch_type_index).is_unresolved_klass()),
+                           is_klass_reference(cp, catch_type_index),
                            "Catch type in exception table has bad constant type in class file %s", CHECK_(nullHandle));
       }
     }
@@ -1117,7 +1232,7 @@
     } else if (tag == ITEM_Object) {
       u2 class_index = u2_array[i2++] = cfs->get_u2(CHECK);
       guarantee_property(valid_cp_range(class_index, cp->length()) &&
-                         cp->tag_at(class_index).is_unresolved_klass(),
+                         is_klass_reference(cp, class_index),
                          "Bad class index %u in StackMap in class file %s",
                          class_index, CHECK);
     } else if (tag == ITEM_Uninitialized) {
@@ -1183,7 +1298,7 @@
       checked_exception = cfs->get_u2_fast();
       check_property(
         valid_cp_range(checked_exception, cp->length()) &&
-        cp->tag_at(checked_exception).is_klass_reference(),
+        is_klass_reference(cp, checked_exception),
         "Exception name has bad type at constant pool %u in class file %s",
         checked_exception, CHECK_NULL);
     }
@@ -1918,7 +2033,7 @@
     check_property(
       inner_class_info_index == 0 ||
         (valid_cp_range(inner_class_info_index, cp_size) &&
-        cp->tag_at(inner_class_info_index).is_klass_reference()),
+        is_klass_reference(cp, inner_class_info_index)),
       "inner_class_info_index %u has bad constant type in class file %s",
       inner_class_info_index, CHECK_0);
     // Outer class index
@@ -1926,7 +2041,7 @@
     check_property(
       outer_class_info_index == 0 ||
         (valid_cp_range(outer_class_info_index, cp_size) &&
-        cp->tag_at(outer_class_info_index).is_klass_reference()),
+        is_klass_reference(cp, outer_class_info_index)),
       "outer_class_info_index %u has bad constant type in class file %s",
       outer_class_info_index, CHECK_0);
     // Inner class name
@@ -2088,7 +2203,7 @@
         }
         // Validate the constant pool indices and types
         if (!cp->is_within_bounds(class_index) ||
-            !cp->tag_at(class_index).is_klass_reference()) {
+            !is_klass_reference(cp, class_index)) {
           classfile_parse_error("Invalid or out-of-bounds class index in EnclosingMethod attribute in class file %s", CHECK);
         }
         if (method_index != 0 &&
@@ -2349,6 +2464,7 @@
 instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
                                                     Handle class_loader,
                                                     Handle protection_domain,
+                                                    GrowableArray<Handle>* cp_patches,
                                                     symbolHandle& parsed_name,
                                                     TRAPS) {
   // So that JVMTI can cache class file in the state before retransformable agents
@@ -2380,6 +2496,7 @@
     }
   }
 
+  _cp_patches = cp_patches;
 
   instanceKlassHandle nullHandle;
 
@@ -2510,14 +2627,22 @@
                      CHECK_(nullHandle));
     } else {
       check_property(valid_cp_range(super_class_index, cp_size) &&
-                     cp->tag_at(super_class_index).is_unresolved_klass(),
+                     is_klass_reference(cp, super_class_index),
                      "Invalid superclass index %u in class file %s",
                      super_class_index,
                      CHECK_(nullHandle));
       // The class name should be legal because it is checked when parsing constant pool.
       // However, make sure it is not an array type.
+      bool is_array = false;
+      if (cp->tag_at(super_class_index).is_klass()) {
+        super_klass = instanceKlassHandle(THREAD, cp->resolved_klass_at(super_class_index));
+        if (_need_verify)
+          is_array = super_klass->oop_is_array();
+      } else if (_need_verify) {
+        is_array = (cp->unresolved_klass_at(super_class_index)->byte_at(0) == JVM_SIGNATURE_ARRAY);
+      }
       if (_need_verify) {
-        guarantee_property(cp->unresolved_klass_at(super_class_index)->byte_at(0) != JVM_SIGNATURE_ARRAY,
+        guarantee_property(!is_array,
                           "Bad superclass name in class file %s", CHECK_(nullHandle));
       }
     }
@@ -2557,7 +2682,7 @@
     objArrayHandle methods_default_annotations(THREAD, methods_default_annotations_oop);
 
     // We check super class after class file is parsed and format is checked
-    if (super_class_index > 0) {
+    if (super_class_index > 0 && super_klass.is_null()) {
       symbolHandle sk (THREAD, cp->klass_name_at(super_class_index));
       if (access_flags.is_interface()) {
         // Before attempting to resolve the superclass, check for class format
@@ -2574,6 +2699,9 @@
                                                            CHECK_(nullHandle));
       KlassHandle kh (THREAD, k);
       super_klass = instanceKlassHandle(THREAD, kh());
+      cp->klass_at_put(super_class_index, super_klass()); // eagerly resolve
+    }
+    if (super_klass.not_null()) {
       if (super_klass->is_interface()) {
         ResourceMark rm(THREAD);
         Exceptions::fthrow(
@@ -3000,6 +3128,7 @@
     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
     this_klass->set_protection_domain(protection_domain());
     this_klass->set_fields_annotations(fields_annotations());
     this_klass->set_methods_annotations(methods_annotations());
--- a/src/share/vm/classfile/classFileParser.hpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/classfile/classFileParser.hpp	Thu Dec 04 17:48:02 2008 -0800
@@ -33,6 +33,7 @@
   u2   _major_version;
   u2   _minor_version;
   symbolHandle _class_name;
+  GrowableArray<Handle>* _cp_patches; // overrides for CP entries
 
   bool _has_finalizer;
   bool _has_empty_finalizer;
@@ -203,6 +204,35 @@
   char* skip_over_field_name(char* name, bool slash_ok, unsigned int length);
   char* skip_over_field_signature(char* signature, bool void_ok, unsigned int length, TRAPS);
 
+  bool has_cp_patch_at(int index) {
+    assert(AnonymousClasses, "");
+    assert(index >= 0, "oob");
+    return (_cp_patches != NULL
+            && index < _cp_patches->length()
+            && _cp_patches->adr_at(index)->not_null());
+  }
+  Handle cp_patch_at(int index) {
+    assert(has_cp_patch_at(index), "oob");
+    return _cp_patches->at(index);
+  }
+  Handle clear_cp_patch_at(int index) {
+    Handle patch = cp_patch_at(index);
+    _cp_patches->at_put(index, Handle());
+    assert(!has_cp_patch_at(index), "");
+    return patch;
+  }
+  void patch_constant_pool(constantPoolHandle cp, int index, Handle patch, TRAPS);
+
+  // Wrapper for constantTag.is_klass_[or_]reference.
+  // In older versions of the VM, klassOops cannot sneak into early phases of
+  // constant pool construction, but in later versions they can.
+  // %%% Let's phase out the old is_klass_reference.
+  bool is_klass_reference(constantPoolHandle cp, int index) {
+    return ((LinkWellKnownClasses || AnonymousClasses)
+            ? cp->tag_at(index).is_klass_or_reference()
+            : cp->tag_at(index).is_klass_reference());
+  }
+
  public:
   // Constructor
   ClassFileParser(ClassFileStream* st) { set_stream(st); }
@@ -218,6 +248,14 @@
                                      Handle class_loader,
                                      Handle protection_domain,
                                      symbolHandle& parsed_name,
+                                     TRAPS) {
+    return parseClassFile(name, class_loader, protection_domain, NULL, parsed_name, THREAD);
+  }
+  instanceKlassHandle parseClassFile(symbolHandle name,
+                                     Handle class_loader,
+                                     Handle protection_domain,
+                                     GrowableArray<Handle>* cp_patches,
+                                     symbolHandle& parsed_name,
                                      TRAPS);
 
   // Verifier checks
--- a/src/share/vm/classfile/systemDictionary.cpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/classfile/systemDictionary.cpp	Thu Dec 04 17:48:02 2008 -0800
@@ -937,6 +937,8 @@
                                         Handle class_loader,
                                         Handle protection_domain,
                                         ClassFileStream* st,
+                                        KlassHandle host_klass,
+                                        GrowableArray<Handle>* cp_patches,
                                         TRAPS) {
   symbolHandle parsed_name;
 
@@ -953,10 +955,10 @@
   instanceKlassHandle k = ClassFileParser(st).parseClassFile(class_name,
                                                              class_loader,
                                                              protection_domain,
+                                                             cp_patches,
                                                              parsed_name,
                                                              THREAD);
 
-
   // We don't redefine the class, so we just need to clean up whether there
   // was an error or not (don't want to modify any system dictionary
   // data structures).
@@ -973,6 +975,30 @@
     }
   }
 
+  if (host_klass.not_null() && k.not_null()) {
+    assert(AnonymousClasses, "");
+    // If it's anonymous, initialize it now, since nobody else will.
+    k->set_host_klass(host_klass());
+
+    {
+      MutexLocker mu_r(Compile_lock, THREAD);
+
+      // Add to class hierarchy, initialize vtables, and do possible
+      // deoptimizations.
+      add_to_hierarchy(k, CHECK_NULL); // No exception, but can block
+
+      // But, do not add to system dictionary.
+    }
+
+    k->eager_initialize(THREAD);
+
+    // notify jvmti
+    if (JvmtiExport::should_post_class_load()) {
+        assert(THREAD->is_Java_thread(), "thread->is_Java_thread()");
+        JvmtiExport::post_class_load((JavaThread *) THREAD, k());
+    }
+  }
+
   return k();
 }
 
--- a/src/share/vm/classfile/systemDictionary.hpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/classfile/systemDictionary.hpp	Thu Dec 04 17:48:02 2008 -0800
@@ -228,6 +228,16 @@
                                Handle class_loader,
                                Handle protection_domain,
                                ClassFileStream* st,
+                               TRAPS) {
+    KlassHandle nullHandle;
+    return parse_stream(class_name, class_loader, protection_domain, st, nullHandle, NULL, THREAD);
+  }
+  static klassOop parse_stream(symbolHandle class_name,
+                               Handle class_loader,
+                               Handle protection_domain,
+                               ClassFileStream* st,
+                               KlassHandle host_klass,
+                               GrowableArray<Handle>* cp_patches,
                                TRAPS);
 
   // Resolve from stream (called by jni_DefineClass and JVM_DefineClass)
--- a/src/share/vm/classfile/verifier.cpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/classfile/verifier.cpp	Thu Dec 04 17:48:02 2008 -0800
@@ -1600,7 +1600,11 @@
     types = (1 << JVM_CONSTANT_Double) | (1 << JVM_CONSTANT_Long);
     verify_cp_type(index, cp, types, CHECK_VERIFY(this));
   }
-  if (tag.is_string() || tag.is_unresolved_string()) {
+  if (tag.is_string() && cp->is_pseudo_string_at(index)) {
+    current_frame->push_stack(
+      VerificationType::reference_type(
+        vmSymbols::java_lang_Object()), CHECK_VERIFY(this));
+  } else if (tag.is_string() || tag.is_unresolved_string()) {
     current_frame->push_stack(
       VerificationType::reference_type(
         vmSymbols::java_lang_String()), CHECK_VERIFY(this));
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentGCThread.cpp	Thu Dec 04 17:29:56 2008 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,314 +0,0 @@
-/*
- * Copyright 2001-2005 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.
- *
- */
-
-// CopyrightVersion 1.2
-
-# include "incls/_precompiled.incl"
-# include "incls/_concurrentGCThread.cpp.incl"
-
-bool ConcurrentGCThread::_should_terminate    = false;
-bool ConcurrentGCThread::_has_terminated      = false;
-int  ConcurrentGCThread::_CGC_flag            = CGC_nil;
-
-SuspendibleThreadSet ConcurrentGCThread::_sts;
-
-ConcurrentGCThread::ConcurrentGCThread() {
-  _sts.initialize();
-};
-
-void ConcurrentGCThread::stopWorldAndDo(VoidClosure* op) {
-  MutexLockerEx x(Heap_lock,
-                  Mutex::_no_safepoint_check_flag);
-  // warning("CGC: about to try stopping world");
-  SafepointSynchronize::begin();
-  // warning("CGC: successfully stopped world");
-  op->do_void();
-  SafepointSynchronize::end();
-  // warning("CGC: successfully restarted world");
-}
-
-void ConcurrentGCThread::safepoint_synchronize() {
-  _sts.suspend_all();
-}
-
-void ConcurrentGCThread::safepoint_desynchronize() {
-  _sts.resume_all();
-}
-
-void ConcurrentGCThread::create_and_start() {
-  if (os::create_thread(this, os::cgc_thread)) {
-    // XXX: need to set this to low priority
-    // unless "agressive mode" set; priority
-    // should be just less than that of VMThread.
-    os::set_priority(this, NearMaxPriority);
-    if (!_should_terminate && !DisableStartThread) {
-      os::start_thread(this);
-    }
-  }
-}
-
-void ConcurrentGCThread::initialize_in_thread() {
-  this->record_stack_base_and_size();
-  this->initialize_thread_local_storage();
-  this->set_active_handles(JNIHandleBlock::allocate_block());
-  // From this time Thread::current() should be working.
-  assert(this == Thread::current(), "just checking");
-}
-
-void ConcurrentGCThread::wait_for_universe_init() {
-  MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag);
-  while (!is_init_completed() && !_should_terminate) {
-    CGC_lock->wait(Mutex::_no_safepoint_check_flag, 200);
-  }
-}
-
-void ConcurrentGCThread::terminate() {
-  // Signal that it is terminated
-  {
-    MutexLockerEx mu(Terminator_lock,
-                     Mutex::_no_safepoint_check_flag);
-    _has_terminated = true;
-    Terminator_lock->notify();
-  }
-
-  // Thread destructor usually does this..
-  ThreadLocalStorage::set_thread(NULL);
-}
-
-
-void SuspendibleThreadSet::initialize_work() {
-  MutexLocker x(STS_init_lock);
-  if (!_initialized) {
-    _m             = new Monitor(Mutex::leaf,
-                                 "SuspendibleThreadSetLock", true);
-    _async         = 0;
-    _async_stop    = false;
-    _async_stopped = 0;
-    _initialized   = true;
-  }
-}
-
-void SuspendibleThreadSet::join() {
-  initialize();
-  MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag);
-  while (_async_stop) _m->wait(Mutex::_no_safepoint_check_flag);
-  _async++;
-  assert(_async > 0, "Huh.");
-}
-
-void SuspendibleThreadSet::leave() {
-  assert(_initialized, "Must be initialized.");
-  MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag);
-  _async--;
-  assert(_async >= 0, "Huh.");
-  if (_async_stop) _m->notify_all();
-}
-
-void SuspendibleThreadSet::yield(const char* id) {
-  assert(_initialized, "Must be initialized.");
-  if (_async_stop) {
-    MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag);
-    if (_async_stop) {
-      _async_stopped++;
-      assert(_async_stopped > 0, "Huh.");
-      if (_async_stopped == _async) {
-        if (ConcGCYieldTimeout > 0) {
-          double now = os::elapsedTime();
-          guarantee((now - _suspend_all_start) * 1000.0 <
-                    (double)ConcGCYieldTimeout,
-                    "Long delay; whodunit?");
-        }
-      }
-      _m->notify_all();
-      while (_async_stop) _m->wait(Mutex::_no_safepoint_check_flag);
-      _async_stopped--;
-      assert(_async >= 0, "Huh");
-      _m->notify_all();
-    }
-  }
-}
-
-void SuspendibleThreadSet::suspend_all() {
-  initialize();  // If necessary.
-  if (ConcGCYieldTimeout > 0) {
-    _suspend_all_start = os::elapsedTime();
-  }
-  MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag);
-  assert(!_async_stop, "Only one at a time.");
-  _async_stop = true;
-  while (_async_stopped < _async) _m->wait(Mutex::_no_safepoint_check_flag);
-}
-
-void SuspendibleThreadSet::resume_all() {
-  assert(_initialized, "Must be initialized.");
-  MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag);
-  assert(_async_stopped == _async, "Huh.");
-  _async_stop = false;
-  _m->notify_all();
-}
-
-static void _sltLoop(JavaThread* thread, TRAPS) {
-  SurrogateLockerThread* slt = (SurrogateLockerThread*)thread;
-  slt->loop();
-}
-
-SurrogateLockerThread::SurrogateLockerThread() :
-  JavaThread(&_sltLoop),
-  _monitor(Mutex::nonleaf, "SLTMonitor"),
-  _buffer(empty)
-{}
-
-SurrogateLockerThread* SurrogateLockerThread::make(TRAPS) {
-  klassOop k =
-    SystemDictionary::resolve_or_fail(vmSymbolHandles::java_lang_Thread(),
-                                      true, CHECK_NULL);
-  instanceKlassHandle klass (THREAD, k);
-  instanceHandle thread_oop = klass->allocate_instance_handle(CHECK_NULL);
-
-  const char thread_name[] = "Surrogate Locker Thread (CMS)";
-  Handle string = java_lang_String::create_from_str(thread_name, CHECK_NULL);
-
-  // Initialize thread_oop to put it into the system threadGroup
-  Handle thread_group (THREAD, Universe::system_thread_group());
-  JavaValue result(T_VOID);
-  JavaCalls::call_special(&result, thread_oop,
-                          klass,
-                          vmSymbolHandles::object_initializer_name(),
-                          vmSymbolHandles::threadgroup_string_void_signature(),
-                          thread_group,
-                          string,
-                          CHECK_NULL);
-
-  SurrogateLockerThread* res;
-  {
-    MutexLocker mu(Threads_lock);
-    res = new SurrogateLockerThread();
-
-    // At this point it may be possible that no osthread was created for the
-    // JavaThread due to lack of memory. We would have to throw an exception
-    // in that case. However, since this must work and we do not allow
-    // exceptions anyway, check and abort if this fails.
-    if (res == NULL || res->osthread() == NULL) {
-      vm_exit_during_initialization("java.lang.OutOfMemoryError",
-                                    "unable to create new native thread");
-    }
-    java_lang_Thread::set_thread(thread_oop(), res);
-    java_lang_Thread::set_priority(thread_oop(), NearMaxPriority);
-    java_lang_Thread::set_daemon(thread_oop());
-
-    res->set_threadObj(thread_oop());
-    Threads::add(res);
-    Thread::start(res);
-  }
-  os::yield(); // This seems to help with initial start-up of SLT
-  return res;
-}
-
-void SurrogateLockerThread::manipulatePLL(SLT_msg_type msg) {
-  MutexLockerEx x(&_monitor, Mutex::_no_safepoint_check_flag);
-  assert(_buffer == empty, "Should be empty");
-  assert(msg != empty, "empty message");
-  _buffer = msg;
-  while (_buffer != empty) {
-    _monitor.notify();
-    _monitor.wait(Mutex::_no_safepoint_check_flag);
-  }
-}
-
-// ======= Surrogate Locker Thread =============
-
-void SurrogateLockerThread::loop() {
-  BasicLock pll_basic_lock;
-  SLT_msg_type msg;
-  debug_only(unsigned int owned = 0;)
-
-  while (/* !isTerminated() */ 1) {
-    {
-      MutexLocker x(&_monitor);
-      // Since we are a JavaThread, we can't be here at a safepoint.
-      assert(!SafepointSynchronize::is_at_safepoint(),
-             "SLT is a JavaThread");
-      // wait for msg buffer to become non-empty
-      while (_buffer == empty) {
-        _monitor.notify();
-        _monitor.wait();
-      }
-      msg = _buffer;
-    }
-    switch(msg) {
-      case acquirePLL: {
-        instanceRefKlass::acquire_pending_list_lock(&pll_basic_lock);
-        debug_only(owned++;)
-        break;
-      }
-      case releaseAndNotifyPLL: {
-        assert(owned > 0, "Don't have PLL");
-        instanceRefKlass::release_and_notify_pending_list_lock(&pll_basic_lock);
-        debug_only(owned--;)
-        break;
-      }
-      case empty:
-      default: {
-        guarantee(false,"Unexpected message in _buffer");
-        break;
-      }
-    }
-    {
-      MutexLocker x(&_monitor);
-      // Since we are a JavaThread, we can't be here at a safepoint.
-      assert(!SafepointSynchronize::is_at_safepoint(),
-             "SLT is a JavaThread");
-      _buffer = empty;
-      _monitor.notify();
-    }
-  }
-  assert(!_monitor.owned_by_self(), "Should unlock before exit.");
-}
-
-
-// ===== STS Access From Outside CGCT =====
-
-void ConcurrentGCThread::stsYield(const char* id) {
-  assert( Thread::current()->is_ConcurrentGC_thread(),
-          "only a conc GC thread can call this" );
-  _sts.yield(id);
-}
-
-bool ConcurrentGCThread::stsShouldYield() {
-  assert( Thread::current()->is_ConcurrentGC_thread(),
-          "only a conc GC thread can call this" );
-  return _sts.should_yield();
-}
-
-void ConcurrentGCThread::stsJoin() {
-  assert( Thread::current()->is_ConcurrentGC_thread(),
-          "only a conc GC thread can call this" );
-  _sts.join();
-}
-
-void ConcurrentGCThread::stsLeave() {
-  assert( Thread::current()->is_ConcurrentGC_thread(),
-          "only a conc GC thread can call this" );
-  _sts.leave();
-}
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentGCThread.hpp	Thu Dec 04 17:29:56 2008 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,167 +0,0 @@
-/*
- * Copyright 2001-2005 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.
- *
- */
-
-class VoidClosure;
-
-// A SuspendibleThreadSet is (obviously) a set of threads that can be
-// suspended.  A thread can join and later leave the set, and periodically
-// yield.  If some thread (not in the set) requests, via suspend_all, that
-// the threads be suspended, then the requesting thread is blocked until
-// all the threads in the set have yielded or left the set.  (Threads may
-// not enter the set when an attempted suspension is in progress.)  The
-// suspending thread later calls resume_all, allowing the suspended threads
-// to continue.
-
-class SuspendibleThreadSet {
-  Monitor* _m;
-  int      _async;
-  bool     _async_stop;
-  int      _async_stopped;
-  bool     _initialized;
-  double   _suspend_all_start;
-
-  void initialize_work();
-
- public:
-  SuspendibleThreadSet() : _initialized(false) {}
-
-  // Add the current thread to the set.  May block if a suspension
-  // is in progress.
-  void join();
-  // Removes the current thread from the set.
-  void leave();
-  // Returns "true" iff an suspension is in progress.
-  bool should_yield() { return _async_stop; }
-  // Suspends the current thread if a suspension is in progress (for
-  // the duration of the suspension.)
-  void yield(const char* id);
-  // Return when all threads in the set are suspended.
-  void suspend_all();
-  // Allow suspended threads to resume.
-  void resume_all();
-  // Redundant initializations okay.
-  void initialize() {
-    // Double-check dirty read idiom.
-    if (!_initialized) initialize_work();
-  }
-};
-
-
-class ConcurrentGCThread: public NamedThread {
-  friend class VMStructs;
-
-protected:
-  static bool _should_terminate;
-  static bool _has_terminated;
-
-  enum CGC_flag_type {
-    CGC_nil           = 0x0,
-    CGC_dont_suspend  = 0x1,
-    CGC_CGC_safepoint = 0x2,
-    CGC_VM_safepoint  = 0x4
-  };
-
-  static int _CGC_flag;
-
-  static bool CGC_flag_is_set(int b)       { return (_CGC_flag & b) != 0; }
-  static int set_CGC_flag(int b)           { return _CGC_flag |= b; }
-  static int reset_CGC_flag(int b)         { return _CGC_flag &= ~b; }
-
-  void stopWorldAndDo(VoidClosure* op);
-
-  // All instances share this one set.
-  static SuspendibleThreadSet _sts;
-
-  // Create and start the thread (setting it's priority high.)
-  void create_and_start();
-
-  // Do initialization steps in the thread: record stack base and size,
-  // init thread local storage, set JNI handle block.
-  void initialize_in_thread();
-
-  // Wait until Universe::is_fully_initialized();
-  void wait_for_universe_init();
-
-  // Record that the current thread is terminating, and will do more
-  // concurrent work.
-  void terminate();
-
-public:
-  // Constructor
-
-  ConcurrentGCThread();
-  ~ConcurrentGCThread() {} // Exists to call NamedThread destructor.
-
-  // Tester
-  bool is_ConcurrentGC_thread() const          { return true;       }
-
-  static void safepoint_synchronize();
-  static void safepoint_desynchronize();
-
-  // All overridings should probably do _sts::yield, but we allow
-  // overriding for distinguished debugging messages.  Default is to do
-  // nothing.
-  virtual void yield() {}
-
-  bool should_yield() { return _sts.should_yield(); }
-
-  // they are prefixed by sts since there are already yield() and
-  // should_yield() (non-static) methods in this class and it was an
-  // easy way to differentiate them.
-  static void stsYield(const char* id);
-  static bool stsShouldYield();
-  static void stsJoin();
-  static void stsLeave();
-
-};
-
-// The SurrogateLockerThread is used by concurrent GC threads for
-// manipulating Java monitors, in particular, currently for
-// manipulating the pending_list_lock. XXX
-class SurrogateLockerThread: public JavaThread {
-  friend class VMStructs;
- public:
-  enum SLT_msg_type {
-    empty = 0,           // no message
-    acquirePLL,          // acquire pending list lock
-    releaseAndNotifyPLL  // notify and release pending list lock
-  };
- private:
-  // the following are shared with the CMSThread
-  SLT_msg_type  _buffer;  // communication buffer
-  Monitor       _monitor; // monitor controlling buffer
-  BasicLock     _basicLock; // used for PLL locking
-
- public:
-  static SurrogateLockerThread* make(TRAPS);
-
-  SurrogateLockerThread();
-
-  bool is_hidden_from_external_view() const     { return true; }
-
-  void loop(); // main method
-
-  void manipulatePLL(SLT_msg_type msg);
-
-};
--- a/src/share/vm/gc_implementation/g1/ptrQueue.cpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/gc_implementation/g1/ptrQueue.cpp	Thu Dec 04 17:48:02 2008 -0800
@@ -30,7 +30,7 @@
   _perm(perm), _lock(NULL)
 {}
 
-PtrQueue::~PtrQueue() {
+void PtrQueue::flush() {
   if (!_perm && _buf != NULL) {
     if (_index == _sz) {
       // No work to do.
@@ -41,8 +41,9 @@
         _buf[byte_index_to_index((int)i)] = NULL;
       }
       qset()->enqueue_complete_buffer(_buf);
-      _buf = NULL;
     }
+    _buf = NULL;
+    _index = 0;
   }
 }
 
--- a/src/share/vm/gc_implementation/g1/ptrQueue.hpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/gc_implementation/g1/ptrQueue.hpp	Thu Dec 04 17:48:02 2008 -0800
@@ -62,7 +62,9 @@
   // given PtrQueueSet.
   PtrQueue(PtrQueueSet*, bool perm = false);
   // Release any contained resources.
-  ~PtrQueue();
+  void flush();
+  // Calls flush() when destroyed.
+  ~PtrQueue() { flush(); }
 
   // Associate a lock with a ptr queue.
   void set_lock(Mutex* lock) { _lock = lock; }
--- a/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp	Thu Dec 04 17:48:02 2008 -0800
@@ -90,10 +90,10 @@
    */
   bool skip_dead = ((PSMarkSweep::total_invocations() % MarkSweepAlwaysCompactCount) != 0);
 
-  ssize_t allowed_deadspace = 0;
+  size_t allowed_deadspace = 0;
   if (skip_dead) {
-    int ratio = allowed_dead_ratio();
-    allowed_deadspace = (space()->capacity_in_bytes() * ratio / 100) / HeapWordSize;
+    const size_t ratio = allowed_dead_ratio();
+    allowed_deadspace = space()->capacity_in_words() * ratio / 100;
   }
 
   // Fetch the current destination decorator
@@ -271,10 +271,10 @@
   dest->set_compaction_top(compact_top);
 }
 
-bool PSMarkSweepDecorator::insert_deadspace(ssize_t& allowed_deadspace_words,
-                                       HeapWord* q, size_t deadlength) {
-  allowed_deadspace_words -= deadlength;
-  if (allowed_deadspace_words >= 0) {
+bool PSMarkSweepDecorator::insert_deadspace(size_t& allowed_deadspace_words,
+                                            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));
--- a/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.hpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.hpp	Thu Dec 04 17:48:02 2008 -0800
@@ -39,14 +39,16 @@
   HeapWord* _first_dead;
   HeapWord* _end_of_live;
   HeapWord* _compaction_top;
-  unsigned int _allowed_dead_ratio;
+  size_t _allowed_dead_ratio;
 
-  bool insert_deadspace(ssize_t& allowed_deadspace_words, HeapWord* q, size_t word_len);
+  bool insert_deadspace(size_t& allowed_deadspace_words, HeapWord* q,
+                        size_t word_len);
 
  public:
   PSMarkSweepDecorator(MutableSpace* space, ObjectStartArray* start_array,
-                       unsigned int allowed_dead_ratio) :
-    _space(space), _start_array(start_array), _allowed_dead_ratio(allowed_dead_ratio) { }
+                       size_t allowed_dead_ratio) :
+    _space(space), _start_array(start_array),
+    _allowed_dead_ratio(allowed_dead_ratio) { }
 
   // During a compacting collection, we need to collapse objects into
   // spaces in a given order. We want to fill space A, space B, and so
@@ -57,14 +59,14 @@
   static PSMarkSweepDecorator* destination_decorator();
 
   // Accessors
-  MutableSpace* space()                           { return _space; }
-  ObjectStartArray* start_array()                 { return _start_array; }
+  MutableSpace* space()                     { return _space; }
+  ObjectStartArray* start_array()           { return _start_array; }
 
-  HeapWord* compaction_top()                      { return _compaction_top; }
-  void set_compaction_top(HeapWord* value)        { _compaction_top = value; }
+  HeapWord* compaction_top()                { return _compaction_top; }
+  void set_compaction_top(HeapWord* value)  { _compaction_top = value; }
 
-  unsigned int allowed_dead_ratio()               { return _allowed_dead_ratio; }
-  void set_allowed_dead_ratio(unsigned int value) { _allowed_dead_ratio = value; }
+  size_t allowed_dead_ratio()               { return _allowed_dead_ratio; }
+  void set_allowed_dead_ratio(size_t value) { _allowed_dead_ratio = value; }
 
   // Work methods
   void adjust_pointers();
--- a/src/share/vm/includeDB_gc_parallel	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/includeDB_gc_parallel	Thu Dec 04 17:48:02 2008 -0800
@@ -30,6 +30,12 @@
 
 compiledICHolderKlass.cpp               oop.pcgc.inline.hpp
 
+constantPoolKlass.cpp                   cardTableRS.hpp
+constantPoolKlass.cpp                   oop.pcgc.inline.hpp
+constantPoolKlass.cpp                   psPromotionManager.inline.hpp
+constantPoolKlass.cpp                   psScavenge.inline.hpp
+constantPoolKlass.cpp                   parOopClosures.inline.hpp
+
 genCollectedHeap.cpp                    concurrentMarkSweepThread.hpp
 genCollectedHeap.cpp                    vmCMSOperations.hpp
 
--- a/src/share/vm/memory/space.cpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/memory/space.cpp	Thu Dec 04 17:48:02 2008 -0800
@@ -997,11 +997,11 @@
 }
 
 
-int TenuredSpace::allowed_dead_ratio() const {
+size_t TenuredSpace::allowed_dead_ratio() const {
   return MarkSweepDeadRatio;
 }
 
 
-int ContigPermSpace::allowed_dead_ratio() const {
+size_t ContigPermSpace::allowed_dead_ratio() const {
   return PermMarkSweepDeadRatio;
 }
--- a/src/share/vm/memory/space.hpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/memory/space.hpp	Thu Dec 04 17:48:02 2008 -0800
@@ -421,7 +421,7 @@
 
   // The maximum percentage of objects that can be dead in the compacted
   // live part of a compacted space ("deadwood" support.)
-  virtual int allowed_dead_ratio() const { return 0; };
+  virtual size_t allowed_dead_ratio() const { return 0; };
 
   // Some contiguous spaces may maintain some data structures that should
   // be updated whenever an allocation crosses a boundary.  This function
@@ -507,7 +507,7 @@
                                                                              \
   size_t allowed_deadspace = 0;                                              \
   if (skip_dead) {                                                           \
-    int ratio = allowed_dead_ratio();                                        \
+    const size_t ratio = allowed_dead_ratio();                               \
     allowed_deadspace = (capacity() * ratio / 100) / HeapWordSize;           \
   }                                                                          \
                                                                              \
@@ -1079,7 +1079,7 @@
   friend class VMStructs;
  protected:
   // Mark sweep support
-  int allowed_dead_ratio() const;
+  size_t allowed_dead_ratio() const;
  public:
   // Constructor
   TenuredSpace(BlockOffsetSharedArray* sharedOffsetArray,
@@ -1094,7 +1094,7 @@
   friend class VMStructs;
  protected:
   // Mark sweep support
-  int allowed_dead_ratio() const;
+  size_t allowed_dead_ratio() const;
  public:
   // Constructor
   ContigPermSpace(BlockOffsetSharedArray* sharedOffsetArray, MemRegion mr) :
--- a/src/share/vm/memory/tenuredGeneration.hpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/memory/tenuredGeneration.hpp	Thu Dec 04 17:48:02 2008 -0800
@@ -73,7 +73,6 @@
 
   // Mark sweep support
   void compute_new_size();
-  int allowed_dead_ratio() const;
 
   virtual void gc_prologue(bool full);
   virtual void gc_epilogue(bool full);
--- a/src/share/vm/oops/constantPoolKlass.cpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/oops/constantPoolKlass.cpp	Thu Dec 04 17:48:02 2008 -0800
@@ -35,6 +35,7 @@
   c->set_tags(NULL);
   c->set_cache(NULL);
   c->set_pool_holder(NULL);
+  c->set_flags(0);
   // only set to non-zero if constant pool is merged by RedefineClasses
   c->set_orig_length(0);
   // all fields are initialized; needed for GC
@@ -261,10 +262,32 @@
 
 void constantPoolKlass::oop_copy_contents(PSPromotionManager* pm, oop obj) {
   assert(obj->is_constantPool(), "should be constant pool");
+  constantPoolOop cp = (constantPoolOop) obj;
+  if (AnonymousClasses && cp->has_pseudo_string() && cp->tags() != NULL) {
+    oop* base = (oop*)cp->base();
+    for (int i = 0; i < cp->length(); ++i, ++base) {
+      if (cp->tag_at(i).is_string()) {
+        if (PSScavenge::should_scavenge(base)) {
+          pm->claim_or_forward_breadth(base);
+        }
+      }
+    }
+  }
 }
 
 void constantPoolKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
   assert(obj->is_constantPool(), "should be constant pool");
+  constantPoolOop cp = (constantPoolOop) obj;
+  if (AnonymousClasses && cp->has_pseudo_string() && cp->tags() != NULL) {
+    oop* base = (oop*)cp->base();
+    for (int i = 0; i < cp->length(); ++i, ++base) {
+      if (cp->tag_at(i).is_string()) {
+        if (PSScavenge::should_scavenge(base)) {
+          pm->claim_or_forward_depth(base);
+        }
+      }
+    }
+  }
 }
 #endif // SERIALGC
 
@@ -278,6 +301,11 @@
   assert(obj->is_constantPool(), "must be constantPool");
   Klass::oop_print_on(obj, st);
   constantPoolOop cp = constantPoolOop(obj);
+  if (cp->flags() != 0) {
+    st->print(" - flags : 0x%x", cp->flags());
+    if (cp->has_pseudo_string()) st->print(" has_pseudo_string");
+    st->cr();
+  }
 
   // Temp. remove cache so we can do lookups with original indicies.
   constantPoolCacheHandle cache (THREAD, cp->cache());
@@ -302,7 +330,11 @@
         break;
       case JVM_CONSTANT_UnresolvedString :
       case JVM_CONSTANT_String :
-        anObj = cp->string_at(index, CATCH);
+        if (cp->is_pseudo_string_at(index)) {
+          anObj = cp->pseudo_string_at(index);
+        } else {
+          anObj = cp->string_at(index, CATCH);
+        }
         anObj->print_value_on(st);
         st->print(" {0x%lx}", (address)anObj);
         break;
@@ -382,8 +414,12 @@
                   "should be symbol or instance");
       }
       if (cp->tag_at(i).is_string()) {
-        guarantee((*base)->is_perm(),     "should be in permspace");
-        guarantee((*base)->is_instance(), "should be instance");
+        if (!cp->has_pseudo_string()) {
+          guarantee((*base)->is_perm(),   "should be in permspace");
+          guarantee((*base)->is_instance(), "should be instance");
+        } else {
+          // can be non-perm, can be non-instance (array)
+        }
       }
       base++;
     }
--- a/src/share/vm/oops/constantPoolOop.cpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/oops/constantPoolOop.cpp	Thu Dec 04 17:48:02 2008 -0800
@@ -25,6 +25,18 @@
 # include "incls/_precompiled.incl"
 # include "incls/_constantPoolOop.cpp.incl"
 
+void constantPoolOopDesc::set_flag_at(FlagBit fb) {
+  const int MAX_STATE_CHANGES = 2;
+  for (int i = MAX_STATE_CHANGES + 10; i > 0; i--) {
+    int oflags = _flags;
+    int nflags = oflags | (1 << (int)fb);
+    if (Atomic::cmpxchg(nflags, &_flags, oflags) == oflags)
+      return;
+  }
+  assert(false, "failed to cmpxchg flags");
+  _flags |= (1 << (int)fb);     // better than nothing
+}
+
 klassOop constantPoolOopDesc::klass_at_impl(constantPoolHandle this_oop, int which, TRAPS) {
   // A resolved constantPool entry will contain a klassOop, otherwise a symbolOop.
   // It is not safe to rely on the tag bit's here, since we don't have a lock, and the entry and
@@ -333,8 +345,10 @@
   oop entry = *(obj_at_addr(which));
   if (entry->is_symbol()) {
     return ((symbolOop)entry)->as_C_string();
+  } else if (java_lang_String::is_instance(entry)) {
+    return java_lang_String::as_utf8_string(entry);
   } else {
-    return java_lang_String::as_utf8_string(entry);
+    return (char*)"<pseudo-string>";
   }
 }
 
@@ -385,6 +399,19 @@
 }
 
 
+bool constantPoolOopDesc::is_pseudo_string_at(int which) {
+  oop entry = *(obj_at_addr(which));
+  if (entry->is_symbol())
+    // Not yet resolved, but it will resolve to a string.
+    return false;
+  else if (java_lang_String::is_instance(entry))
+    return false; // actually, it might be a non-interned or non-perm string
+  else
+    // truly pseudo
+    return true;
+}
+
+
 bool constantPoolOopDesc::klass_name_at_matches(instanceKlassHandle k,
                                                 int which) {
   // Names are interned, so we can compare symbolOops directly
--- a/src/share/vm/oops/constantPoolOop.hpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/oops/constantPoolOop.hpp	Thu Dec 04 17:48:02 2008 -0800
@@ -41,6 +41,7 @@
   typeArrayOop         _tags; // the tag array describing the constant pool's contents
   constantPoolCacheOop _cache;         // the cache holding interpreter runtime information
   klassOop             _pool_holder;   // the corresponding class
+  int                  _flags;         // a few header bits to describe contents for GC
   int                  _length; // number of elements in the array
   // only set to non-zero if constant pool is merged by RedefineClasses
   int                  _orig_length;
@@ -49,6 +50,16 @@
   void tag_at_put(int which, jbyte t)          { tags()->byte_at_put(which, t); }
   void release_tag_at_put(int which, jbyte t)  { tags()->release_byte_at_put(which, t); }
 
+  enum FlagBit {
+    FB_has_pseudo_string = 2
+  };
+
+  int flags() const                         { return _flags; }
+  void set_flags(int f)                     { _flags = f; }
+  bool flag_at(FlagBit fb) const            { return (_flags & (1 << (int)fb)) != 0; }
+  void set_flag_at(FlagBit fb);
+  // no clear_flag_at function; they only increase
+
  private:
   intptr_t* base() const { return (intptr_t*) (((char*) this) + sizeof(constantPoolOopDesc)); }
   oop* tags_addr()       { return (oop*)&_tags; }
@@ -82,6 +93,9 @@
  public:
   typeArrayOop tags() const                 { return _tags; }
 
+  bool has_pseudo_string() const            { return flag_at(FB_has_pseudo_string); }
+  void set_pseudo_string()                  {    set_flag_at(FB_has_pseudo_string); }
+
   // Klass holding pool
   klassOop pool_holder() const              { return _pool_holder; }
   void set_pool_holder(klassOop k)          { oop_store_without_check((oop*)&_pool_holder, (oop) k); }
@@ -272,6 +286,27 @@
     return string_at_impl(h_this, which, CHECK_NULL);
   }
 
+  // A "pseudo-string" is an non-string oop that has found is way into
+  // a String entry.
+  // Under AnonymousClasses this can happen if the user patches a live
+  // object into a CONSTANT_String entry of an anonymous class.
+  // Method oops internally created for method handles may also
+  // use pseudo-strings to link themselves to related metaobjects.
+
+  bool is_pseudo_string_at(int which);
+
+  oop pseudo_string_at(int which) {
+    assert(tag_at(which).is_string(), "Corrupted constant pool");
+    return *obj_at_addr(which);
+  }
+
+  void pseudo_string_at_put(int which, oop x) {
+    assert(AnonymousClasses, "");
+    set_pseudo_string();        // mark header
+    assert(tag_at(which).is_string() || tag_at(which).is_unresolved_string(), "Corrupted constant pool");
+    string_at_put(which, x);    // this works just fine
+  }
+
   // only called when we are sure a string entry is already resolved (via an
   // earlier string_at call.
   oop resolved_string_at(int which) {
@@ -293,6 +328,7 @@
   // UTF8 char* representation was chosen to avoid conversion of
   // java_lang_Strings at resolved entries into symbolOops
   // or vice versa.
+  // Caller is responsible for checking for pseudo-strings.
   char* string_at_noresolve(int which);
 
   jint name_and_type_at(int which) {
--- a/src/share/vm/oops/instanceKlass.hpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/oops/instanceKlass.hpp	Thu Dec 04 17:48:02 2008 -0800
@@ -147,6 +147,10 @@
   oop             _class_loader;
   // Protection domain.
   oop             _protection_domain;
+  // Host class, which grants its access privileges to this class also.
+  // This is only non-null for an anonymous class (AnonymousClasses enabled).
+  // The host class is either named, or a previously loaded anonymous class.
+  klassOop        _host_klass;
   // Class signers.
   objArrayOop     _signers;
   // Name of source file containing this klass, NULL if not specified.
@@ -375,6 +379,11 @@
   oop protection_domain()                  { return _protection_domain; }
   void set_protection_domain(oop pd)       { oop_store((oop*) &_protection_domain, pd); }
 
+  // host class
+  oop host_klass() const                   { return _host_klass; }
+  void set_host_klass(oop host)            { oop_store((oop*) &_host_klass, host); }
+  bool is_anonymous() const                { return _host_klass != NULL; }
+
   // signers
   objArrayOop signers() const              { return _signers; }
   void set_signers(objArrayOop s)          { oop_store((oop*) &_signers, oop(s)); }
@@ -709,6 +718,7 @@
   oop* adr_constants() const         { return (oop*)&this->_constants;}
   oop* adr_class_loader() const      { return (oop*)&this->_class_loader;}
   oop* adr_protection_domain() const { return (oop*)&this->_protection_domain;}
+  oop* adr_host_klass() const        { return (oop*)&this->_host_klass;}
   oop* adr_signers() const           { return (oop*)&this->_signers;}
   oop* adr_source_file_name() const  { return (oop*)&this->_source_file_name;}
   oop* adr_source_debug_extension() const { return (oop*)&this->_source_debug_extension;}
--- a/src/share/vm/oops/instanceKlassKlass.cpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/oops/instanceKlassKlass.cpp	Thu Dec 04 17:48:02 2008 -0800
@@ -81,6 +81,7 @@
   MarkSweep::mark_and_push(ik->adr_source_debug_extension());
   MarkSweep::mark_and_push(ik->adr_inner_classes());
   MarkSweep::mark_and_push(ik->adr_protection_domain());
+  MarkSweep::mark_and_push(ik->adr_host_klass());
   MarkSweep::mark_and_push(ik->adr_signers());
   MarkSweep::mark_and_push(ik->adr_generic_signature());
   MarkSweep::mark_and_push(ik->adr_class_annotations());
@@ -120,6 +121,7 @@
   PSParallelCompact::mark_and_push(cm, ik->adr_source_debug_extension());
   PSParallelCompact::mark_and_push(cm, ik->adr_inner_classes());
   PSParallelCompact::mark_and_push(cm, ik->adr_protection_domain());
+  PSParallelCompact::mark_and_push(cm, ik->adr_host_klass());
   PSParallelCompact::mark_and_push(cm, ik->adr_signers());
   PSParallelCompact::mark_and_push(cm, ik->adr_generic_signature());
   PSParallelCompact::mark_and_push(cm, ik->adr_class_annotations());
@@ -159,6 +161,7 @@
   blk->do_oop(ik->adr_constants());
   blk->do_oop(ik->adr_class_loader());
   blk->do_oop(ik->adr_protection_domain());
+  blk->do_oop(ik->adr_host_klass());
   blk->do_oop(ik->adr_signers());
   blk->do_oop(ik->adr_source_file_name());
   blk->do_oop(ik->adr_source_debug_extension());
@@ -211,6 +214,8 @@
   if (mr.contains(adr)) blk->do_oop(adr);
   adr = ik->adr_protection_domain();
   if (mr.contains(adr)) blk->do_oop(adr);
+  adr = ik->adr_host_klass();
+  if (mr.contains(adr)) blk->do_oop(adr);
   adr = ik->adr_signers();
   if (mr.contains(adr)) blk->do_oop(adr);
   adr = ik->adr_source_file_name();
@@ -260,6 +265,7 @@
   MarkSweep::adjust_pointer(ik->adr_constants());
   MarkSweep::adjust_pointer(ik->adr_class_loader());
   MarkSweep::adjust_pointer(ik->adr_protection_domain());
+  MarkSweep::adjust_pointer(ik->adr_host_klass());
   MarkSweep::adjust_pointer(ik->adr_signers());
   MarkSweep::adjust_pointer(ik->adr_source_file_name());
   MarkSweep::adjust_pointer(ik->adr_source_debug_extension());
@@ -295,6 +301,11 @@
     pm->claim_or_forward_breadth(pd_addr);
   }
 
+  oop* hk_addr = ik->adr_host_klass();
+  if (PSScavenge::should_scavenge(hk_addr)) {
+    pm->claim_or_forward_breadth(hk_addr);
+  }
+
   oop* sg_addr = ik->adr_signers();
   if (PSScavenge::should_scavenge(sg_addr)) {
     pm->claim_or_forward_breadth(sg_addr);
@@ -318,6 +329,11 @@
     pm->claim_or_forward_depth(pd_addr);
   }
 
+  oop* hk_addr = ik->adr_host_klass();
+  if (PSScavenge::should_scavenge(hk_addr)) {
+    pm->claim_or_forward_depth(hk_addr);
+  }
+
   oop* sg_addr = ik->adr_signers();
   if (PSScavenge::should_scavenge(sg_addr)) {
     pm->claim_or_forward_depth(sg_addr);
@@ -421,6 +437,7 @@
     ik->set_constants(NULL);
     ik->set_class_loader(NULL);
     ik->set_protection_domain(NULL);
+    ik->set_host_klass(NULL);
     ik->set_signers(NULL);
     ik->set_source_file_name(NULL);
     ik->set_source_debug_extension(NULL);
@@ -526,6 +543,7 @@
   st->print(" - constants:         "); ik->constants()->print_value_on(st);         st->cr();
   st->print(" - class loader:      "); ik->class_loader()->print_value_on(st);      st->cr();
   st->print(" - protection domain: "); ik->protection_domain()->print_value_on(st); st->cr();
+  st->print(" - host class: ");        ik->host_klass()->print_value_on(st);        st->cr();
   st->print(" - signers:           "); ik->signers()->print_value_on(st);           st->cr();
   if (ik->source_file_name() != NULL) {
     st->print(" - source file:       ");
@@ -626,7 +644,7 @@
     ik->_verify_count = Universe::verify_count();
 #endif
     // Verify that klass is present in SystemDictionary
-    if (ik->is_loaded()) {
+    if (ik->is_loaded() && !ik->is_anonymous()) {
       symbolHandle h_name (thread, ik->name());
       Handle h_loader (thread, ik->class_loader());
       Handle h_obj(thread, obj);
@@ -764,6 +782,9 @@
     if (ik->protection_domain() != NULL) {
       guarantee(ik->protection_domain()->is_oop(),  "should be oop");
     }
+    if (ik->host_klass() != NULL) {
+      guarantee(ik->host_klass()->is_oop(),  "should be oop");
+    }
     if (ik->signers() != NULL) {
       guarantee(ik->signers()->is_objArray(),       "should be obj array");
     }
--- a/src/share/vm/oops/klass.cpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/oops/klass.cpp	Thu Dec 04 17:48:02 2008 -0800
@@ -478,6 +478,24 @@
 
 
 const char* Klass::external_name() const {
+  if (oop_is_instance()) {
+    instanceKlass* ik = (instanceKlass*) this;
+    if (ik->is_anonymous()) {
+      assert(AnonymousClasses, "");
+      intptr_t hash = ik->java_mirror()->identity_hash();
+      char     hash_buf[40];
+      sprintf(hash_buf, "/" UINTX_FORMAT, (uintx)hash);
+      size_t   hash_len = strlen(hash_buf);
+
+      size_t result_len = name()->utf8_length();
+      char*  result     = NEW_RESOURCE_ARRAY(char, result_len + hash_len + 1);
+      name()->as_klass_external_name(result, (int) result_len + 1);
+      assert(strlen(result) == result_len, "");
+      strcpy(result + result_len, hash_buf);
+      assert(strlen(result) == result_len + hash_len, "");
+      return result;
+    }
+  }
   return name()->as_klass_external_name();
 }
 
--- a/src/share/vm/opto/block.cpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/opto/block.cpp	Thu Dec 04 17:48:02 2008 -0800
@@ -57,6 +57,14 @@
   _blocks[i] = b;
 }
 
+#ifndef PRODUCT
+void Block_List::print() {
+  for (uint i=0; i < size(); i++) {
+    tty->print("B%d ", _blocks[i]->_pre_order);
+  }
+  tty->print("size = %d\n", size());
+}
+#endif
 
 //=============================================================================
 
@@ -66,6 +74,12 @@
   // Check for Start block
   if( _pre_order == 1 ) return InteriorEntryAlignment;
   // Check for loop alignment
+  if (has_loop_alignment())  return loop_alignment();
+
+  return 1;                     // no particular alignment
+}
+
+uint Block::compute_loop_alignment() {
   Node *h = head();
   if( h->is_Loop() && h->as_Loop()->is_inner_loop() )  {
     // Pre- and post-loops have low trip count so do not bother with
@@ -83,13 +97,15 @@
     }
     return OptoLoopAlignment; // Otherwise align loop head
   }
+
   return 1;                     // no particular alignment
 }
 
 //-----------------------------------------------------------------------------
 // Compute the size of first 'inst_cnt' instructions in this block.
 // Return the number of instructions left to compute if the block has
-// less then 'inst_cnt' instructions.
+// less then 'inst_cnt' instructions. Stop, and return 0 if sum_size
+// exceeds OptoLoopAlignment.
 uint Block::compute_first_inst_size(uint& sum_size, uint inst_cnt,
                                     PhaseRegAlloc* ra) {
   uint last_inst = _nodes.size();
@@ -307,6 +323,8 @@
     tty->print("\tLoop: B%d-B%d ", bhead->_pre_order, bx->_pre_order);
     // Dump any loop-specific bits, especially for CountedLoops.
     loop->dump_spec(tty);
+  } else if (has_loop_alignment()) {
+    tty->print(" top-of-loop");
   }
   tty->print(" Freq: %g",_freq);
   if( Verbose || WizardMode ) {
@@ -509,9 +527,11 @@
   int branch_idx = b->_nodes.size() - b->_num_succs-1;
   if( branch_idx < 1 ) return false;
   Node *bra = b->_nodes[branch_idx];
-  if( bra->is_Catch() ) return true;
+  if( bra->is_Catch() )
+    return true;
   if( bra->is_Mach() ) {
-    if( bra->is_MachNullCheck() ) return true;
+    if( bra->is_MachNullCheck() )
+      return true;
     int iop = bra->as_Mach()->ideal_Opcode();
     if( iop == Op_FastLock || iop == Op_FastUnlock )
       return true;
@@ -557,10 +577,10 @@
     dead->_nodes[k]->del_req(j);
 }
 
-//------------------------------MoveToNext-------------------------------------
+//------------------------------move_to_next-----------------------------------
 // Helper function to move block bx to the slot following b_index. Return
 // true if the move is successful, otherwise false
-bool PhaseCFG::MoveToNext(Block* bx, uint b_index) {
+bool PhaseCFG::move_to_next(Block* bx, uint b_index) {
   if (bx == NULL) return false;
 
   // Return false if bx is already scheduled.
@@ -591,9 +611,9 @@
   return true;
 }
 
-//------------------------------MoveToEnd--------------------------------------
+//------------------------------move_to_end------------------------------------
 // Move empty and uncommon blocks to the end.
-void PhaseCFG::MoveToEnd(Block *b, uint i) {
+void PhaseCFG::move_to_end(Block *b, uint i) {
   int e = b->is_Empty();
   if (e != Block::not_empty) {
     if (e == Block::empty_with_goto) {
@@ -609,15 +629,31 @@
   _blocks.push(b);
 }
 
-//------------------------------RemoveEmpty------------------------------------
-// Remove empty basic blocks and useless branches.
-void PhaseCFG::RemoveEmpty() {
+//---------------------------set_loop_alignment--------------------------------
+// Set loop alignment for every block
+void PhaseCFG::set_loop_alignment() {
+  uint last = _num_blocks;
+  assert( _blocks[0] == _broot, "" );
+
+  for (uint i = 1; i < last; i++ ) {
+    Block *b = _blocks[i];
+    if (b->head()->is_Loop()) {
+      b->set_loop_alignment(b);
+    }
+  }
+}
+
+//-----------------------------remove_empty------------------------------------
+// Make empty basic blocks to be "connector" blocks, Move uncommon blocks
+// to the end.
+void PhaseCFG::remove_empty() {
   // Move uncommon blocks to the end
   uint last = _num_blocks;
-  uint i;
   assert( _blocks[0] == _broot, "" );
-  for( i = 1; i < last; i++ ) {
+
+  for (uint i = 1; i < last; i++) {
     Block *b = _blocks[i];
+    if (b->is_connector()) break;
 
     // Check for NeverBranch at block end.  This needs to become a GOTO to the
     // true target.  NeverBranch are treated as a conditional branch that
@@ -629,37 +665,40 @@
       convert_NeverBranch_to_Goto(b);
 
     // Look for uncommon blocks and move to end.
-    if( b->is_uncommon(_bbs) ) {
-      MoveToEnd(b, i);
-      last--;                   // No longer check for being uncommon!
-      if( no_flip_branch(b) ) { // Fall-thru case must follow?
-        b = _blocks[i];         // Find the fall-thru block
-        MoveToEnd(b, i);
-        last--;
+    if (!C->do_freq_based_layout()) {
+      if( b->is_uncommon(_bbs) ) {
+        move_to_end(b, i);
+        last--;                   // No longer check for being uncommon!
+        if( no_flip_branch(b) ) { // Fall-thru case must follow?
+          b = _blocks[i];         // Find the fall-thru block
+          move_to_end(b, i);
+          last--;
+        }
+        i--;                      // backup block counter post-increment
       }
-      i--;                      // backup block counter post-increment
     }
   }
 
-  // Remove empty blocks
-  uint j1;
+  // Move empty blocks to the end
   last = _num_blocks;
-  for( i=0; i < last; i++ ) {
+  for (uint i = 1; i < last; i++) {
     Block *b = _blocks[i];
-    if (i > 0) {
-      if (b->is_Empty() != Block::not_empty) {
-        MoveToEnd(b, i);
-        last--;
-        i--;
-      }
+    if (b->is_Empty() != Block::not_empty) {
+      move_to_end(b, i);
+      last--;
+      i--;
     }
   } // End of for all blocks
+}
 
+//-----------------------------fixup_flow--------------------------------------
+// Fix up the final control flow for basic blocks.
+void PhaseCFG::fixup_flow() {
   // Fixup final control flow for the blocks.  Remove jump-to-next
   // block.  If neither arm of a IF follows the conditional branch, we
   // have to add a second jump after the conditional.  We place the
   // TRUE branch target in succs[0] for both GOTOs and IFs.
-  for( i=0; i < _num_blocks; i++ ) {
+  for (uint i=0; i < _num_blocks; i++) {
     Block *b = _blocks[i];
     b->_pre_order = i;          // turn pre-order into block-index
 
@@ -700,7 +739,7 @@
         }
       }
       // Remove all CatchProjs
-      for (j1 = 0; j1 < b->_num_succs; j1++) b->_nodes.pop();
+      for (uint j1 = 0; j1 < b->_num_succs; j1++) b->_nodes.pop();
 
     } else if (b->_num_succs == 1) {
       // Block ends in a Goto?
@@ -730,8 +769,7 @@
       // successors after the current one, provided that the
       // successor was previously unscheduled, but moveable
       // (i.e., all paths to it involve a branch).
-      if( bnext != bs0 && bnext != bs1 ) {
-
+      if( !C->do_freq_based_layout() && bnext != bs0 && bnext != bs1 ) {
         // Choose the more common successor based on the probability
         // of the conditional branch.
         Block *bx = bs0;
@@ -751,9 +789,9 @@
         }
 
         // Attempt the more common successor first
-        if (MoveToNext(bx, i)) {
+        if (move_to_next(bx, i)) {
           bnext = bx;
-        } else if (MoveToNext(by, i)) {
+        } else if (move_to_next(by, i)) {
           bnext = by;
         }
       }
@@ -774,10 +812,8 @@
         // Flip projection for each target
         { ProjNode *tmp = proj0; proj0 = proj1; proj1 = tmp; }
 
-      } else if( bnext == bs1 ) { // Fall-thru is already in succs[1]
-
-      } else {                  // Else need a double-branch
-
+      } else if( bnext != bs1 ) {
+        // Need a double-branch
         // The existing conditional branch need not change.
         // Add a unconditional branch to the false target.
         // Alas, it must appear in its own block and adding a
@@ -786,8 +822,9 @@
       }
 
       // Make sure we TRUE branch to the target
-      if( proj0->Opcode() == Op_IfFalse )
+      if( proj0->Opcode() == Op_IfFalse ) {
         iff->negate();
+      }
 
       b->_nodes.pop();          // Remove IfFalse & IfTrue projections
       b->_nodes.pop();
@@ -796,9 +833,7 @@
       // Multi-exit block, e.g. a switch statement
       // But we don't need to do anything here
     }
-
   } // End of for all blocks
-
 }
 
 
@@ -905,7 +940,7 @@
   // Force the Union-Find mapping to be at least this large
   extend(max,0);
   // Initialize to be the ID mapping.
-  for( uint i=0; i<_max; i++ ) map(i,i);
+  for( uint i=0; i<max; i++ ) map(i,i);
 }
 
 //------------------------------Find_compress----------------------------------
@@ -937,7 +972,6 @@
   if( idx >= _max ) return idx;
   uint next = lookup(idx);
   while( next != idx ) {        // Scan chain of equivalences
-    assert( next < idx, "always union smaller" );
     idx = next;                 // until find a fixed-point
     next = lookup(idx);
   }
@@ -956,3 +990,491 @@
   assert( src < dst, "always union smaller" );
   map(dst,src);
 }
+
+#ifndef PRODUCT
+static void edge_dump(GrowableArray<CFGEdge *> *edges) {
+  tty->print_cr("---- Edges ----");
+  for (int i = 0; i < edges->length(); i++) {
+    CFGEdge *e = edges->at(i);
+    if (e != NULL) {
+      edges->at(i)->dump();
+    }
+  }
+}
+
+static void trace_dump(Trace *traces[], int count) {
+  tty->print_cr("---- Traces ----");
+  for (int i = 0; i < count; i++) {
+    Trace *tr = traces[i];
+    if (tr != NULL) {
+      tr->dump();
+    }
+  }
+}
+
+void Trace::dump( ) const {
+  tty->print_cr("Trace (freq %f)", first_block()->_freq);
+  for (Block *b = first_block(); b != NULL; b = next(b)) {
+    tty->print("  B%d", b->_pre_order);
+    if (b->head()->is_Loop()) {
+      tty->print(" (L%d)", b->compute_loop_alignment());
+    }
+    if (b->has_loop_alignment()) {
+      tty->print(" (T%d)", b->code_alignment());
+    }
+  }
+  tty->cr();
+}
+
+void CFGEdge::dump( ) const {
+  tty->print(" B%d  -->  B%d  Freq: %f  out:%3d%%  in:%3d%%  State: ",
+             from()->_pre_order, to()->_pre_order, freq(), _from_pct, _to_pct);
+  switch(state()) {
+  case connected:
+    tty->print("connected");
+    break;
+  case open:
+    tty->print("open");
+    break;
+  case interior:
+    tty->print("interior");
+    break;
+  }
+  if (infrequent()) {
+    tty->print("  infrequent");
+  }
+  tty->cr();
+}
+#endif
+
+//=============================================================================
+
+//------------------------------edge_order-------------------------------------
+// Comparison function for edges
+static int edge_order(CFGEdge **e0, CFGEdge **e1) {
+  float freq0 = (*e0)->freq();
+  float freq1 = (*e1)->freq();
+  if (freq0 != freq1) {
+    return freq0 > freq1 ? -1 : 1;
+  }
+
+  int dist0 = (*e0)->to()->_rpo - (*e0)->from()->_rpo;
+  int dist1 = (*e1)->to()->_rpo - (*e1)->from()->_rpo;
+
+  return dist1 - dist0;
+}
+
+//------------------------------trace_frequency_order--------------------------
+// Comparison function for edges
+static int trace_frequency_order(const void *p0, const void *p1) {
+  Trace *tr0 = *(Trace **) p0;
+  Trace *tr1 = *(Trace **) p1;
+  Block *b0 = tr0->first_block();
+  Block *b1 = tr1->first_block();
+
+  // The trace of connector blocks goes at the end;
+  // we only expect one such trace
+  if (b0->is_connector() != b1->is_connector()) {
+    return b1->is_connector() ? -1 : 1;
+  }
+
+  // Pull more frequently executed blocks to the beginning
+  float freq0 = b0->_freq;
+  float freq1 = b1->_freq;
+  if (freq0 != freq1) {
+    return freq0 > freq1 ? -1 : 1;
+  }
+
+  int diff = tr0->first_block()->_rpo - tr1->first_block()->_rpo;
+
+  return diff;
+}
+
+//------------------------------find_edges-------------------------------------
+// Find edges of interest, i.e, those which can fall through. Presumes that
+// edges which don't fall through are of low frequency and can be generally
+// ignored.  Initialize the list of traces.
+void PhaseBlockLayout::find_edges()
+{
+  // Walk the blocks, creating edges and Traces
+  uint i;
+  Trace *tr = NULL;
+  for (i = 0; i < _cfg._num_blocks; i++) {
+    Block *b = _cfg._blocks[i];
+    tr = new Trace(b, next, prev);
+    traces[tr->id()] = tr;
+
+    // All connector blocks should be at the end of the list
+    if (b->is_connector()) break;
+
+    // If this block and the next one have a one-to-one successor
+    // predecessor relationship, simply append the next block
+    int nfallthru = b->num_fall_throughs();
+    while (nfallthru == 1 &&
+           b->succ_fall_through(0)) {
+      Block *n = b->_succs[0];
+
+      // Skip over single-entry connector blocks, we don't want to
+      // add them to the trace.
+      while (n->is_connector() && n->num_preds() == 1) {
+        n = n->_succs[0];
+      }
+
+      // We see a merge point, so stop search for the next block
+      if (n->num_preds() != 1) break;
+
+      i++;
+      assert(n = _cfg._blocks[i], "expecting next block");
+      tr->append(n);
+      uf->map(n->_pre_order, tr->id());
+      traces[n->_pre_order] = NULL;
+      nfallthru = b->num_fall_throughs();
+      b = n;
+    }
+
+    if (nfallthru > 0) {
+      // Create a CFGEdge for each outgoing
+      // edge that could be a fall-through.
+      for (uint j = 0; j < b->_num_succs; j++ ) {
+        if (b->succ_fall_through(j)) {
+          Block *target = b->non_connector_successor(j);
+          float freq = b->_freq * b->succ_prob(j);
+          int from_pct = (int) ((100 * freq) / b->_freq);
+          int to_pct = (int) ((100 * freq) / target->_freq);
+          edges->append(new CFGEdge(b, target, freq, from_pct, to_pct));
+        }
+      }
+    }
+  }
+
+  // Group connector blocks into one trace
+  for (i++; i < _cfg._num_blocks; i++) {
+    Block *b = _cfg._blocks[i];
+    assert(b->is_connector(), "connector blocks at the end");
+    tr->append(b);
+    uf->map(b->_pre_order, tr->id());
+    traces[b->_pre_order] = NULL;
+  }
+}
+
+//------------------------------union_traces----------------------------------
+// Union two traces together in uf, and null out the trace in the list
+void PhaseBlockLayout::union_traces(Trace* updated_trace, Trace* old_trace)
+{
+  uint old_id = old_trace->id();
+  uint updated_id = updated_trace->id();
+
+  uint lo_id = updated_id;
+  uint hi_id = old_id;
+
+  // If from is greater than to, swap values to meet
+  // UnionFind guarantee.
+  if (updated_id > old_id) {
+    lo_id = old_id;
+    hi_id = updated_id;
+
+    // Fix up the trace ids
+    traces[lo_id] = traces[updated_id];
+    updated_trace->set_id(lo_id);
+  }
+
+  // Union the lower with the higher and remove the pointer
+  // to the higher.
+  uf->Union(lo_id, hi_id);
+  traces[hi_id] = NULL;
+}
+
+//------------------------------grow_traces-------------------------------------
+// Append traces together via the most frequently executed edges
+void PhaseBlockLayout::grow_traces()
+{
+  // Order the edges, and drive the growth of Traces via the most
+  // frequently executed edges.
+  edges->sort(edge_order);
+  for (int i = 0; i < edges->length(); i++) {
+    CFGEdge *e = edges->at(i);
+
+    if (e->state() != CFGEdge::open) continue;
+
+    Block *src_block = e->from();
+    Block *targ_block = e->to();
+
+    // Don't grow traces along backedges?
+    if (!BlockLayoutRotateLoops) {
+      if (targ_block->_rpo <= src_block->_rpo) {
+        targ_block->set_loop_alignment(targ_block);
+        continue;
+      }
+    }
+
+    Trace *src_trace = trace(src_block);
+    Trace *targ_trace = trace(targ_block);
+
+    // If the edge in question can join two traces at their ends,
+    // append one trace to the other.
+   if (src_trace->last_block() == src_block) {
+      if (src_trace == targ_trace) {
+        e->set_state(CFGEdge::interior);
+        if (targ_trace->backedge(e)) {
+          // Reset i to catch any newly eligible edge
+          // (Or we could remember the first "open" edge, and reset there)
+          i = 0;
+        }
+      } else if (targ_trace->first_block() == targ_block) {
+        e->set_state(CFGEdge::connected);
+        src_trace->append(targ_trace);
+        union_traces(src_trace, targ_trace);
+      }
+    }
+  }
+}
+
+//------------------------------merge_traces-----------------------------------
+// Embed one trace into another, if the fork or join points are sufficiently
+// balanced.
+void PhaseBlockLayout::merge_traces(bool fall_thru_only)
+{
+  // Walk the edge list a another time, looking at unprocessed edges.
+  // Fold in diamonds
+  for (int i = 0; i < edges->length(); i++) {
+    CFGEdge *e = edges->at(i);
+
+    if (e->state() != CFGEdge::open) continue;
+    if (fall_thru_only) {
+      if (e->infrequent()) continue;
+    }
+
+    Block *src_block = e->from();
+    Trace *src_trace = trace(src_block);
+    bool src_at_tail = src_trace->last_block() == src_block;
+
+    Block *targ_block  = e->to();
+    Trace *targ_trace  = trace(targ_block);
+    bool targ_at_start = targ_trace->first_block() == targ_block;
+
+    if (src_trace == targ_trace) {
+      // This may be a loop, but we can't do much about it.
+      e->set_state(CFGEdge::interior);
+      continue;
+    }
+
+    if (fall_thru_only) {
+      // If the edge links the middle of two traces, we can't do anything.
+      // Mark the edge and continue.
+      if (!src_at_tail & !targ_at_start) {
+        continue;
+      }
+
+      // Don't grow traces along backedges?
+      if (!BlockLayoutRotateLoops && (targ_block->_rpo <= src_block->_rpo)) {
+          continue;
+      }
+
+      // If both ends of the edge are available, why didn't we handle it earlier?
+      assert(src_at_tail ^ targ_at_start, "Should have caught this edge earlier.");
+
+      if (targ_at_start) {
+        // Insert the "targ" trace in the "src" trace if the insertion point
+        // is a two way branch.
+        // Better profitability check possible, but may not be worth it.
+        // Someday, see if the this "fork" has an associated "join";
+        // then make a policy on merging this trace at the fork or join.
+        // For example, other things being equal, it may be better to place this
+        // trace at the join point if the "src" trace ends in a two-way, but
+        // the insertion point is one-way.
+        assert(src_block->num_fall_throughs() == 2, "unexpected diamond");
+        e->set_state(CFGEdge::connected);
+        src_trace->insert_after(src_block, targ_trace);
+        union_traces(src_trace, targ_trace);
+      } else if (src_at_tail) {
+        if (src_trace != trace(_cfg._broot)) {
+          e->set_state(CFGEdge::connected);
+          targ_trace->insert_before(targ_block, src_trace);
+          union_traces(targ_trace, src_trace);
+        }
+      }
+    } else if (e->state() == CFGEdge::open) {
+      // Append traces, even without a fall-thru connection.
+      // But leave root entry at the begining of the block list.
+      if (targ_trace != trace(_cfg._broot)) {
+        e->set_state(CFGEdge::connected);
+        src_trace->append(targ_trace);
+        union_traces(src_trace, targ_trace);
+      }
+    }
+  }
+}
+
+//----------------------------reorder_traces-----------------------------------
+// Order the sequence of the traces in some desirable way, and fixup the
+// jumps at the end of each block.
+void PhaseBlockLayout::reorder_traces(int count)
+{
+  ResourceArea *area = Thread::current()->resource_area();
+  Trace ** new_traces = NEW_ARENA_ARRAY(area, Trace *, count);
+  Block_List worklist;
+  int new_count = 0;
+
+  // Compact the traces.
+  for (int i = 0; i < count; i++) {
+    Trace *tr = traces[i];
+    if (tr != NULL) {
+      new_traces[new_count++] = tr;
+    }
+  }
+
+  // The entry block should be first on the new trace list.
+  Trace *tr = trace(_cfg._broot);
+  assert(tr == new_traces[0], "entry trace misplaced");
+
+  // Sort the new trace list by frequency
+  qsort(new_traces + 1, new_count - 1, sizeof(new_traces[0]), trace_frequency_order);
+
+  // Patch up the successor blocks
+  _cfg._blocks.reset();
+  _cfg._num_blocks = 0;
+  for (int i = 0; i < new_count; i++) {
+    Trace *tr = new_traces[i];
+    if (tr != NULL) {
+      tr->fixup_blocks(_cfg);
+    }
+  }
+}
+
+//------------------------------PhaseBlockLayout-------------------------------
+// Order basic blocks based on frequency
+PhaseBlockLayout::PhaseBlockLayout(PhaseCFG &cfg) :
+  Phase(BlockLayout),
+  _cfg(cfg)
+{
+  ResourceMark rm;
+  ResourceArea *area = Thread::current()->resource_area();
+
+  // List of traces
+  int size = _cfg._num_blocks + 1;
+  traces = NEW_ARENA_ARRAY(area, Trace *, size);
+  memset(traces, 0, size*sizeof(Trace*));
+  next = NEW_ARENA_ARRAY(area, Block *, size);
+  memset(next,   0, size*sizeof(Block *));
+  prev = NEW_ARENA_ARRAY(area, Block *, size);
+  memset(prev  , 0, size*sizeof(Block *));
+
+  // List of edges
+  edges = new GrowableArray<CFGEdge*>;
+
+  // Mapping block index --> block_trace
+  uf = new UnionFind(size);
+  uf->reset(size);
+
+  // Find edges and create traces.
+  find_edges();
+
+  // Grow traces at their ends via most frequent edges.
+  grow_traces();
+
+  // Merge one trace into another, but only at fall-through points.
+  // This may make diamonds and other related shapes in a trace.
+  merge_traces(true);
+
+  // Run merge again, allowing two traces to be catenated, even if
+  // one does not fall through into the other. This appends loosely
+  // related traces to be near each other.
+  merge_traces(false);
+
+  // Re-order all the remaining traces by frequency
+  reorder_traces(size);
+
+  assert(_cfg._num_blocks >= (uint) (size - 1), "number of blocks can not shrink");
+}
+
+
+//------------------------------backedge---------------------------------------
+// Edge e completes a loop in a trace. If the target block is head of the
+// loop, rotate the loop block so that the loop ends in a conditional branch.
+bool Trace::backedge(CFGEdge *e) {
+  bool loop_rotated = false;
+  Block *src_block  = e->from();
+  Block *targ_block    = e->to();
+
+  assert(last_block() == src_block, "loop discovery at back branch");
+  if (first_block() == targ_block) {
+    if (BlockLayoutRotateLoops && last_block()->num_fall_throughs() < 2) {
+      // Find the last block in the trace that has a conditional
+      // branch.
+      Block *b;
+      for (b = last_block(); b != NULL; b = prev(b)) {
+        if (b->num_fall_throughs() == 2) {
+          break;
+        }
+      }
+
+      if (b != last_block() && b != NULL) {
+        loop_rotated = true;
+
+        // Rotate the loop by doing two-part linked-list surgery.
+        append(first_block());
+        break_loop_after(b);
+      }
+    }
+
+    // Backbranch to the top of a trace
+    // Scroll foward through the trace from the targ_block. If we find
+    // a loop head before another loop top, use the the loop head alignment.
+    for (Block *b = targ_block; b != NULL; b = next(b)) {
+      if (b->has_loop_alignment()) {
+        break;
+      }
+      if (b->head()->is_Loop()) {
+        targ_block = b;
+        break;
+      }
+    }
+
+    first_block()->set_loop_alignment(targ_block);
+
+  } else {
+    // Backbranch into the middle of a trace
+    targ_block->set_loop_alignment(targ_block);
+  }
+
+  return loop_rotated;
+}
+
+//------------------------------fixup_blocks-----------------------------------
+// push blocks onto the CFG list
+// ensure that blocks have the correct two-way branch sense
+void Trace::fixup_blocks(PhaseCFG &cfg) {
+  Block *last = last_block();
+  for (Block *b = first_block(); b != NULL; b = next(b)) {
+    cfg._blocks.push(b);
+    cfg._num_blocks++;
+    if (!b->is_connector()) {
+      int nfallthru = b->num_fall_throughs();
+      if (b != last) {
+        if (nfallthru == 2) {
+          // Ensure that the sense of the branch is correct
+          Block *bnext = next(b);
+          Block *bs0 = b->non_connector_successor(0);
+
+          MachNode *iff = b->_nodes[b->_nodes.size()-3]->as_Mach();
+          ProjNode *proj0 = b->_nodes[b->_nodes.size()-2]->as_Proj();
+          ProjNode *proj1 = b->_nodes[b->_nodes.size()-1]->as_Proj();
+
+          if (bnext == bs0) {
+            // Fall-thru case in succs[0], should be in succs[1]
+
+            // Flip targets in _succs map
+            Block *tbs0 = b->_succs[0];
+            Block *tbs1 = b->_succs[1];
+            b->_succs.map( 0, tbs1 );
+            b->_succs.map( 1, tbs0 );
+
+            // Flip projections to match targets
+            b->_nodes.map(b->_nodes.size()-2, proj1);
+            b->_nodes.map(b->_nodes.size()-1, proj0);
+          }
+        }
+      }
+    }
+  }
+}
--- a/src/share/vm/opto/block.hpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/opto/block.hpp	Thu Dec 04 17:48:02 2008 -0800
@@ -75,6 +75,7 @@
   void insert( uint i, Block *n );
   uint size() const { return _cnt; }
   void reset() { _cnt = 0; }
+  void print();
 };
 
 
@@ -129,7 +130,11 @@
   uint _rpo;                    // Number in reverse post order walk
 
   virtual bool is_block() { return true; }
-  float succ_prob(uint i); // return probability of i'th successor
+  float succ_prob(uint i);      // return probability of i'th successor
+  int num_fall_throughs();      // How many fall-through candidate this block has
+  void update_uncommon_branch(Block* un); // Lower branch prob to uncommon code
+  bool succ_fall_through(uint i); // Is successor "i" is a fall-through candidate
+  Block* lone_fall_through();   // Return lone fall-through Block or null
 
   Block* dom_lca(Block* that);  // Compute LCA in dominator tree.
 #ifdef ASSERT
@@ -144,6 +149,7 @@
   // Report the alignment required by this block.  Must be a power of 2.
   // The previous block will insert nops to get this alignment.
   uint code_alignment();
+  uint compute_loop_alignment();
 
   // BLOCK_FREQUENCY is a sentinel to mark uses of constant block frequencies.
   // It is currently also used to scale such frequencies relative to
@@ -184,11 +190,12 @@
       int current_alignment = current_offset & max_pad;
       if( current_alignment != 0 ) {
         uint padding = (block_alignment-current_alignment) & max_pad;
-        if( !head()->is_Loop() ||
-            padding <= (uint)MaxLoopPad ||
-            first_inst_size() > padding ) {
-          return padding;
+        if( has_loop_alignment() &&
+            padding > (uint)MaxLoopPad &&
+            first_inst_size() <= padding ) {
+          return 0;
         }
+        return padding;
       }
     }
     return 0;
@@ -202,6 +209,21 @@
   void set_connector() { _connector = true; }
   bool is_connector() const { return _connector; };
 
+  // Loop_alignment will be set for blocks which are at the top of loops.
+  // The block layout pass may rotate loops such that the loop head may not
+  // be the sequentially first block of the loop encountered in the linear
+  // list of blocks.  If the layout pass is not run, loop alignment is set
+  // for each block which is the head of a loop.
+  uint _loop_alignment;
+  void set_loop_alignment(Block *loop_top) {
+    uint new_alignment = loop_top->compute_loop_alignment();
+    if (new_alignment > _loop_alignment) {
+      _loop_alignment = new_alignment;
+    }
+  }
+  uint loop_alignment() const { return _loop_alignment; }
+  bool has_loop_alignment() const { return loop_alignment() > 0; }
+
   // Create a new Block with given head Node.
   // Creates the (empty) predecessor arrays.
   Block( Arena *a, Node *headnode )
@@ -219,7 +241,8 @@
       _raise_LCA_mark(0),
       _raise_LCA_visited(0),
       _first_inst_size(999999),
-      _connector(false) {
+      _connector(false),
+      _loop_alignment(0) {
     _nodes.push(headnode);
   }
 
@@ -275,6 +298,16 @@
     return s;
   }
 
+  // Return true if b is a successor of this block
+  bool has_successor(Block* b) const {
+    for (uint i = 0; i < _num_succs; i++ ) {
+      if (non_connector_successor(i) == b) {
+        return true;
+      }
+    }
+    return false;
+  }
+
   // Successor block, after forwarding through connectors
   Block* non_connector_successor(int i) const {
     return _succs[i]->non_connector();
@@ -319,7 +352,6 @@
 
   // I'll need a few machine-specific GotoNodes.  Clone from this one.
   MachNode *_goto;
-  void insert_goto_at(uint block_no, uint succ_no);
 
   Block* insert_anti_dependences(Block* LCA, Node* load, bool verify = false);
   void verify_anti_dependences(Block* LCA, Node* load) {
@@ -379,10 +411,15 @@
   // Compute the instruction global latency with a backwards walk
   void ComputeLatenciesBackwards(VectorSet &visited, Node_List &stack);
 
+  // Set loop alignment
+  void set_loop_alignment();
+
   // Remove empty basic blocks
-  void RemoveEmpty();
-  bool MoveToNext(Block* bx, uint b_index);
-  void MoveToEnd(Block* bx, uint b_index);
+  void remove_empty();
+  void fixup_flow();
+  bool move_to_next(Block* bx, uint b_index);
+  void move_to_end(Block* bx, uint b_index);
+  void insert_goto_at(uint block_no, uint succ_no);
 
   // Check for NeverBranch at block end.  This needs to become a GOTO to the
   // true target.  NeverBranch are treated as a conditional branch that always
@@ -413,7 +450,7 @@
 };
 
 
-//------------------------------UnionFindInfo----------------------------------
+//------------------------------UnionFind--------------------------------------
 // Map Block indices to a block-index for a cfg-cover.
 // Array lookup in the optimized case.
 class UnionFind : public ResourceObj {
@@ -508,3 +545,166 @@
   void dump_tree() const;
 #endif
 };
+
+
+//----------------------------------CFGEdge------------------------------------
+// A edge between two basic blocks that will be embodied by a branch or a
+// fall-through.
+class CFGEdge : public ResourceObj {
+ private:
+  Block * _from;        // Source basic block
+  Block * _to;          // Destination basic block
+  float _freq;          // Execution frequency (estimate)
+  int   _state;
+  bool  _infrequent;
+  int   _from_pct;
+  int   _to_pct;
+
+  // Private accessors
+  int  from_pct() const { return _from_pct; }
+  int  to_pct()   const { return _to_pct;   }
+  int  from_infrequent() const { return from_pct() < BlockLayoutMinDiamondPercentage; }
+  int  to_infrequent()   const { return to_pct()   < BlockLayoutMinDiamondPercentage; }
+
+ public:
+  enum {
+    open,               // initial edge state; unprocessed
+    connected,          // edge used to connect two traces together
+    interior            // edge is interior to trace (could be backedge)
+  };
+
+  CFGEdge(Block *from, Block *to, float freq, int from_pct, int to_pct) :
+    _from(from), _to(to), _freq(freq),
+    _from_pct(from_pct), _to_pct(to_pct), _state(open) {
+    _infrequent = from_infrequent() || to_infrequent();
+  }
+
+  float  freq() const { return _freq; }
+  Block* from() const { return _from; }
+  Block* to  () const { return _to;   }
+  int  infrequent() const { return _infrequent; }
+  int state() const { return _state; }
+
+  void set_state(int state) { _state = state; }
+
+#ifndef PRODUCT
+  void dump( ) const;
+#endif
+};
+
+
+//-----------------------------------Trace-------------------------------------
+// An ordered list of basic blocks.
+class Trace : public ResourceObj {
+ private:
+  uint _id;             // Unique Trace id (derived from initial block)
+  Block ** _next_list;  // Array mapping index to next block
+  Block ** _prev_list;  // Array mapping index to previous block
+  Block * _first;       // First block in the trace
+  Block * _last;        // Last block in the trace
+
+  // Return the block that follows "b" in the trace.
+  Block * next(Block *b) const { return _next_list[b->_pre_order]; }
+  void set_next(Block *b, Block *n) const { _next_list[b->_pre_order] = n; }
+
+  // Return the block that preceeds "b" in the trace.
+  Block * prev(Block *b) const { return _prev_list[b->_pre_order]; }
+  void set_prev(Block *b, Block *p) const { _prev_list[b->_pre_order] = p; }
+
+  // We've discovered a loop in this trace. Reset last to be "b", and first as
+  // the block following "b
+  void break_loop_after(Block *b) {
+    _last = b;
+    _first = next(b);
+    set_prev(_first, NULL);
+    set_next(_last, NULL);
+  }
+
+ public:
+
+  Trace(Block *b, Block **next_list, Block **prev_list) :
+    _first(b),
+    _last(b),
+    _next_list(next_list),
+    _prev_list(prev_list),
+    _id(b->_pre_order) {
+    set_next(b, NULL);
+    set_prev(b, NULL);
+  };
+
+  // Return the id number
+  uint id() const { return _id; }
+  void set_id(uint id) { _id = id; }
+
+  // Return the first block in the trace
+  Block * first_block() const { return _first; }
+
+  // Return the last block in the trace
+  Block * last_block() const { return _last; }
+
+  // Insert a trace in the middle of this one after b
+  void insert_after(Block *b, Trace *tr) {
+    set_next(tr->last_block(), next(b));
+    if (next(b) != NULL) {
+      set_prev(next(b), tr->last_block());
+    }
+
+    set_next(b, tr->first_block());
+    set_prev(tr->first_block(), b);
+
+    if (b == _last) {
+      _last = tr->last_block();
+    }
+  }
+
+  void insert_before(Block *b, Trace *tr) {
+    Block *p = prev(b);
+    assert(p != NULL, "use append instead");
+    insert_after(p, tr);
+  }
+
+  // Append another trace to this one.
+  void append(Trace *tr) {
+    insert_after(_last, tr);
+  }
+
+  // Append a block at the end of this trace
+  void append(Block *b) {
+    set_next(_last, b);
+    set_prev(b, _last);
+    _last = b;
+  }
+
+  // Adjust the the blocks in this trace
+  void fixup_blocks(PhaseCFG &cfg);
+  bool backedge(CFGEdge *e);
+
+#ifndef PRODUCT
+  void dump( ) const;
+#endif
+};
+
+//------------------------------PhaseBlockLayout-------------------------------
+// Rearrange blocks into some canonical order, based on edges and their frequencies
+class PhaseBlockLayout : public Phase {
+  PhaseCFG &_cfg;               // Control flow graph
+
+  GrowableArray<CFGEdge *> *edges;
+  Trace **traces;
+  Block **next;
+  Block **prev;
+  UnionFind *uf;
+
+  // Given a block, find its encompassing Trace
+  Trace * trace(Block *b) {
+    return traces[uf->Find_compress(b->_pre_order)];
+  }
+ public:
+  PhaseBlockLayout(PhaseCFG &cfg);
+
+  void find_edges();
+  void grow_traces();
+  void merge_traces(bool loose_connections);
+  void reorder_traces(int count);
+  void union_traces(Trace* from, Trace* to);
+};
--- a/src/share/vm/opto/c2_globals.hpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/opto/c2_globals.hpp	Thu Dec 04 17:48:02 2008 -0800
@@ -256,10 +256,10 @@
   develop(intx, PrintIdealGraphPort, 4444,                                  \
           "Ideal graph printer to network port")                            \
                                                                             \
-  develop(ccstr, PrintIdealGraphAddress, "127.0.0.1",                       \
+  notproduct(ccstr, PrintIdealGraphAddress, "127.0.0.1",                    \
           "IP address to connect to visualizer")                            \
                                                                             \
-  develop(ccstr, PrintIdealGraphFile, NULL,                                 \
+  notproduct(ccstr, PrintIdealGraphFile, NULL,                              \
           "File to dump ideal graph to.  If set overrides the "             \
           "use of the network")                                             \
                                                                             \
@@ -388,6 +388,9 @@
   product(intx, EliminateAllocationArraySizeLimit, 64,                      \
           "Array size (number of elements) limit for scalar replacement")   \
                                                                             \
+  product(bool, UseOptoBiasInlining, true,                                 \
+          "Generate biased locking code in C2 ideal graph")                 \
+                                                                            \
   product(intx, ValueSearchLimit, 1000,                                     \
           "Recursion limit in PhaseMacroExpand::value_from_mem_phi")        \
                                                                             \
@@ -396,5 +399,15 @@
                                                                             \
   diagnostic(intx, DominatorSearchLimit, 1000,                              \
           "Iterations limit in Node::dominates")                            \
+                                                                            \
+  product(bool, BlockLayoutByFrequency, true,                               \
+          "Use edge frequencies to drive block ordering")                   \
+                                                                            \
+  product(intx, BlockLayoutMinDiamondPercentage, 20,                        \
+          "Miniumum %% of a successor (predecessor) for which block layout "\
+          "a will allow a fork (join) in a single chain")                   \
+                                                                            \
+  product(bool, BlockLayoutRotateLoops, false,                              \
+          "Allow back branches to be fall throughs in the block layour")    \
 
 C2_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_NOTPRODUCT_FLAG)
--- a/src/share/vm/opto/callnode.cpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/opto/callnode.cpp	Thu Dec 04 17:48:02 2008 -0800
@@ -967,6 +967,7 @@
   init_class_id(Class_SafePointScalarObject);
 }
 
+bool SafePointScalarObjectNode::pinned() const { return true; }
 
 uint SafePointScalarObjectNode::ideal_reg() const {
   return 0; // No matching to machine instruction
--- a/src/share/vm/opto/callnode.hpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/opto/callnode.hpp	Thu Dec 04 17:48:02 2008 -0800
@@ -433,6 +433,10 @@
   uint n_fields()    const { return _n_fields; }
   DEBUG_ONLY(AllocateNode* alloc() const { return _alloc; })
 
+  // SafePointScalarObject should be always pinned to the control edge
+  // of the SafePoint node for which it was generated.
+  virtual bool pinned() const; // { return true; }
+
   virtual uint size_of() const { return sizeof(*this); }
 
   // Assumes that "this" is an argument to a safepoint node "s", and that
--- a/src/share/vm/opto/chaitin.cpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/opto/chaitin.cpp	Thu Dec 04 17:48:02 2008 -0800
@@ -440,9 +440,7 @@
   assert((int)(_matcher._new_SP+_framesize) >= (int)_matcher._out_arg_limit, "framesize must be large enough");
 
   // This frame must preserve the required fp alignment
-  const int stack_alignment_in_words = Matcher::stack_alignment_in_slots();
-  if (stack_alignment_in_words > 0)
-    _framesize = round_to(_framesize, Matcher::stack_alignment_in_bytes());
+  _framesize = round_to(_framesize, Matcher::stack_alignment_in_slots());
   assert( _framesize >= 0 && _framesize <= 1000000, "sanity check" );
 #ifndef PRODUCT
   _total_framesize += _framesize;
--- a/src/share/vm/opto/classes.hpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/opto/classes.hpp	Thu Dec 04 17:48:02 2008 -0800
@@ -205,6 +205,7 @@
 macro(StoreC)
 macro(StoreCM)
 macro(StorePConditional)
+macro(StoreIConditional)
 macro(StoreLConditional)
 macro(StoreD)
 macro(StoreF)
--- a/src/share/vm/opto/compile.cpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/opto/compile.cpp	Thu Dec 04 17:48:02 2008 -0800
@@ -551,7 +551,7 @@
       rethrow_exceptions(kit.transfer_exceptions_into_jvms());
     }
 
-    print_method("Before RemoveUseless");
+    print_method("Before RemoveUseless", 3);
 
     // Remove clutter produced by parsing.
     if (!failing()) {
@@ -822,6 +822,7 @@
   Copy::zero_to_bytes(_trap_hist, sizeof(_trap_hist));
   set_decompile_count(0);
 
+  set_do_freq_based_layout(BlockLayoutByFrequency || method_has_option("BlockLayoutByFrequency"));
   // Compilation level related initialization
   if (env()->comp_level() == CompLevel_fast_compile) {
     set_num_loop_opts(Tier1LoopOptsCount);
@@ -1701,8 +1702,14 @@
   // are not adding any new instructions.  If any basic block is empty, we
   // can now safely remove it.
   {
-    NOT_PRODUCT( TracePhase t2("removeEmpty", &_t_removeEmptyBlocks, TimeCompiler); )
-    cfg.RemoveEmpty();
+    NOT_PRODUCT( TracePhase t2("blockOrdering", &_t_blockOrdering, TimeCompiler); )
+    cfg.remove_empty();
+    if (do_freq_based_layout()) {
+      PhaseBlockLayout layout(cfg);
+    } else {
+      cfg.set_loop_alignment();
+    }
+    cfg.fixup_flow();
   }
 
   // Perform any platform dependent postallocation verifications.
@@ -1994,6 +2001,7 @@
   case Op_StorePConditional:
   case Op_StoreI:
   case Op_StoreL:
+  case Op_StoreIConditional:
   case Op_StoreLConditional:
   case Op_CompareAndSwapI:
   case Op_CompareAndSwapL:
--- a/src/share/vm/opto/compile.hpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/opto/compile.hpp	Thu Dec 04 17:48:02 2008 -0800
@@ -154,6 +154,7 @@
   uint                  _decompile_count;       // Cumulative decompilation counts.
   bool                  _do_inlining;           // True if we intend to do inlining
   bool                  _do_scheduling;         // True if we intend to do scheduling
+  bool                  _do_freq_based_layout;  // True if we intend to do frequency based block layout
   bool                  _do_count_invocations;  // True if we generate code to count invocations
   bool                  _do_method_data_update; // True if we generate code to update methodDataOops
   int                   _AliasLevel;            // Locally-adjusted version of AliasLevel flag.
@@ -307,6 +308,8 @@
   void          set_do_inlining(bool z)         { _do_inlining = z; }
   bool              do_scheduling() const       { return _do_scheduling; }
   void          set_do_scheduling(bool z)       { _do_scheduling = z; }
+  bool              do_freq_based_layout() const{ return _do_freq_based_layout; }
+  void          set_do_freq_based_layout(bool z){ _do_freq_based_layout = z; }
   bool              do_count_invocations() const{ return _do_count_invocations; }
   void          set_do_count_invocations(bool z){ _do_count_invocations = z; }
   bool              do_method_data_update() const { return _do_method_data_update; }
--- a/src/share/vm/opto/gcm.cpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/opto/gcm.cpp	Thu Dec 04 17:48:02 2008 -0800
@@ -1319,11 +1319,33 @@
 //------------------------------Estimate_Block_Frequency-----------------------
 // Estimate block frequencies based on IfNode probabilities.
 void PhaseCFG::Estimate_Block_Frequency() {
-  int cnts = C->method() ? C->method()->interpreter_invocation_count() : 1;
-  // Most of our algorithms will die horribly if frequency can become
-  // negative so make sure cnts is a sane value.
-  if( cnts <= 0 ) cnts = 1;
-  float f = (float)cnts/(float)FreqCountInvocations;
+
+  // Force conditional branches leading to uncommon traps to be unlikely,
+  // not because we get to the uncommon_trap with less relative frequency,
+  // but because an uncommon_trap typically causes a deopt, so we only get
+  // there once.
+  if (C->do_freq_based_layout()) {
+    Block_List worklist;
+    Block* root_blk = _blocks[0];
+    for (uint i = 1; i < root_blk->num_preds(); i++) {
+      Block *pb = _bbs[root_blk->pred(i)->_idx];
+      if (pb->has_uncommon_code()) {
+        worklist.push(pb);
+      }
+    }
+    while (worklist.size() > 0) {
+      Block* uct = worklist.pop();
+      if (uct == _broot) continue;
+      for (uint i = 1; i < uct->num_preds(); i++) {
+        Block *pb = _bbs[uct->pred(i)->_idx];
+        if (pb->_num_succs == 1) {
+          worklist.push(pb);
+        } else if (pb->num_fall_throughs() == 2) {
+          pb->update_uncommon_branch(uct);
+        }
+      }
+    }
+  }
 
   // Create the loop tree and calculate loop depth.
   _root_loop = create_loop_tree();
@@ -1333,25 +1355,27 @@
   _root_loop->compute_freq();
 
   // Adjust all frequencies to be relative to a single method entry
-  _root_loop->_freq = f * 1.0;
+  _root_loop->_freq = 1.0;
   _root_loop->scale_freq();
 
   // force paths ending at uncommon traps to be infrequent
-  Block_List worklist;
-  Block* root_blk = _blocks[0];
-  for (uint i = 0; i < root_blk->num_preds(); i++) {
-    Block *pb = _bbs[root_blk->pred(i)->_idx];
-    if (pb->has_uncommon_code()) {
-      worklist.push(pb);
+  if (!C->do_freq_based_layout()) {
+    Block_List worklist;
+    Block* root_blk = _blocks[0];
+    for (uint i = 1; i < root_blk->num_preds(); i++) {
+      Block *pb = _bbs[root_blk->pred(i)->_idx];
+      if (pb->has_uncommon_code()) {
+        worklist.push(pb);
+      }
     }
-  }
-  while (worklist.size() > 0) {
-    Block* uct = worklist.pop();
-    uct->_freq = PROB_MIN;
-    for (uint i = 0; i < uct->num_preds(); i++) {
-      Block *pb = _bbs[uct->pred(i)->_idx];
-      if (pb->_num_succs == 1 && pb->_freq > PROB_MIN) {
-        worklist.push(pb);
+    while (worklist.size() > 0) {
+      Block* uct = worklist.pop();
+      uct->_freq = PROB_MIN;
+      for (uint i = 1; i < uct->num_preds(); i++) {
+        Block *pb = _bbs[uct->pred(i)->_idx];
+        if (pb->_num_succs == 1 && pb->_freq > PROB_MIN) {
+          worklist.push(pb);
+        }
       }
     }
   }
@@ -1556,22 +1580,6 @@
     }
   }
 
-#if 0
-  // Raise frequency of the loop backedge block, in an effort
-  // to keep it empty.  Skip the method level "loop".
-  if (_parent != NULL) {
-    CFGElement* s = _members.at(_members.length() - 1);
-    if (s->is_block()) {
-      Block* bk = s->as_Block();
-      if (bk->_num_succs == 1 && bk->_succs[0] == hd) {
-        // almost any value >= 1.0f works
-        // FIXME: raw constant
-        bk->_freq = 1.05f;
-      }
-    }
-  }
-#endif
-
   // For all loops other than the outer, "method" loop,
   // sum and normalize the exit probability. The "method" loop
   // should keep the initial exit probability of 1, so that
@@ -1589,12 +1597,15 @@
     // the probability of exit per loop entry.
     for (int i = 0; i < _exits.length(); i++) {
       Block* et = _exits.at(i).get_target();
-      float new_prob = _exits.at(i).get_prob() / exits_sum;
+      float new_prob = 0.0f;
+      if (_exits.at(i).get_prob() > 0.0f) {
+        new_prob = _exits.at(i).get_prob() / exits_sum;
+      }
       BlockProbPair bpp(et, new_prob);
       _exits.at_put(i, bpp);
     }
 
-    // Save the total, but guard against unreasoable probability,
+    // Save the total, but guard against unreasonable probability,
     // as the value is used to estimate the loop trip count.
     // An infinite trip count would blur relative block
     // frequencies.
@@ -1688,6 +1699,137 @@
   return 0.0f;
 }
 
+//------------------------------num_fall_throughs-----------------------------
+// Return the number of fall-through candidates for a block
+int Block::num_fall_throughs() {
+  int eidx = end_idx();
+  Node *n = _nodes[eidx];  // Get ending Node
+
+  int op = n->Opcode();
+  if (n->is_Mach()) {
+    if (n->is_MachNullCheck()) {
+      // In theory, either side can fall-thru, for simplicity sake,
+      // let's say only the false branch can now.
+      return 1;
+    }
+    op = n->as_Mach()->ideal_Opcode();
+  }
+
+  // Switch on branch type
+  switch( op ) {
+  case Op_CountedLoopEnd:
+  case Op_If:
+    return 2;
+
+  case Op_Root:
+  case Op_Goto:
+    return 1;
+
+  case Op_Catch: {
+    for (uint i = 0; i < _num_succs; i++) {
+      const CatchProjNode *ci = _nodes[i + eidx + 1]->as_CatchProj();
+      if (ci->_con == CatchProjNode::fall_through_index) {
+        return 1;
+      }
+    }
+    return 0;
+  }
+
+  case Op_Jump:
+  case Op_NeverBranch:
+  case Op_TailCall:
+  case Op_TailJump:
+  case Op_Return:
+  case Op_Halt:
+  case Op_Rethrow:
+    return 0;
+
+  default:
+    ShouldNotReachHere();
+  }
+
+  return 0;
+}
+
+//------------------------------succ_fall_through-----------------------------
+// Return true if a specific successor could be fall-through target.
+bool Block::succ_fall_through(uint i) {
+  int eidx = end_idx();
+  Node *n = _nodes[eidx];  // Get ending Node
+
+  int op = n->Opcode();
+  if (n->is_Mach()) {
+    if (n->is_MachNullCheck()) {
+      // In theory, either side can fall-thru, for simplicity sake,
+      // let's say only the false branch can now.
+      return _nodes[i + eidx + 1]->Opcode() == Op_IfFalse;
+    }
+    op = n->as_Mach()->ideal_Opcode();
+  }
+
+  // Switch on branch type
+  switch( op ) {
+  case Op_CountedLoopEnd:
+  case Op_If:
+  case Op_Root:
+  case Op_Goto:
+    return true;
+
+  case Op_Catch: {
+    const CatchProjNode *ci = _nodes[i + eidx + 1]->as_CatchProj();
+    return ci->_con == CatchProjNode::fall_through_index;
+  }
+
+  case Op_Jump:
+  case Op_NeverBranch:
+  case Op_TailCall:
+  case Op_TailJump:
+  case Op_Return:
+  case Op_Halt:
+  case Op_Rethrow:
+    return false;
+
+  default:
+    ShouldNotReachHere();
+  }
+
+  return false;
+}
+
+//------------------------------update_uncommon_branch------------------------
+// Update the probability of a two-branch to be uncommon
+void Block::update_uncommon_branch(Block* ub) {
+  int eidx = end_idx();
+  Node *n = _nodes[eidx];  // Get ending Node
+
+  int op = n->as_Mach()->ideal_Opcode();
+
+  assert(op == Op_CountedLoopEnd || op == Op_If, "must be a If");
+  assert(num_fall_throughs() == 2, "must be a two way branch block");
+
+  // Which successor is ub?
+  uint s;
+  for (s = 0; s <_num_succs; s++) {
+    if (_succs[s] == ub) break;
+  }
+  assert(s < 2, "uncommon successor must be found");
+
+  // If ub is the true path, make the proability small, else
+  // ub is the false path, and make the probability large
+  bool invert = (_nodes[s + eidx + 1]->Opcode() == Op_IfFalse);
+
+  // Get existing probability
+  float p = n->as_MachIf()->_prob;
+
+  if (invert) p = 1.0 - p;
+  if (p > PROB_MIN) {
+    p = PROB_MIN;
+  }
+  if (invert) p = 1.0 - p;
+
+  n->as_MachIf()->_prob = p;
+}
+
 //------------------------------update_succ_freq-------------------------------
 // Update the appropriate frequency associated with block 'b', a succesor of
 // a block in this loop.
--- a/src/share/vm/opto/library_call.cpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/opto/library_call.cpp	Thu Dec 04 17:48:02 2008 -0800
@@ -3485,11 +3485,32 @@
   const TypePtr *adr_type = _gvn.type(adr)->is_ptr();
   int alias_idx = C->get_alias_index(adr_type);
 
-  Node *result = _gvn.transform(new (C, 5) StoreLConditionalNode(control(), memory(alias_idx), adr, newVal, oldVal));
-  Node *store_proj = _gvn.transform( new (C, 1) SCMemProjNode(result));
+  Node *cas = _gvn.transform(new (C, 5) StoreLConditionalNode(control(), memory(alias_idx), adr, newVal, oldVal));
+  Node *store_proj = _gvn.transform( new (C, 1) SCMemProjNode(cas));
   set_memory(store_proj, alias_idx);
-
-  push(result);
+  Node *bol = _gvn.transform( new (C, 2) BoolNode( cas, BoolTest::eq ) );
+
+  Node *result;
+  // CMove node is not used to be able fold a possible check code
+  // after attemptUpdate() call. This code could be transformed
+  // into CMove node by loop optimizations.
+  {
+    RegionNode *r = new (C, 3) RegionNode(3);
+    result = new (C, 3) PhiNode(r, TypeInt::BOOL);
+
+    Node *iff = create_and_xform_if(control(), bol, PROB_FAIR, COUNT_UNKNOWN);
+    Node *iftrue = opt_iff(r, iff);
+    r->init_req(1, iftrue);
+    result->init_req(1, intcon(1));
+    result->init_req(2, intcon(0));
+
+    set_control(_gvn.transform(r));
+    record_for_igvn(r);
+
+    C->set_has_split_ifs(true); // Has chance for split-if optimization
+  }
+
+  push(_gvn.transform(result));
   return true;
 }
 
--- a/src/share/vm/opto/loopTransform.cpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/opto/loopTransform.cpp	Thu Dec 04 17:48:02 2008 -0800
@@ -1519,6 +1519,7 @@
         Node *bol = iff->in(1);
         if( bol && bol->req() > 1 && bol->in(1) &&
             ((bol->in(1)->Opcode() == Op_StorePConditional ) ||
+             (bol->in(1)->Opcode() == Op_StoreIConditional ) ||
              (bol->in(1)->Opcode() == Op_StoreLConditional ) ||
              (bol->in(1)->Opcode() == Op_CompareAndSwapI ) ||
              (bol->in(1)->Opcode() == Op_CompareAndSwapL ) ||
--- a/src/share/vm/opto/macro.cpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/opto/macro.cpp	Thu Dec 04 17:48:02 2008 -0800
@@ -82,16 +82,31 @@
   }
 }
 
-Node* PhaseMacroExpand::opt_iff(Node* region, Node* iff) {
-  IfNode *opt_iff = transform_later(iff)->as_If();
+Node* PhaseMacroExpand::opt_bits_test(Node* ctrl, Node* region, int edge, Node* word, int mask, int bits, bool return_fast_path) {
+  Node* cmp;
+  if (mask != 0) {
+    Node* and_node = transform_later(new (C, 3) AndXNode(word, MakeConX(mask)));
+    cmp = transform_later(new (C, 3) CmpXNode(and_node, MakeConX(bits)));
+  } else {
+    cmp = word;
+  }
+  Node* bol = transform_later(new (C, 2) BoolNode(cmp, BoolTest::ne));
+  IfNode* iff = new (C, 2) IfNode( ctrl, bol, PROB_MIN, COUNT_UNKNOWN );
+  transform_later(iff);
 
-  // Fast path taken; set region slot 2
-  Node *fast_taken = transform_later( new (C, 1) IfFalseNode(opt_iff) );
-  region->init_req(2,fast_taken); // Capture fast-control
+  // Fast path taken.
+  Node *fast_taken = transform_later( new (C, 1) IfFalseNode(iff) );
 
   // Fast path not-taken, i.e. slow path
-  Node *slow_taken = transform_later( new (C, 1) IfTrueNode(opt_iff) );
-  return slow_taken;
+  Node *slow_taken = transform_later( new (C, 1) IfTrueNode(iff) );
+
+  if (return_fast_path) {
+    region->init_req(edge, slow_taken); // Capture slow-control
+    return fast_taken;
+  } else {
+    region->init_req(edge, fast_taken); // Capture fast-control
+    return slow_taken;
+  }
 }
 
 //--------------------copy_predefined_input_for_runtime_call--------------------
@@ -854,7 +869,7 @@
 
 Node* PhaseMacroExpand::make_load(Node* ctl, Node* mem, Node* base, int offset, const Type* value_type, BasicType bt) {
   Node* adr = basic_plus_adr(base, offset);
-  const TypePtr* adr_type = TypeRawPtr::BOTTOM;
+  const TypePtr* adr_type = adr->bottom_type()->is_ptr();
   Node* value = LoadNode::make(_igvn, ctl, mem, adr, adr_type, value_type, bt);
   transform_later(value);
   return value;
@@ -1583,12 +1598,193 @@
   Node* flock = lock->fastlock_node();
 
   // Make the merge point
-  Node *region = new (C, 3) RegionNode(3);
+  Node *region;
+  Node *mem_phi;
+  Node *slow_path;
 
-  Node *bol = transform_later(new (C, 2) BoolNode(flock,BoolTest::ne));
-  Node *iff = new (C, 2) IfNode( ctrl, bol, PROB_MIN, COUNT_UNKNOWN );
-  // Optimize test; set region slot 2
-  Node *slow_path = opt_iff(region,iff);
+  if (UseOptoBiasInlining) {
+    /*
+     *  See the full descrition in MacroAssembler::biased_locking_enter().
+     *
+     *  if( (mark_word & biased_lock_mask) == biased_lock_pattern ) {
+     *    // The object is biased.
+     *    proto_node = klass->prototype_header;
+     *    o_node = thread | proto_node;
+     *    x_node = o_node ^ mark_word;
+     *    if( (x_node & ~age_mask) == 0 ) { // Biased to the current thread ?
+     *      // Done.
+     *    } else {
+     *      if( (x_node & biased_lock_mask) != 0 ) {
+     *        // The klass's prototype header is no longer biased.
+     *        cas(&mark_word, mark_word, proto_node)
+     *        goto cas_lock;
+     *      } else {
+     *        // The klass's prototype header is still biased.
+     *        if( (x_node & epoch_mask) != 0 ) { // Expired epoch?
+     *          old = mark_word;
+     *          new = o_node;
+     *        } else {
+     *          // Different thread or anonymous biased.
+     *          old = mark_word & (epoch_mask | age_mask | biased_lock_mask);
+     *          new = thread | old;
+     *        }
+     *        // Try to rebias.
+     *        if( cas(&mark_word, old, new) == 0 ) {
+     *          // Done.
+     *        } else {
+     *          goto slow_path; // Failed.
+     *        }
+     *      }
+     *    }
+     *  } else {
+     *    // The object is not biased.
+     *    cas_lock:
+     *    if( FastLock(obj) == 0 ) {
+     *      // Done.
+     *    } else {
+     *      slow_path:
+     *      OptoRuntime::complete_monitor_locking_Java(obj);
+     *    }
+     *  }
+     */
+
+    region  = new (C, 5) RegionNode(5);
+    // create a Phi for the memory state
+    mem_phi = new (C, 5) PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM);
+
+    Node* fast_lock_region  = new (C, 3) RegionNode(3);
+    Node* fast_lock_mem_phi = new (C, 3) PhiNode( fast_lock_region, Type::MEMORY, TypeRawPtr::BOTTOM);
+
+    // First, check mark word for the biased lock pattern.
+    Node* mark_node = make_load(ctrl, mem, obj, oopDesc::mark_offset_in_bytes(), TypeX_X, TypeX_X->basic_type());
+
+    // Get fast path - mark word has the biased lock pattern.
+    ctrl = opt_bits_test(ctrl, fast_lock_region, 1, mark_node,
+                         markOopDesc::biased_lock_mask_in_place,
+                         markOopDesc::biased_lock_pattern, true);
+    // fast_lock_region->in(1) is set to slow path.
+    fast_lock_mem_phi->init_req(1, mem);
+
+    // Now check that the lock is biased to the current thread and has
+    // the same epoch and bias as Klass::_prototype_header.
+
+    // Special-case a fresh allocation to avoid building nodes:
+    Node* klass_node = AllocateNode::Ideal_klass(obj, &_igvn);
+    if (klass_node == NULL) {
+      Node* k_adr = basic_plus_adr(obj, oopDesc::klass_offset_in_bytes());
+      klass_node = transform_later( LoadKlassNode::make(_igvn, mem, k_adr, _igvn.type(k_adr)->is_ptr()) );
+    }
+    Node *proto_node = make_load(ctrl, mem, klass_node, Klass::prototype_header_offset_in_bytes() + sizeof(oopDesc), TypeX_X, TypeX_X->basic_type());
+
+    Node* thread = transform_later(new (C, 1) ThreadLocalNode());
+    Node* cast_thread = transform_later(new (C, 2) CastP2XNode(ctrl, thread));
+    Node* o_node = transform_later(new (C, 3) OrXNode(cast_thread, proto_node));
+    Node* x_node = transform_later(new (C, 3) XorXNode(o_node, mark_node));
+
+    // Get slow path - mark word does NOT match the value.
+    Node* not_biased_ctrl =  opt_bits_test(ctrl, region, 3, x_node,
+                                      (~markOopDesc::age_mask_in_place), 0);
+    // region->in(3) is set to fast path - the object is biased to the current thread.
+    mem_phi->init_req(3, mem);
+
+
+    // Mark word does NOT match the value (thread | Klass::_prototype_header).
+
+
+    // First, check biased pattern.
+    // Get fast path - _prototype_header has the same biased lock pattern.
+    ctrl =  opt_bits_test(not_biased_ctrl, fast_lock_region, 2, x_node,
+                          markOopDesc::biased_lock_mask_in_place, 0, true);
+
+    not_biased_ctrl = fast_lock_region->in(2); // Slow path
+    // fast_lock_region->in(2) - the prototype header is no longer biased
+    // and we have to revoke the bias on this object.
+    // We are going to try to reset the mark of this object to the prototype
+    // value and fall through to the CAS-based locking scheme.
+    Node* adr = basic_plus_adr(obj, oopDesc::mark_offset_in_bytes());
+    Node* cas = new (C, 5) StoreXConditionalNode(not_biased_ctrl, mem, adr,
+                                                 proto_node, mark_node);
+    transform_later(cas);
+    Node* proj = transform_later( new (C, 1) SCMemProjNode(cas));
+    fast_lock_mem_phi->init_req(2, proj);
+
+
+    // Second, check epoch bits.
+    Node* rebiased_region  = new (C, 3) RegionNode(3);
+    Node* old_phi = new (C, 3) PhiNode( rebiased_region, TypeX_X);
+    Node* new_phi = new (C, 3) PhiNode( rebiased_region, TypeX_X);
+
+    // Get slow path - mark word does NOT match epoch bits.
+    Node* epoch_ctrl =  opt_bits_test(ctrl, rebiased_region, 1, x_node,
+                                      markOopDesc::epoch_mask_in_place, 0);
+    // The epoch of the current bias is not valid, attempt to rebias the object
+    // toward the current thread.
+    rebiased_region->init_req(2, epoch_ctrl);
+    old_phi->init_req(2, mark_node);
+    new_phi->init_req(2, o_node);
+
+    // rebiased_region->in(1) is set to fast path.
+    // The epoch of the current bias is still valid but we know
+    // nothing about the owner; it might be set or it might be clear.
+    Node* cmask   = MakeConX(markOopDesc::biased_lock_mask_in_place |
+                             markOopDesc::age_mask_in_place |
+                             markOopDesc::epoch_mask_in_place);
+    Node* old = transform_later(new (C, 3) AndXNode(mark_node, cmask));
+    cast_thread = transform_later(new (C, 2) CastP2XNode(ctrl, thread));
+    Node* new_mark = transform_later(new (C, 3) OrXNode(cast_thread, old));
+    old_phi->init_req(1, old);
+    new_phi->init_req(1, new_mark);
+
+    transform_later(rebiased_region);
+    transform_later(old_phi);
+    transform_later(new_phi);
+
+    // Try to acquire the bias of the object using an atomic operation.
+    // If this fails we will go in to the runtime to revoke the object's bias.
+    cas = new (C, 5) StoreXConditionalNode(rebiased_region, mem, adr,
+                                           new_phi, old_phi);
+    transform_later(cas);
+    proj = transform_later( new (C, 1) SCMemProjNode(cas));
+
+    // Get slow path - Failed to CAS.
+    not_biased_ctrl = opt_bits_test(rebiased_region, region, 4, cas, 0, 0);
+    mem_phi->init_req(4, proj);
+    // region->in(4) is set to fast path - the object is rebiased to the current thread.
+
+    // Failed to CAS.
+    slow_path  = new (C, 3) RegionNode(3);
+    Node *slow_mem = new (C, 3) PhiNode( slow_path, Type::MEMORY, TypeRawPtr::BOTTOM);
+
+    slow_path->init_req(1, not_biased_ctrl); // Capture slow-control
+    slow_mem->init_req(1, proj);
+
+    // Call CAS-based locking scheme (FastLock node).
+
+    transform_later(fast_lock_region);
+    transform_later(fast_lock_mem_phi);
+
+    // Get slow path - FastLock failed to lock the object.
+    ctrl = opt_bits_test(fast_lock_region, region, 2, flock, 0, 0);
+    mem_phi->init_req(2, fast_lock_mem_phi);
+    // region->in(2) is set to fast path - the object is locked to the current thread.
+
+    slow_path->init_req(2, ctrl); // Capture slow-control
+    slow_mem->init_req(2, fast_lock_mem_phi);
+
+    transform_later(slow_path);
+    transform_later(slow_mem);
+    // Reset lock's memory edge.
+    lock->set_req(TypeFunc::Memory, slow_mem);
+
+  } else {
+    region  = new (C, 3) RegionNode(3);
+    // create a Phi for the memory state
+    mem_phi = new (C, 3) PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM);
+
+    // Optimize test; set region slot 2
+    slow_path = opt_bits_test(ctrl, region, 2, flock, 0, 0);
+    mem_phi->init_req(2, mem);
+  }
 
   // Make slow path call
   CallNode *call = make_slow_call( (CallNode *) lock, OptoRuntime::complete_monitor_enter_Type(), OptoRuntime::complete_monitor_locking_Java(), NULL, slow_path, obj, box );
@@ -1614,16 +1810,11 @@
   transform_later(region);
   _igvn.subsume_node(_fallthroughproj, region);
 
-  // create a Phi for the memory state
-  Node *mem_phi = new (C, 3) PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM);
-  Node *memproj = transform_later( new (C, 1) ProjNode(call, TypeFunc::Memory) );
+  Node *memproj = transform_later( new(C, 1) ProjNode(call, TypeFunc::Memory) );
   mem_phi->init_req(1, memproj );
-  mem_phi->init_req(2, mem);
   transform_later(mem_phi);
-    _igvn.hash_delete(_memproj_fallthrough);
+  _igvn.hash_delete(_memproj_fallthrough);
   _igvn.subsume_node(_memproj_fallthrough, mem_phi);
-
-
 }
 
 //------------------------------expand_unlock_node----------------------
@@ -1637,14 +1828,31 @@
   // No need for a null check on unlock
 
   // Make the merge point
-  RegionNode *region = new (C, 3) RegionNode(3);
+  Node *region;
+  Node *mem_phi;
+
+  if (UseOptoBiasInlining) {
+    // Check for biased locking unlock case, which is a no-op.
+    // See the full descrition in MacroAssembler::biased_locking_exit().
+    region  = new (C, 4) RegionNode(4);
+    // create a Phi for the memory state
+    mem_phi = new (C, 4) PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM);
+    mem_phi->init_req(3, mem);
+
+    Node* mark_node = make_load(ctrl, mem, obj, oopDesc::mark_offset_in_bytes(), TypeX_X, TypeX_X->basic_type());
+    ctrl = opt_bits_test(ctrl, region, 3, mark_node,
+                         markOopDesc::biased_lock_mask_in_place,
+                         markOopDesc::biased_lock_pattern);
+  } else {
+    region  = new (C, 3) RegionNode(3);
+    // create a Phi for the memory state
+    mem_phi = new (C, 3) PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM);
+  }
 
   FastUnlockNode *funlock = new (C, 3) FastUnlockNode( ctrl, obj, box );
   funlock = transform_later( funlock )->as_FastUnlock();
-  Node *bol = transform_later(new (C, 2) BoolNode(funlock,BoolTest::ne));
-  Node *iff = new (C, 2) IfNode( ctrl, bol, PROB_MIN, COUNT_UNKNOWN );
   // Optimize test; set region slot 2
-  Node *slow_path = opt_iff(region,iff);
+  Node *slow_path = opt_bits_test(ctrl, region, 2, funlock, 0, 0);
 
   CallNode *call = make_slow_call( (CallNode *) unlock, OptoRuntime::complete_monitor_exit_Type(), CAST_FROM_FN_PTR(address, SharedRuntime::complete_monitor_unlocking_C), "complete_monitor_unlocking_C", slow_path, obj, box );
 
@@ -1666,16 +1874,12 @@
   transform_later(region);
   _igvn.subsume_node(_fallthroughproj, region);
 
-  // create a Phi for the memory state
-  Node *mem_phi = new (C, 3) PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM);
   Node *memproj = transform_later( new(C, 1) ProjNode(call, TypeFunc::Memory) );
   mem_phi->init_req(1, memproj );
   mem_phi->init_req(2, mem);
   transform_later(mem_phi);
-    _igvn.hash_delete(_memproj_fallthrough);
+  _igvn.hash_delete(_memproj_fallthrough);
   _igvn.subsume_node(_memproj_fallthrough, mem_phi);
-
-
 }
 
 //------------------------------expand_macro_nodes----------------------
--- a/src/share/vm/opto/macro.hpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/opto/macro.hpp	Thu Dec 04 17:48:02 2008 -0800
@@ -93,7 +93,7 @@
 
   int replace_input(Node *use, Node *oldref, Node *newref);
   void copy_call_debug_info(CallNode *oldcall, CallNode * newcall);
-  Node* opt_iff(Node* region, Node* iff);
+  Node* opt_bits_test(Node* ctrl, Node* region, int edge, Node* word, int mask, int bits, bool return_fast_path = false);
   void copy_predefined_input_for_runtime_call(Node * ctrl, CallNode* oldcall, CallNode* call);
   CallNode* make_slow_call(CallNode *oldcall, const TypeFunc* slow_call_type, address slow_call,
                        const char* leaf_name, Node* slow_path, Node* parm0, Node* parm1);
--- a/src/share/vm/opto/matcher.cpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/opto/matcher.cpp	Thu Dec 04 17:48:02 2008 -0800
@@ -1951,6 +1951,7 @@
       // Now hack a few special opcodes
       switch( n->Opcode() ) {       // Handle some opcodes special
       case Op_StorePConditional:
+      case Op_StoreIConditional:
       case Op_StoreLConditional:
       case Op_CompareAndSwapI:
       case Op_CompareAndSwapL:
--- a/src/share/vm/opto/matcher.hpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/opto/matcher.hpp	Thu Dec 04 17:48:02 2008 -0800
@@ -324,7 +324,7 @@
   virtual int      regnum_to_fpu_offset(int regnum);
 
   // Is this branch offset small enough to be addressed by a short branch?
-  bool is_short_branch_offset(int offset);
+  bool is_short_branch_offset(int rule, int offset);
 
   // Optional scaling for the parameter to the ClearArray/CopyArray node.
   static const bool init_array_count_is_in_bytes;
--- a/src/share/vm/opto/memnode.cpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/opto/memnode.cpp	Thu Dec 04 17:48:02 2008 -0800
@@ -227,6 +227,14 @@
   const Type *t_adr = phase->type( address );
   if( t_adr == Type::TOP )              return NodeSentinel; // caller will return NULL
 
+  PhaseIterGVN *igvn = phase->is_IterGVN();
+  if( can_reshape && igvn != NULL && igvn->_worklist.member(address) ) {
+    // The address's base and type may change when the address is processed.
+    // Delay this mem node transformation until the address is processed.
+    phase->is_IterGVN()->_worklist.push(this);
+    return NodeSentinel; // caller will return NULL
+  }
+
   // Avoid independent memory operations
   Node* old_mem = mem;
 
--- a/src/share/vm/opto/memnode.hpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/opto/memnode.hpp	Thu Dec 04 17:48:02 2008 -0800
@@ -632,6 +632,17 @@
   virtual uint ideal_reg() const { return Op_RegFlags; }
 };
 
+//------------------------------StoreIConditionalNode---------------------------
+// Conditionally store int to memory, if no change since prior
+// load-locked.  Sets flags for success or failure of the store.
+class StoreIConditionalNode : public LoadStoreNode {
+public:
+  StoreIConditionalNode( Node *c, Node *mem, Node *adr, Node *val, Node *ii ) : LoadStoreNode(c, mem, adr, val, ii) { }
+  virtual int Opcode() const;
+  // Produces flags
+  virtual uint ideal_reg() const { return Op_RegFlags; }
+};
+
 //------------------------------StoreLConditionalNode---------------------------
 // Conditionally store long to memory, if no change since prior
 // load-locked.  Sets flags for success or failure of the store.
@@ -639,6 +650,8 @@
 public:
   StoreLConditionalNode( Node *c, Node *mem, Node *adr, Node *val, Node *ll ) : LoadStoreNode(c, mem, adr, val, ll) { }
   virtual int Opcode() const;
+  // Produces flags
+  virtual uint ideal_reg() const { return Op_RegFlags; }
 };
 
 
--- a/src/share/vm/opto/output.cpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/opto/output.cpp	Thu Dec 04 17:48:02 2008 -0800
@@ -263,7 +263,7 @@
 # endif // ENABLE_ZAP_DEAD_LOCALS
 
 //------------------------------compute_loop_first_inst_sizes------------------
-// Compute the size of first NumberOfLoopInstrToAlign instructions at head
+// Compute the size of first NumberOfLoopInstrToAlign instructions at the top
 // of a loop. When aligning a loop we need to provide enough instructions
 // in cpu's fetch buffer to feed decoders. The loop alignment could be
 // avoided if we have enough instructions in fetch buffer at the head of a loop.
@@ -284,34 +284,23 @@
     for( uint i=1; i <= last_block; i++ ) {
       Block *b = _cfg->_blocks[i];
       // Check the first loop's block which requires an alignment.
-      if( b->head()->is_Loop() &&
-          b->code_alignment() > (uint)relocInfo::addr_unit() ) {
+      if( b->loop_alignment() > (uint)relocInfo::addr_unit() ) {
         uint sum_size = 0;
         uint inst_cnt = NumberOfLoopInstrToAlign;
-        inst_cnt = b->compute_first_inst_size(sum_size, inst_cnt,
-                                              _regalloc);
-        // Check the next fallthrough block if first loop's block does not have
-        // enough instructions.
-        if( inst_cnt > 0 && i < last_block ) {
-          // First, check if the first loop's block contains whole loop.
-          // LoopNode::LoopBackControl == 2.
-          Block *bx = _cfg->_bbs[b->pred(2)->_idx];
-          // Skip connector blocks (with limit in case of irreducible loops).
-          int search_limit = 16;
-          while( bx->is_connector() && search_limit-- > 0) {
-            bx = _cfg->_bbs[bx->pred(1)->_idx];
-          }
-          if( bx != b ) { // loop body is in several blocks.
-            Block *nb = NULL;
-            while( inst_cnt > 0 && i < last_block && nb != bx &&
-                  !_cfg->_blocks[i+1]->head()->is_Loop() ) {
-              i++;
-              nb = _cfg->_blocks[i];
-              inst_cnt  = nb->compute_first_inst_size(sum_size, inst_cnt,
-                                                      _regalloc);
-            } // while( inst_cnt > 0 && i < last_block  )
-          } // if( bx != b )
-        } // if( inst_cnt > 0 && i < last_block )
+        inst_cnt = b->compute_first_inst_size(sum_size, inst_cnt, _regalloc);
+
+        // Check subsequent fallthrough blocks if the loop's first
+        // block(s) does not have enough instructions.
+        Block *nb = b;
+        while( inst_cnt > 0 &&
+               i < last_block &&
+               !_cfg->_blocks[i+1]->has_loop_alignment() &&
+               !nb->has_successor(b) ) {
+          i++;
+          nb = _cfg->_blocks[i];
+          inst_cnt  = nb->compute_first_inst_size(sum_size, inst_cnt, _regalloc);
+        } // while( inst_cnt > 0 && i < last_block  )
+
         b->set_first_inst_size(sum_size);
       } // f( b->head()->is_Loop() )
     } // for( i <= last_block )
@@ -332,6 +321,7 @@
   uint *jmp_end    = NEW_RESOURCE_ARRAY(uint,_cfg->_num_blocks);
   uint *blk_starts = NEW_RESOURCE_ARRAY(uint,_cfg->_num_blocks+1);
   DEBUG_ONLY( uint *jmp_target = NEW_RESOURCE_ARRAY(uint,_cfg->_num_blocks); )
+  DEBUG_ONLY( uint *jmp_rule = NEW_RESOURCE_ARRAY(uint,_cfg->_num_blocks); )
   blk_starts[0]    = 0;
 
   // Initialize the sizes to 0
@@ -443,9 +433,9 @@
         uintptr_t target = blk_starts[bnum];
         if( mach->is_pc_relative() ) {
           int offset = target-(blk_starts[i] + jmp_end[i]);
-          if (_matcher->is_short_branch_offset(offset)) {
+          if (_matcher->is_short_branch_offset(mach->rule(), offset)) {
             // We've got a winner.  Replace this branch.
-            MachNode *replacement = mach->short_branch_version(this);
+            MachNode* replacement = mach->short_branch_version(this);
             b->_nodes.map(j, replacement);
             mach->subsume_by(replacement);
 
@@ -453,6 +443,7 @@
             // next pass.
             jmp_end[i] -= (mach->size(_regalloc) - replacement->size(_regalloc));
             DEBUG_ONLY( jmp_target[i] = bnum; );
+            DEBUG_ONLY( jmp_rule[i] = mach->rule(); );
           }
         } else {
 #ifndef PRODUCT
@@ -510,7 +501,7 @@
       // Get the size of the block
       uint blk_size = adr - blk_starts[i];
 
-      // When the next block starts a loop, we may insert pad NOP
+      // When the next block is the top of a loop, we may insert pad NOP
       // instructions.
       Block *nb = _cfg->_blocks[i+1];
       int current_offset = blk_starts[i] + blk_size;
@@ -524,10 +515,10 @@
   for( i=0; i<_cfg->_num_blocks; i++ ) { // For all blocks
     if( jmp_target[i] != 0 ) {
       int offset = blk_starts[jmp_target[i]]-(blk_starts[i] + jmp_end[i]);
-      if (!_matcher->is_short_branch_offset(offset)) {
+      if (!_matcher->is_short_branch_offset(jmp_rule[i], offset)) {
         tty->print_cr("target (%d) - jmp_end(%d) = offset (%d), jmp_block B%d, target_block B%d", blk_starts[jmp_target[i]], blk_starts[i] + jmp_end[i], offset, i, jmp_target[i]);
       }
-      assert(_matcher->is_short_branch_offset(offset), "Displacement too large for short jmp");
+      assert(_matcher->is_short_branch_offset(jmp_rule[i], offset), "Displacement too large for short jmp");
     }
   }
 #endif
@@ -1069,7 +1060,7 @@
 
   // If this machine supports different size branch offsets, then pre-compute
   // the length of the blocks
-  if( _matcher->is_short_branch_offset(0) ) {
+  if( _matcher->is_short_branch_offset(-1, 0) ) {
     Shorten_branches(blk_labels, code_req, locs_req, stub_req, const_req);
     labels_not_set = false;
   }
@@ -1380,8 +1371,8 @@
 
     } // End for all instructions in block
 
-    // If the next block _starts_ a loop, pad this block out to align
-    // the loop start a little. Helps prevent pipe stalls at loop starts
+    // If the next block is the top of a loop, pad this block out to align
+    // the loop top a little. Helps prevent pipe stalls at loop back branches.
     int nop_size = (new (this) MachNopNode())->size(_regalloc);
     if( i<_cfg->_num_blocks-1 ) {
       Block *nb = _cfg->_blocks[i+1];
--- a/src/share/vm/opto/parse.hpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/opto/parse.hpp	Thu Dec 04 17:48:02 2008 -0800
@@ -175,7 +175,7 @@
     bool is_SEL_backedge(Block* pred) const{ return is_SEL_head() && pred->rpo() >= rpo(); }
     bool is_invariant_local(uint i) const  {
       const JVMState* jvms = start_map()->jvms();
-      if (!jvms->is_loc(i)) return false;
+      if (!jvms->is_loc(i) || flow()->outer()->has_irreducible_entry()) return false;
       return flow()->is_invariant_local(i - jvms->locoff());
     }
     bool can_elide_SEL_phi(uint i) const  { assert(is_SEL_head(),""); return is_invariant_local(i); }
--- a/src/share/vm/opto/phase.cpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/opto/phase.cpp	Thu Dec 04 17:48:02 2008 -0800
@@ -46,7 +46,7 @@
 #ifndef PRODUCT
 elapsedTimer Phase::_t_graphReshaping;
 elapsedTimer Phase::_t_scheduler;
-elapsedTimer Phase::_t_removeEmptyBlocks;
+elapsedTimer Phase::_t_blockOrdering;
 elapsedTimer Phase::_t_macroExpand;
 elapsedTimer Phase::_t_peephole;
 elapsedTimer Phase::_t_codeGeneration;
@@ -128,7 +128,7 @@
     tty->print_cr ("      subtotal     : %3.3f sec,  %3.2f %%", regalloc_subtotal, percent_of_regalloc);
   }
   tty->print_cr ("    macroExpand  : %3.3f sec", Phase::_t_macroExpand.seconds());
-  tty->print_cr ("    removeEmpty  : %3.3f sec", Phase::_t_removeEmptyBlocks.seconds());
+  tty->print_cr ("    blockOrdering: %3.3f sec", Phase::_t_blockOrdering.seconds());
   tty->print_cr ("    peephole     : %3.3f sec", Phase::_t_peephole.seconds());
   tty->print_cr ("    codeGen      : %3.3f sec", Phase::_t_codeGeneration.seconds());
   tty->print_cr ("    install_code : %3.3f sec", Phase::_t_registerMethod.seconds());
@@ -137,7 +137,7 @@
     (DoEscapeAnalysis ? Phase::_t_escapeAnalysis.seconds() : 0.0) +
     Phase::_t_optimizer.seconds() + Phase::_t_graphReshaping.seconds() +
     Phase::_t_matcher.seconds() + Phase::_t_scheduler.seconds() +
-    Phase::_t_registerAllocation.seconds() + Phase::_t_removeEmptyBlocks.seconds() +
+    Phase::_t_registerAllocation.seconds() + Phase::_t_blockOrdering.seconds() +
     Phase::_t_macroExpand.seconds() + Phase::_t_peephole.seconds() +
     Phase::_t_codeGeneration.seconds() + Phase::_t_registerMethod.seconds();
   double percent_of_method_compile = ((phase_subtotal == 0.0) ? 0.0 : phase_subtotal / Phase::_t_methodCompilation.seconds()) * 100.0;
--- a/src/share/vm/opto/phase.hpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/opto/phase.hpp	Thu Dec 04 17:48:02 2008 -0800
@@ -40,16 +40,12 @@
     Optimistic,                 // Optimistic analysis phase
     GVN,                        // Pessimistic global value numbering phase
     Ins_Select,                 // Instruction selection phase
-    Copy_Elimination,           // Copy Elimination
-    Dead_Code_Elimination,      // DCE and compress Nodes
-    Conditional_Constant,       // Conditional Constant Propagation
     CFG,                        // Build a CFG
-    DefUse,                     // Build Def->Use chains
+    BlockLayout,                // Linear ordering of blocks
     Register_Allocation,        // Register allocation, duh
     LIVE,                       // Dragon-book LIVE range problem
     Interference_Graph,         // Building the IFG
     Coalesce,                   // Coalescing copies
-    Conditional_CProp,          // Conditional Constant Propagation
     Ideal_Loop,                 // Find idealized trip-counted loops
     Macro_Expand,               // Expand macro nodes
     Peephole,                   // Apply peephole optimizations
@@ -80,7 +76,7 @@
 #ifndef PRODUCT
   static elapsedTimer _t_graphReshaping;
   static elapsedTimer _t_scheduler;
-  static elapsedTimer _t_removeEmptyBlocks;
+  static elapsedTimer _t_blockOrdering;
   static elapsedTimer _t_macroExpand;
   static elapsedTimer _t_peephole;
   static elapsedTimer _t_codeGeneration;
--- a/src/share/vm/opto/reg_split.cpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/opto/reg_split.cpp	Thu Dec 04 17:48:02 2008 -0800
@@ -53,6 +53,7 @@
   // Bail rather than abort
   int ireg = def->ideal_reg();
   if( ireg == 0 || ireg == Op_RegFlags ) {
+    assert(false, "attempted to spill a non-spillable item");
     C->record_method_not_compilable("attempted to spill a non-spillable item");
     return NULL;
   }
--- a/src/share/vm/opto/type.cpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/opto/type.cpp	Thu Dec 04 17:48:02 2008 -0800
@@ -3541,7 +3541,7 @@
 
 #ifndef PRODUCT
 void TypeNarrowOop::dump2( Dict & d, uint depth, outputStream *st ) const {
-  tty->print("narrowoop: ");
+  st->print("narrowoop: ");
   _ooptype->dump2(d, depth, st);
 }
 #endif
--- a/src/share/vm/opto/type.hpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/opto/type.hpp	Thu Dec 04 17:48:02 2008 -0800
@@ -1183,6 +1183,9 @@
 #define RShiftXNode  RShiftLNode
 // For card marks and hashcodes
 #define URShiftXNode URShiftLNode
+// UseOptoBiasInlining
+#define XorXNode     XorLNode
+#define StoreXConditionalNode StoreLConditionalNode
 // Opcodes
 #define Op_LShiftX   Op_LShiftL
 #define Op_AndX      Op_AndL
@@ -1222,6 +1225,9 @@
 #define RShiftXNode  RShiftINode
 // For card marks and hashcodes
 #define URShiftXNode URShiftINode
+// UseOptoBiasInlining
+#define XorXNode     XorINode
+#define StoreXConditionalNode StoreIConditionalNode
 // Opcodes
 #define Op_LShiftX   Op_LShiftI
 #define Op_AndX      Op_AndI
--- a/src/share/vm/prims/jvm.cpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/prims/jvm.cpp	Thu Dec 04 17:48:02 2008 -0800
@@ -744,6 +744,7 @@
 
 // common code for JVM_DefineClass() and JVM_DefineClassWithSource()
 static jclass jvm_define_class_common(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize len, jobject pd, const char *source, TRAPS) {
+  if (source == NULL)  source = "__JVM_DefineClass__";
 
   // Since exceptions can be thrown, class initialization can take place
   // if name is NULL no check for class name in .class stream has to be made.
@@ -782,7 +783,7 @@
 JVM_ENTRY(jclass, JVM_DefineClass(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize len, jobject pd))
   JVMWrapper2("JVM_DefineClass %s", name);
 
-  return jvm_define_class_common(env, name, loader, buf, len, pd, "__JVM_DefineClass__", THREAD);
+  return jvm_define_class_common(env, name, loader, buf, len, pd, NULL, THREAD);
 JVM_END
 
 
--- a/src/share/vm/prims/jvm.h	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/prims/jvm.h	Thu Dec 04 17:48:02 2008 -0800
@@ -422,6 +422,14 @@
                           const jbyte *buf, jsize len, jobject pd,
                           const char *source);
 
+/* Define a class with a source (MLVM) */
+JNIEXPORT jclass JNICALL
+JVM_DefineClassWithCP(JNIEnv *env, const char *name, jobject loader,
+                      const jbyte *buf, jsize len, jobject pd,
+                      const char *source,
+                      // same args as JVM_DefineClassWithSource to this point
+                      jobjectArray constants);
+
 /*
  * Reflection support functions
  */
--- a/src/share/vm/prims/unsafe.cpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/prims/unsafe.cpp	Thu Dec 04 17:48:02 2008 -0800
@@ -837,6 +837,163 @@
   }
 UNSAFE_END
 
+#define DAC_Args CLS"[B["OBJ
+// define a class but do not make it known to the class loader or system dictionary
+// - host_class:  supplies context for linkage, access control, protection domain, and class loader
+// - data:  bytes of a class file, a raw memory address (length gives the number of bytes)
+// - cp_patches:  where non-null entries exist, they replace corresponding CP entries in data
+
+// When you load an anonymous class U, it works as if you changed its name just before loading,
+// to a name that you will never use again.  Since the name is lost, no other class can directly
+// link to any member of U.  Just after U is loaded, the only way to use it is reflectively,
+// through java.lang.Class methods like Class.newInstance.
+
+// Access checks for linkage sites within U continue to follow the same rules as for named classes.
+// The package of an anonymous class is given by the package qualifier on the name under which it was loaded.
+// An anonymous class also has special privileges to access any member of its host class.
+// This is the main reason why this loading operation is unsafe.  The purpose of this is to
+// allow language implementations to simulate "open classes"; a host class in effect gets
+// new code when an anonymous class is loaded alongside it.  A less convenient but more
+// standard way to do this is with reflection, which can also be set to ignore access
+// restrictions.
+
+// Access into an anonymous class is possible only through reflection.  Therefore, there
+// are no special access rules for calling into an anonymous class.  The relaxed access
+// rule for the host class is applied in the opposite direction:  A host class reflectively
+// access one of its anonymous classes.
+
+// If you load the same bytecodes twice, you get two different classes.  You can reload
+// the same bytecodes with or without varying CP patches.
+
+// By using the CP patching array, you can have a new anonymous class U2 refer to an older one U1.
+// The bytecodes for U2 should refer to U1 by a symbolic name (doesn't matter what the name is).
+// The CONSTANT_Class entry for that name can be patched to refer directly to U1.
+
+// This allows, for example, U2 to use U1 as a superclass or super-interface, or as
+// an outer class (so that U2 is an anonymous inner class of anonymous U1).
+// It is not possible for a named class, or an older anonymous class, to refer by
+// name (via its CP) to a newer anonymous class.
+
+// CP patching may also be used to modify (i.e., hack) the names of methods, classes,
+// or type descriptors used in the loaded anonymous class.
+
+// Finally, CP patching may be used to introduce "live" objects into the constant pool,
+// instead of "dead" strings.  A compiled statement like println((Object)"hello") can
+// be changed to println(greeting), where greeting is an arbitrary object created before
+// the anonymous class is loaded.  This is useful in dynamic languages, in which
+// various kinds of metaobjects must be introduced as constants into bytecode.
+// Note the cast (Object), which tells the verifier to expect an arbitrary object,
+// not just a literal string.  For such ldc instructions, the verifier uses the
+// type Object instead of String, if the loaded constant is not in fact a String.
+
+static oop
+Unsafe_DefineAnonymousClass_impl(JNIEnv *env,
+                                 jclass host_class, jbyteArray data, jobjectArray cp_patches_jh,
+                                 HeapWord* *temp_alloc,
+                                 TRAPS) {
+
+  if (UsePerfData) {
+    ClassLoader::unsafe_defineClassCallCounter()->inc();
+  }
+
+  if (data == NULL) {
+    THROW_0(vmSymbols::java_lang_NullPointerException());
+  }
+
+  jint length = typeArrayOop(JNIHandles::resolve_non_null(data))->length();
+  jint word_length = (length + sizeof(HeapWord)-1) / sizeof(HeapWord);
+  HeapWord* body = NEW_C_HEAP_ARRAY(HeapWord, word_length);
+  if (body == NULL) {
+    THROW_0(vmSymbols::java_lang_OutOfMemoryError());
+  }
+
+  // caller responsible to free it:
+  (*temp_alloc) = body;
+
+  {
+    jbyte* array_base = typeArrayOop(JNIHandles::resolve_non_null(data))->byte_at_addr(0);
+    Copy::conjoint_words((HeapWord*) array_base, body, word_length);
+  }
+
+  u1* class_bytes = (u1*) body;
+  int class_bytes_length = (int) length;
+  if (class_bytes_length < 0)  class_bytes_length = 0;
+  if (class_bytes == NULL
+      || host_class == NULL
+      || length != class_bytes_length)
+    THROW_0(vmSymbols::java_lang_IllegalArgumentException());
+
+  objArrayHandle cp_patches_h;
+  if (cp_patches_jh != NULL) {
+    oop p = JNIHandles::resolve_non_null(cp_patches_jh);
+    if (!p->is_objArray())
+      THROW_0(vmSymbols::java_lang_IllegalArgumentException());
+    cp_patches_h = objArrayHandle(THREAD, (objArrayOop)p);
+  }
+
+  KlassHandle host_klass(THREAD, java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(host_class)));
+  const char* host_source = host_klass->external_name();
+  Handle      host_loader(THREAD, host_klass->class_loader());
+  Handle      host_domain(THREAD, host_klass->protection_domain());
+
+  GrowableArray<Handle>* cp_patches = NULL;
+  if (cp_patches_h.not_null()) {
+    int alen = cp_patches_h->length();
+    for (int i = alen-1; i >= 0; i--) {
+      oop p = cp_patches_h->obj_at(i);
+      if (p != NULL) {
+        Handle patch(THREAD, p);
+        if (cp_patches == NULL)
+          cp_patches = new GrowableArray<Handle>(i+1, i+1, Handle());
+        cp_patches->at_put(i, patch);
+      }
+    }
+  }
+
+  ClassFileStream st(class_bytes, class_bytes_length, (char*) host_source);
+
+  instanceKlassHandle anon_klass;
+  {
+    symbolHandle no_class_name;
+    klassOop anonk = SystemDictionary::parse_stream(no_class_name,
+                                                    host_loader, host_domain,
+                                                    &st, host_klass, cp_patches,
+                                                    CHECK_NULL);
+    if (anonk == NULL)  return NULL;
+    anon_klass = instanceKlassHandle(THREAD, anonk);
+  }
+
+  // let caller initialize it as needed...
+
+  return anon_klass->java_mirror();
+}
+
+UNSAFE_ENTRY(jclass, Unsafe_DefineAnonymousClass(JNIEnv *env, jobject unsafe, jclass host_class, jbyteArray data, jobjectArray cp_patches_jh))
+{
+  UnsafeWrapper("Unsafe_DefineAnonymousClass");
+  ResourceMark rm(THREAD);
+
+  HeapWord* temp_alloc = NULL;
+
+  jobject res_jh = NULL;
+
+  { oop res_oop = Unsafe_DefineAnonymousClass_impl(env,
+                                                   host_class, data, cp_patches_jh,
+                                                   &temp_alloc, THREAD);
+    if (res_oop != NULL)
+      res_jh = JNIHandles::make_local(env, res_oop);
+  }
+
+  // try/finally clause:
+  if (temp_alloc != NULL) {
+    FREE_C_HEAP_ARRAY(HeapWord, temp_alloc);
+  }
+
+  return (jclass) res_jh;
+}
+UNSAFE_END
+
+
 
 UNSAFE_ENTRY(void, Unsafe_MonitorEnter(JNIEnv *env, jobject unsafe, jobject jobj))
   UnsafeWrapper("Unsafe_MonitorEnter");
@@ -1292,6 +1449,9 @@
     {CC"copyMemory",         CC"("ADR ADR"J)V",          FN_PTR(Unsafe_CopyMemory)}
 };
 
+JNINativeMethod anonk_methods[] = {
+    {CC"defineAnonymousClass", CC"("DAC_Args")"CLS,      FN_PTR(Unsafe_DefineAnonymousClass)},
+};
 
 #undef CC
 #undef FN_PTR
@@ -1354,6 +1514,15 @@
         }
       }
     }
+    if (AnonymousClasses) {
+      env->RegisterNatives(unsafecls, anonk_methods, sizeof(anonk_methods)/sizeof(JNINativeMethod));
+      if (env->ExceptionOccurred()) {
+        if (PrintMiscellaneous && (Verbose || WizardMode)) {
+          tty->print_cr("Warning:  SDK 1.7 Unsafe.defineClass (anonymous version) not found.");
+        }
+        env->ExceptionClear();
+      }
+    }
     int status = env->RegisterNatives(unsafecls, methods, sizeof(methods)/sizeof(JNINativeMethod));
     if (env->ExceptionOccurred()) {
       if (PrintMiscellaneous && (Verbose || WizardMode)) {
--- a/src/share/vm/runtime/arguments.cpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/runtime/arguments.cpp	Thu Dec 04 17:48:02 2008 -0800
@@ -1365,6 +1365,9 @@
   if (AggressiveOpts && FLAG_IS_DEFAULT(SpecialArraysEquals)) {
     FLAG_SET_DEFAULT(SpecialArraysEquals, true);
   }
+  if (AggressiveOpts && FLAG_IS_DEFAULT(BiasedLockingStartupDelay)) {
+    FLAG_SET_DEFAULT(BiasedLockingStartupDelay, 500);
+  }
 #endif
 
   if (AggressiveOpts) {
@@ -2319,7 +2322,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;
 }
 
@@ -2625,6 +2633,12 @@
   FLAG_SET_DEFAULT(UseBiasedLocking, false);
 #endif /* CC_INTERP */
 
+#ifdef COMPILER2
+  if (!UseBiasedLocking || EmitSync != 0) {
+    UseOptoBiasInlining = false;
+  }
+#endif
+
   if (PrintCommandLineFlags) {
     CommandLineFlags::printSetFlags();
   }
--- a/src/share/vm/runtime/biasedLocking.cpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/runtime/biasedLocking.cpp	Thu Dec 04 17:48:02 2008 -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/src/share/vm/runtime/frame.cpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/runtime/frame.cpp	Thu Dec 04 17:48:02 2008 -0800
@@ -83,12 +83,12 @@
     intptr_t* src = (intptr_t*) location(r);
     if (src != NULL) {
 
-      r->print();
-      tty->print(" [" INTPTR_FORMAT "] = ", src);
+      r->print_on(st);
+      st->print(" [" INTPTR_FORMAT "] = ", src);
       if (((uintptr_t)src & (sizeof(*src)-1)) != 0) {
-        tty->print_cr("<misaligned>");
+        st->print_cr("<misaligned>");
       } else {
-        tty->print_cr(INTPTR_FORMAT, *src);
+        st->print_cr(INTPTR_FORMAT, *src);
       }
     }
   }
--- a/src/share/vm/runtime/globals.hpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/runtime/globals.hpp	Thu Dec 04 17:48:02 2008 -0800
@@ -493,7 +493,7 @@
   develop(bool, DeoptimizeALot, false,                                      \
           "deoptimize at every exit from the runtime system")               \
                                                                             \
-  develop(ccstrlist, DeoptimizeOnlyAt, "",                                  \
+  notproduct(ccstrlist, DeoptimizeOnlyAt, "",                               \
           "a comma separated list of bcis to deoptimize at")                \
                                                                             \
   product(bool, DeoptimizeRandom, false,                                    \
@@ -2792,7 +2792,7 @@
   product(intx, TargetSurvivorRatio,    50,                                 \
           "Desired percentage of survivor space used after scavenge")       \
                                                                             \
-  product(intx, MarkSweepDeadRatio,     5,                                  \
+  product(uintx, MarkSweepDeadRatio,     5,                                 \
           "Percentage (0-100) of the old gen allowed as dead wood."         \
           "Serial mark sweep treats this as both the min and max value."    \
           "CMS uses this value only if it falls back to mark sweep."        \
@@ -2801,7 +2801,7 @@
           "either completely full or completely empty.  Par compact also"   \
           "has a smaller default value; see arguments.cpp.")                \
                                                                             \
-  product(intx, PermMarkSweepDeadRatio,    20,                              \
+  product(uintx, PermMarkSweepDeadRatio,    20,                             \
           "Percentage (0-100) of the perm gen allowed as dead wood."        \
           "See MarkSweepDeadRatio for collector-specific comments.")        \
                                                                             \
@@ -3230,6 +3230,9 @@
           "Skip assert() and verify() which page-in unwanted shared "       \
           "objects. ")                                                      \
                                                                             \
+  product(bool, AnonymousClasses, false,                                    \
+          "support sun.misc.Unsafe.defineAnonymousClass")                   \
+                                                                            \
   product(bool, TaggedStackInterpreter, false,                              \
           "Insert tags in interpreter execution stack for oopmap generaion")\
                                                                             \
@@ -3259,9 +3262,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/src/share/vm/runtime/perfMemory.cpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/runtime/perfMemory.cpp	Thu Dec 04 17:48:02 2008 -0800
@@ -25,6 +25,14 @@
 # include "incls/_precompiled.incl"
 # include "incls/_perfMemory.cpp.incl"
 
+// Prefix of performance data file.
+const char               PERFDATA_NAME[] = "hsperfdata";
+
+// Add 1 for the '_' character between PERFDATA_NAME and pid. The '\0' terminating
+// character will be included in the sizeof(PERFDATA_NAME) operation.
+static const size_t PERFDATA_FILENAME_LEN = sizeof(PERFDATA_NAME) +
+                                            UINT_CHARS + 1;
+
 char*                    PerfMemory::_start = NULL;
 char*                    PerfMemory::_end = NULL;
 char*                    PerfMemory::_top = NULL;
--- a/src/share/vm/runtime/perfMemory.hpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/runtime/perfMemory.hpp	Thu Dec 04 17:48:02 2008 -0800
@@ -95,7 +95,7 @@
 } PerfDataEntry;
 
 // Prefix of performance data file.
-static const char PERFDATA_NAME[] = "hsperfdata";
+extern const char PERFDATA_NAME[];
 
 // UINT_CHARS contains the number of characters holding a process id
 // (i.e. pid). pid is defined as unsigned "int" so the maximum possible pid value
@@ -103,11 +103,6 @@
 // string.
 static const size_t UINT_CHARS = 10;
 
-// Add 1 for the '_' character between PERFDATA_NAME and pid. The '\0' terminating
-// character will be included in the sizeof(PERFDATA_NAME) operation.
-static const size_t PERFDATA_FILENAME_LEN = sizeof(PERFDATA_NAME) +
-                                            UINT_CHARS + 1;
-
 /* the PerfMemory class manages creation, destruction,
  * and allocation of the PerfData region.
  */
--- a/src/share/vm/runtime/reflection.cpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/runtime/reflection.cpp	Thu Dec 04 17:48:02 2008 -0800
@@ -456,10 +456,32 @@
   return can_relax_access_check_for(current_class, new_class, classloader_only);
 }
 
+static bool under_host_klass(instanceKlass* ik, klassOop host_klass) {
+  DEBUG_ONLY(int inf_loop_check = 1000 * 1000 * 1000);
+  for (;;) {
+    klassOop hc = (klassOop) ik->host_klass();
+    if (hc == NULL)        return false;
+    if (hc == host_klass)  return true;
+    ik = instanceKlass::cast(hc);
+
+    // There's no way to make a host class loop short of patching memory.
+    // Therefore there cannot be a loop here unles there's another bug.
+    // Still, let's check for it.
+    assert(--inf_loop_check > 0, "no host_klass loop");
+  }
+}
+
 bool Reflection::can_relax_access_check_for(
     klassOop accessor, klassOop accessee, bool classloader_only) {
   instanceKlass* accessor_ik = instanceKlass::cast(accessor);
   instanceKlass* accessee_ik  = instanceKlass::cast(accessee);
+
+  // If either is on the other's host_klass chain, access is OK,
+  // because one is inside the other.
+  if (under_host_klass(accessor_ik, accessee) ||
+      under_host_klass(accessee_ik, accessor))
+    return true;
+
   if (RelaxAccessControlCheck ||
       (accessor_ik->major_version() < JAVA_1_5_VERSION &&
        accessee_ik->major_version() < JAVA_1_5_VERSION)) {
--- a/src/share/vm/runtime/thread.cpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/runtime/thread.cpp	Thu Dec 04 17:48:02 2008 -0800
@@ -1422,6 +1422,7 @@
   thread->clear_pending_exception();
 }
 
+
 // For any new cleanup additions, please check to see if they need to be applied to
 // cleanup_failed_attach_current_thread as well.
 void JavaThread::exit(bool destroy_vm, ExitType exit_type) {
@@ -1592,39 +1593,62 @@
     JvmtiExport::cleanup_thread(this);
   }
 
+#ifndef SERIALGC
+  // We must flush G1-related buffers before removing a thread from
+  // the list of active threads.
+  if (UseG1GC) {
+    flush_barrier_queues();
+  }
+#endif
+
   // Remove from list of active threads list, and notify VM thread if we are the last non-daemon thread
   Threads::remove(this);
 }
 
+#ifndef SERIALGC
+// Flush G1-related queues.
+void JavaThread::flush_barrier_queues() {
+  satb_mark_queue().flush();
+  dirty_card_queue().flush();
+}
+#endif
+
 void JavaThread::cleanup_failed_attach_current_thread() {
-
-     if (get_thread_profiler() != NULL) {
-       get_thread_profiler()->disengage();
-       ResourceMark rm;
-       get_thread_profiler()->print(get_thread_name());
-     }
-
-     if (active_handles() != NULL) {
-      JNIHandleBlock* block = active_handles();
-      set_active_handles(NULL);
-      JNIHandleBlock::release_block(block);
-     }
-
-     if (free_handle_block() != NULL) {
-       JNIHandleBlock* block = free_handle_block();
-       set_free_handle_block(NULL);
-       JNIHandleBlock::release_block(block);
-     }
-
-     if (UseTLAB) {
-       tlab().make_parsable(true);  // retire TLAB, if any
-     }
-
-     Threads::remove(this);
-     delete this;
+  if (get_thread_profiler() != NULL) {
+    get_thread_profiler()->disengage();
+    ResourceMark rm;
+    get_thread_profiler()->print(get_thread_name());
+  }
+
+  if (active_handles() != NULL) {
+    JNIHandleBlock* block = active_handles();
+    set_active_handles(NULL);
+    JNIHandleBlock::release_block(block);
+  }
+
+  if (free_handle_block() != NULL) {
+    JNIHandleBlock* block = free_handle_block();
+    set_free_handle_block(NULL);
+    JNIHandleBlock::release_block(block);
+  }
+
+  if (UseTLAB) {
+    tlab().make_parsable(true);  // retire TLAB, if any
+  }
+
+#ifndef SERIALGC
+  if (UseG1GC) {
+    flush_barrier_queues();
+  }
+#endif
+
+  Threads::remove(this);
+  delete this;
 }
 
 
+
+
 JavaThread* JavaThread::active() {
   Thread* thread = ThreadLocalStorage::thread();
   assert(thread != NULL, "just checking");
--- a/src/share/vm/runtime/thread.hpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/runtime/thread.hpp	Thu Dec 04 17:48:02 2008 -0800
@@ -793,6 +793,8 @@
   DirtyCardQueue _dirty_card_queue;      // Thread-local log for dirty cards.
   // Set of all such queues.
   static DirtyCardQueueSet _dirty_card_queue_set;
+
+  void flush_barrier_queues();
 #endif // !SERIALGC
 
   friend class VMThread;
--- a/src/share/vm/utilities/array.hpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/utilities/array.hpp	Thu Dec 04 17:48:02 2008 -0800
@@ -40,11 +40,18 @@
     _length  = 0;
     _data    = NULL;
     DEBUG_ONLY(init_nesting();)
+    // client may call initialize, at most once
   }
 
 
   ResourceArray(size_t esize, int length) {
+    DEBUG_ONLY(_data = NULL);
+    initialize(esize, length);
+  }
+
+  void initialize(size_t esize, int length) {
     assert(length >= 0, "illegal length");
+    assert(_data == NULL, "must be new object");
     _length  = length;
     _data    = resource_allocate_bytes(esize * length);
     DEBUG_ONLY(init_nesting();)
@@ -111,7 +118,10 @@
     /* creation */                                                                       \
     array_name() : base_class()                       {}                                 \
     array_name(const int length) : base_class(esize, length) {}                          \
-    array_name(const int length, const etype fx) : base_class(esize, length) {           \
+    array_name(const int length, const etype fx)      { initialize(length, fx); }        \
+    void initialize(const int length)     { base_class::initialize(esize, length); }     \
+    void initialize(const int length, const etype fx) {                                  \
+      initialize(length);                                                                \
       for (int i = 0; i < length; i++) ((etype*)_data)[i] = fx;                          \
     }                                                                                    \
                                                                                          \
@@ -157,16 +167,29 @@
                                                                                          \
    public:                                                                               \
     /* creation */                                                                       \
-    stack_name() : array_name()                  { _size = 0; }                          \
-    stack_name(const int size) : array_name(size){ _length = 0; _size = size; }          \
-    stack_name(const int size, const etype fx) : array_name(size, fx) { _size = size; }  \
+    stack_name() : array_name()                     { _size = 0; }                       \
+    stack_name(const int size)                      { initialize(size); }                \
+    stack_name(const int size, const etype fx)      { initialize(size, fx); }            \
+    void initialize(const int size, const etype fx) {                                    \
+      _size = size;                                                                      \
+      array_name::initialize(size, fx);                                                  \
+      /* _length == size, allocation and size are the same */                            \
+    }                                                                                    \
+    void initialize(const int size) {                                                    \
+      _size = size;                                                                      \
+      array_name::initialize(size);                                                      \
+      _length = 0;          /* reset length to zero; _size records the allocation */     \
+    }                                                                                    \
                                                                                          \
     /* standard operations */                                                            \
     int size() const                             { return _size; }                       \
                                                                                          \
-    void push(const etype x) {                                                           \
-      if (length() >= size()) expand(esize, length(), _size);                            \
-      ((etype*)_data)[_length++] = x;                                                    \
+    int push(const etype x) {                                                            \
+      int len = length();                                                                \
+      if (len >= size()) expand(esize, len, _size);                                      \
+      ((etype*)_data)[len] = x;                                                          \
+      _length = len+1;                                                                   \
+      return len;                                                                        \
     }                                                                                    \
                                                                                          \
     etype pop() {                                                                        \
@@ -235,7 +258,7 @@
     int  capacity() const                        { return size(); }                      \
     void clear()                                 { truncate(0); }                        \
     void trunc_to(const int length)              { truncate(length); }                   \
-    void append(const etype x)                   { push(x); }                            \
+    int  append(const etype x)                   { return push(x); }                     \
     void appendAll(const stack_name* stack)      { push_all(stack); }                    \
     etype last() const                           { return top(); }                       \
   };                                                                                     \
--- a/src/share/vm/utilities/constantTag.hpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/utilities/constantTag.hpp	Thu Dec 04 17:48:02 2008 -0800
@@ -71,6 +71,7 @@
   bool is_string_index() const      { return _tag == JVM_CONSTANT_StringIndex; }
 
   bool is_klass_reference() const   { return is_klass_index() || is_unresolved_klass(); }
+  bool is_klass_or_reference() const{ return is_klass() || is_klass_reference(); }
   bool is_field_or_method() const   { return is_field() || is_method() || is_interface_method(); }
   bool is_symbol() const            { return is_utf8(); }
 
--- a/src/share/vm/utilities/debug.cpp	Thu Dec 04 17:29:56 2008 -0800
+++ b/src/share/vm/utilities/debug.cpp	Thu Dec 04 17:48:02 2008 -0800
@@ -567,7 +567,7 @@
       }
       // the InlineCacheBuffer is using stubs generated into a buffer blob
       if (InlineCacheBuffer::contains(addr)) {
-        tty->print_cr(INTPTR_FORMAT "is pointing into InlineCacheBuffer", addr);
+        tty->print_cr(INTPTR_FORMAT " is pointing into InlineCacheBuffer", addr);
         return;
       }
       VtableStub* v = VtableStubs::stub_containing(addr);
@@ -595,7 +595,7 @@
     return;
   }
 
-  if (Universe::heap()->is_in_reserved(addr)) {
+  if (Universe::heap()->is_in(addr)) {
     H