changeset 2034:9669f9b28410 hs20-b04 jdk7-b123

Merge
author trims
date Thu, 16 Dec 2010 20:48:11 -0800
parents af96d06cc0da (current diff) 03e1b9fce89d (diff)
children 08b76f57574b 3da13a976363
files
diffstat 170 files changed, 4859 insertions(+), 2267 deletions(-) [+]
line wrap: on
line diff
--- a/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPool.java	Thu Dec 16 20:35:33 2010 -0800
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPool.java	Thu Dec 16 20:48:11 2010 -0800
@@ -60,10 +60,7 @@
     headerSize  = type.getSize();
     elementSize = 0;
     // fetch constants:
-    MULTI_OPERAND_COUNT_OFFSET = db.lookupIntConstant("constantPoolOopDesc::_multi_operand_count_offset").intValue();
-    MULTI_OPERAND_BASE_OFFSET = db.lookupIntConstant("constantPoolOopDesc::_multi_operand_base_offset").intValue();
     INDY_BSM_OFFSET = db.lookupIntConstant("constantPoolOopDesc::_indy_bsm_offset").intValue();
-    INDY_NT_OFFSET = db.lookupIntConstant("constantPoolOopDesc::_indy_nt_offset").intValue();
     INDY_ARGC_OFFSET = db.lookupIntConstant("constantPoolOopDesc::_indy_argc_offset").intValue();
     INDY_ARGV_OFFSET = db.lookupIntConstant("constantPoolOopDesc::_indy_argv_offset").intValue();
   }
@@ -83,10 +80,7 @@
   private static long headerSize;
   private static long elementSize;
 
-  private static int MULTI_OPERAND_COUNT_OFFSET;
-  private static int MULTI_OPERAND_BASE_OFFSET;
   private static int INDY_BSM_OFFSET;
-  private static int INDY_NT_OFFSET;
   private static int INDY_ARGC_OFFSET;
   private static int INDY_ARGV_OFFSET;
 
@@ -296,20 +290,23 @@
   }
 
   /** Lookup for multi-operand (InvokeDynamic) entries. */
-  public int[] getMultiOperandsAt(int i) {
+  public short[] getBootstrapSpecifierAt(int i) {
     if (Assert.ASSERTS_ENABLED) {
       Assert.that(getTagAt(i).isInvokeDynamic(), "Corrupted constant pool");
     }
-    int pos = this.getIntAt(i);
-    int countPos = pos + MULTI_OPERAND_COUNT_OFFSET;  // == pos-1
-    int basePos  = pos + MULTI_OPERAND_BASE_OFFSET;   // == pos
-    if (countPos < 0)  return null;  // safety first
+    if (getTagAt(i).value() == JVM_CONSTANT_InvokeDynamicTrans)
+        return null;
+    int bsmSpec = extractLowShortFromInt(this.getIntAt(i));
     TypeArray operands = getOperands();
     if (operands == null)  return null;  // safety first
-    int length = operands.getIntAt(countPos);
-    int[] values = new int[length];
-    for (int j = 0; j < length; j++) {
-        values[j] = operands.getIntAt(basePos+j);
+    int basePos = VM.getVM().buildIntFromShorts(operands.getShortAt(bsmSpec * 2 + 0),
+                                                operands.getShortAt(bsmSpec * 2 + 1));
+    int argv = basePos + INDY_ARGV_OFFSET;
+    int argc = operands.getShortAt(basePos + INDY_ARGC_OFFSET);
+    int endPos = argv + argc;
+    short[] values = new short[endPos - basePos];
+    for (int j = 0; j < values.length; j++) {
+        values[j] = operands.getShortAt(basePos+j);
     }
     return values;
   }
@@ -334,6 +331,7 @@
     case JVM_CONSTANT_MethodHandle:       return "JVM_CONSTANT_MethodHandle";
     case JVM_CONSTANT_MethodType:         return "JVM_CONSTANT_MethodType";
     case JVM_CONSTANT_InvokeDynamic:      return "JVM_CONSTANT_InvokeDynamic";
+    case JVM_CONSTANT_InvokeDynamicTrans: return "JVM_CONSTANT_InvokeDynamic/transitional";
     case JVM_CONSTANT_Invalid:            return "JVM_CONSTANT_Invalid";
     case JVM_CONSTANT_UnresolvedClass:    return "JVM_CONSTANT_UnresolvedClass";
     case JVM_CONSTANT_UnresolvedClassInError:    return "JVM_CONSTANT_UnresolvedClassInError";
@@ -393,6 +391,7 @@
         case JVM_CONSTANT_MethodHandle:
         case JVM_CONSTANT_MethodType:
         case JVM_CONSTANT_InvokeDynamic:
+        case JVM_CONSTANT_InvokeDynamicTrans:
           visitor.doInt(new IntField(new NamedFieldIdentifier(nameForTag(ctag)), indexOffset(index), true), true);
           break;
         }
@@ -556,19 +555,16 @@
                   break;
               }
 
+              case JVM_CONSTANT_InvokeDynamicTrans:
               case JVM_CONSTANT_InvokeDynamic: {
                   dos.writeByte(cpConstType);
-                  int[] values = getMultiOperandsAt(ci);
-                  for (int vn = 0; vn < values.length; vn++) {
-                      dos.writeShort(values[vn]);
-                  }
-                  int bootstrapMethodIndex = values[INDY_BSM_OFFSET];
-                  int nameAndTypeIndex = values[INDY_NT_OFFSET];
-                  int argumentCount = values[INDY_ARGC_OFFSET];
-                  assert(INDY_ARGV_OFFSET + argumentCount == values.length);
-                  if (DEBUG) debugMessage("CP[" + ci + "] = indy BSM = " + bootstrapMethodIndex
-                                          + ", N&T = " + nameAndTypeIndex
-                                          + ", argc = " + argumentCount);
+                  int value = getIntAt(ci);
+                  short bsmIndex = (short) extractLowShortFromInt(value);
+                  short nameAndTypeIndex = (short) extractHighShortFromInt(value);
+                  dos.writeShort(bsmIndex);
+                  dos.writeShort(nameAndTypeIndex);
+                  if (DEBUG) debugMessage("CP[" + ci + "] = indy BSM = " + bsmIndex
+                                          + ", N&T = " + nameAndTypeIndex);
                   break;
               }
 
--- a/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java	Thu Dec 16 20:35:33 2010 -0800
+++ b/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java	Thu Dec 16 20:48:11 2010 -0800
@@ -321,13 +321,16 @@
                      break;
                 }
 
+                case JVM_CONSTANT_InvokeDynamicTrans:
                 case JVM_CONSTANT_InvokeDynamic: {
                      dos.writeByte(cpConstType);
-                     int[] values = cpool.getMultiOperandsAt(ci);
-                     for (int vn = 0; vn < values.length; vn++) {
-                         dos.writeShort(values[vn]);
-                     }
-                     if (DEBUG) debugMessage("CP[" + ci + "] = INDY indexes = " + Arrays.toString(values));
+                     int value = cpool.getIntAt(ci);
+                     short bsmIndex = (short) extractLowShortFromInt(value);
+                     short nameAndTypeIndex = (short) extractHighShortFromInt(value);
+                     dos.writeShort(bsmIndex);
+                     dos.writeShort(nameAndTypeIndex);
+                     if (DEBUG) debugMessage("CP[" + ci + "] = INDY bsm = " +
+                           bsmIndex + ", N&T = " + nameAndTypeIndex);
                      break;
                 }
 
--- a/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java	Thu Dec 16 20:35:33 2010 -0800
+++ b/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java	Thu Dec 16 20:48:11 2010 -0800
@@ -460,7 +460,8 @@
       return buf.toString();
    }
 
-   private String genListOfShort(int[] values) {
+   private String genListOfShort(short[] values) {
+      if (values == null || values.length == 0)  return "";
       Formatter buf = new Formatter(genHTML);
       buf.append('[');
       for (int i = 0; i < values.length; i++) {
@@ -594,9 +595,11 @@
                buf.cell(Integer.toString(cpool.getIntAt(index)));
                break;
 
+            case JVM_CONSTANT_InvokeDynamicTrans:
             case JVM_CONSTANT_InvokeDynamic:
                buf.cell("JVM_CONSTANT_InvokeDynamic");
-               buf.cell(genListOfShort(cpool.getMultiOperandsAt(index)));
+               buf.cell(genLowHighShort(cpool.getIntAt(index)) +
+                        genListOfShort(cpool.getBootstrapSpecifierAt(index)));
                break;
 
             default:
--- a/agent/src/share/classes/sun/jvm/hotspot/utilities/ConstantTag.java	Thu Dec 16 20:35:33 2010 -0800
+++ b/agent/src/share/classes/sun/jvm/hotspot/utilities/ConstantTag.java	Thu Dec 16 20:48:11 2010 -0800
@@ -40,7 +40,7 @@
   private static int JVM_CONSTANT_NameAndType             = 12;
   private static int JVM_CONSTANT_MethodHandle            = 15;  // JSR 292
   private static int JVM_CONSTANT_MethodType              = 16;  // JSR 292
-  //      static int JVM_CONSTANT_InvokeDynamicTrans      = 17;  // JSR 292, only occurs in old class files
+  private static int JVM_CONSTANT_InvokeDynamicTrans      = 17;  // JSR 292, only occurs in old class files
   private static int JVM_CONSTANT_InvokeDynamic           = 18;  // JSR 292
   private static int JVM_CONSTANT_Invalid                 = 0;   // For bad value initialization
   private static int JVM_CONSTANT_UnresolvedClass         = 100; // Temporary tag until actual use
@@ -67,6 +67,8 @@
     this.tag = tag;
   }
 
+  public int value() { return tag; }
+
   public boolean isKlass()            { return tag == JVM_CONSTANT_Class; }
   public boolean isField ()           { return tag == JVM_CONSTANT_Fieldref; }
   public boolean isMethod()           { return tag == JVM_CONSTANT_Methodref; }
@@ -81,6 +83,7 @@
   public boolean isMethodHandle()     { return tag == JVM_CONSTANT_MethodHandle; }
   public boolean isMethodType()       { return tag == JVM_CONSTANT_MethodType; }
   public boolean isInvokeDynamic()    { return tag == JVM_CONSTANT_InvokeDynamic; }
+  public boolean isInvokeDynamicTrans() { return tag == JVM_CONSTANT_InvokeDynamicTrans; }
 
   public boolean isInvalid()          { return tag == JVM_CONSTANT_Invalid; }
 
--- a/make/linux/makefiles/build_vm_def.sh	Thu Dec 16 20:35:33 2010 -0800
+++ b/make/linux/makefiles/build_vm_def.sh	Thu Dec 16 20:48:11 2010 -0800
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 # If we're cross compiling use that path for nm
-if [ "$ALT_COMPILER_PATH" != "" ]; then 
+if [ "$CROSS_COMPILE_ARCH" != "" ]; then 
 NM=$ALT_COMPILER_PATH/nm
 else
 NM=nm
--- a/make/linux/makefiles/buildtree.make	Thu Dec 16 20:35:33 2010 -0800
+++ b/make/linux/makefiles/buildtree.make	Thu Dec 16 20:48:11 2010 -0800
@@ -124,7 +124,7 @@
 BUILDTREE_MAKE	= $(GAMMADIR)/make/$(OS_FAMILY)/makefiles/buildtree.make
 
 BUILDTREE_TARGETS = Makefile flags.make flags_vm.make vm.make adlc.make jvmti.make sa.make \
-        env.sh env.csh .dbxrc test_gamma
+        env.sh env.csh jdkpath.sh .dbxrc test_gamma
 
 BUILDTREE_VARS	= GAMMADIR=$(GAMMADIR) OS_FAMILY=$(OS_FAMILY) \
 	ARCH=$(ARCH) BUILDARCH=$(BUILDARCH) LIBARCH=$(LIBARCH) VARIANT=$(VARIANT)
@@ -318,6 +318,13 @@
 	sed -n 's/^\([A-Za-z_][A-Za-z0-9_]*\)=/setenv \1 /p' $?; \
 	) > $@
 
+jdkpath.sh: $(BUILDTREE_MAKE)
+	@echo Creating $@ ...
+	$(QUIETLY) ( \
+	$(BUILDTREE_COMMENT); \
+	echo "JDK=${JAVA_HOME}"; \
+	) > $@	   
+
 .dbxrc:  $(BUILDTREE_MAKE)
 	@echo Creating $@ ...
 	$(QUIETLY) ( \
--- a/make/linux/makefiles/gcc.make	Thu Dec 16 20:35:33 2010 -0800
+++ b/make/linux/makefiles/gcc.make	Thu Dec 16 20:48:11 2010 -0800
@@ -25,7 +25,9 @@
 #------------------------------------------------------------------------
 # CC, CPP & AS
 
-ifdef ALT_COMPILER_PATH
+# When cross-compiling the ALT_COMPILER_PATH points
+# to the cross-compilation toolset
+ifdef CROSS_COMPILE_ARCH
 CPP = $(ALT_COMPILER_PATH)/g++
 CC  = $(ALT_COMPILER_PATH)/gcc
 else
--- a/make/linux/makefiles/vm.make	Thu Dec 16 20:35:33 2010 -0800
+++ b/make/linux/makefiles/vm.make	Thu Dec 16 20:48:11 2010 -0800
@@ -168,7 +168,9 @@
 
 # Locate all source files in the given directory, excluding files in Src_Files_EXCLUDE.
 define findsrc
-	$(notdir $(shell find $(1) \( -name \*.c -o -name \*.cpp -o -name \*.s \) -a \! \( -name DUMMY $(addprefix -o -name ,$(Src_Files_EXCLUDE)) \) ))
+	$(notdir $(shell find $(1)/. ! -name . -prune \
+		-a \( -name \*.c -o -name \*.cpp -o -name \*.s \) \
+		-a ! \( -name DUMMY $(addprefix -o -name ,$(Src_Files_EXCLUDE)) \)))
 endef
 
 Src_Files := $(foreach e,$(Src_Dirs),$(call findsrc,$(e)))
--- a/make/solaris/makefiles/buildtree.make	Thu Dec 16 20:35:33 2010 -0800
+++ b/make/solaris/makefiles/buildtree.make	Thu Dec 16 20:48:11 2010 -0800
@@ -117,7 +117,7 @@
 BUILDTREE_MAKE	= $(GAMMADIR)/make/$(OS_FAMILY)/makefiles/buildtree.make
 
 BUILDTREE_TARGETS = Makefile flags.make flags_vm.make vm.make adlc.make jvmti.make sa.make \
-        env.ksh env.csh .dbxrc test_gamma
+        env.ksh env.csh jdkpath.sh .dbxrc test_gamma
 
 BUILDTREE_VARS	= GAMMADIR=$(GAMMADIR) OS_FAMILY=$(OS_FAMILY) \
 	ARCH=$(ARCH) BUILDARCH=$(BUILDARCH) LIBARCH=$(LIBARCH) VARIANT=$(VARIANT)
@@ -314,6 +314,13 @@
 	sed -n 's/^\([A-Za-z_][A-Za-z0-9_]*\)=/setenv \1 /p' $?; \
 	) > $@
 
+jdkpath.sh: $(BUILDTREE_MAKE)
+	@echo Creating $@ ...
+	$(QUIETLY) ( \
+	$(BUILDTREE_COMMENT); \
+	echo "JDK=${JAVA_HOME}"; \
+	) > $@	   
+
 .dbxrc:  $(BUILDTREE_MAKE)
 	@echo Creating $@ ...
 	$(QUIETLY) ( \
--- a/make/solaris/makefiles/vm.make	Thu Dec 16 20:35:33 2010 -0800
+++ b/make/solaris/makefiles/vm.make	Thu Dec 16 20:48:11 2010 -0800
@@ -106,17 +106,17 @@
 # Not sure what the 'designed for' comment is referring too above.
 #   The order may not be too significant anymore, but I have placed this
 #   older libm before libCrun, just to make sure it's found and used first.
-LIBS += -lsocket -lsched -ldl $(LIBM) -lCrun -lthread -ldoor -lc
+LIBS += -lsocket -lsched -ldl $(LIBM) -lCrun -lthread -ldoor -lc -ldemangle
 else
 ifeq ($(COMPILER_REV_NUMERIC), 502)
 # SC6.1 has it's own libm.so: specifying anything else provokes a name conflict.
-LIBS += -ldl -lthread -lsocket -lm -lsched -ldoor
+LIBS += -ldl -lthread -lsocket -lm -lsched -ldoor -ldemangle
 else
-LIBS += -ldl -lthread -lsocket $(LIBM) -lsched -ldoor
+LIBS += -ldl -lthread -lsocket $(LIBM) -lsched -ldoor -ldemangle
 endif # 502
 endif # 505
 else
-LIBS += -lsocket -lsched -ldl $(LIBM) -lthread -lc
+LIBS += -lsocket -lsched -ldl $(LIBM) -lthread -lc -ldemangle
 endif # sparcWorks
 
 # By default, link the *.o into the library, not the executable.
@@ -184,7 +184,9 @@
 
 # Locate all source files in the given directory, excluding files in Src_Files_EXCLUDE.
 define findsrc
-	$(notdir $(shell find $(1) \( -name \*.c -o -name \*.cpp -o -name \*.s \) -a \! \( -name DUMMY $(addprefix -o -name ,$(Src_Files_EXCLUDE)) \) ))
+	$(notdir $(shell find $(1)/. ! -name . -prune \
+		-a \( -name \*.c -o -name \*.cpp -o -name \*.s \) \
+		-a ! \( -name DUMMY $(addprefix -o -name ,$(Src_Files_EXCLUDE)) \)))
 endef
 
 Src_Files := $(foreach e,$(Src_Dirs),$(call findsrc,$(e)))
--- a/make/windows/build_vm_def.sh	Thu Dec 16 20:35:33 2010 -0800
+++ b/make/windows/build_vm_def.sh	Thu Dec 16 20:48:11 2010 -0800
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -45,6 +45,9 @@
 echo "EXPORTS" > vm1.def
 
 AWK="$MKS_HOME/awk.exe"
+if [ ! -e $AWK ]; then
+    AWK="$MKS_HOME/gawk.exe"
+fi
 GREP="$MKS_HOME/grep.exe"
 SORT="$MKS_HOME/sort.exe"
 UNIQ="$MKS_HOME/uniq.exe"
@@ -57,7 +60,7 @@
 LINK_VER="$1"
 fi
 
-if [ "x$LINK_VER" != "x800" -a  "x$LINK_VER" != "x900" ]; then
+if [ "x$LINK_VER" != "x800" -a  "x$LINK_VER" != "x900" -a "x$LINK_VER" != "x1000" ]; then
 $DUMPBIN /symbols *.obj | "$GREP" "??_7.*@@6B@" | "$GREP" -v "type_info" | "$AWK" '{print $7}' | "$SORT" | "$UNIQ" > vm2.def
 else
 # Can't use pipes when calling cl.exe or link.exe from IDE. Using transit file vm3.def
--- a/make/windows/create.bat	Thu Dec 16 20:35:33 2010 -0800
+++ b/make/windows/create.bat	Thu Dec 16 20:48:11 2010 -0800
@@ -36,6 +36,20 @@
 REM Note: Running this batch file from the Windows command shell requires
 REM that "grep" be accessible on the PATH. An MKS install does this.
 REM 
+
+cl 2>NUL >NUL
+if %errorlevel% == 0 goto nexttest
+echo Make sure cl.exe is in your PATH before running this script.
+goto end
+
+:nexttest
+grep -V 2>NUL >NUL
+if %errorlevel% == 0 goto testit
+echo Make sure grep.exe is in your PATH before running this script. Either cygwin or MKS should work.
+goto end
+
+
+:testit
 cl 2>&1 | grep "IA-64" >NUL
 if %errorlevel% == 0 goto isia64
 cl 2>&1 | grep "AMD64" >NUL
@@ -44,37 +58,40 @@
 set BUILDARCH=i486
 set Platform_arch=x86
 set Platform_arch_model=x86_32
-goto end
+goto done
 :amd64
 set ARCH=x86
 set BUILDARCH=amd64
 set Platform_arch=x86
 set Platform_arch_model=x86_64
-goto end
+goto done
 :isia64
 set ARCH=ia64
 set BUILDARCH=ia64
 set Platform_arch=ia64
 set Platform_arch_model=ia64
-:end
+:done
 
 setlocal
 
 if "%1" == "" goto usage
 
-if not "%4" == "" goto usage
+if not "%2" == "" goto usage
 
-set HotSpotWorkSpace=%1
-set HotSpotBuildSpace=%2
-set HotSpotJDKDist=%3
+REM Set HotSpotWorkSpace to the directy two steps above this script
+for %%i in ("%~dp0..") do ( set HotSpotWorkSpace=%%~dpi)
+set HotSpotBuildRoot=%HotSpotWorkSpace%build
+set HotSpotBuildSpace=%HotSpotBuildRoot%\vs
+set HotSpotJDKDist=%1
+
 
 REM figure out MSC version
 for /F %%i in ('sh %HotSpotWorkSpace%/make/windows/get_msc_ver.sh') do set %%i
 
 echo **************************************************************
-set ProjectFile=vm.vcproj
+set ProjectFile=jvm.vcproj
 if "%MSC_VER%" == "1200" (
-set ProjectFile=vm.dsp
+set ProjectFile=jvm.dsp
 echo Will generate VC6 project {unsupported}
 ) else (
 if "%MSC_VER%" == "1400" (
@@ -83,10 +100,16 @@
 if "%MSC_VER%" == "1500" (
 echo Will generate VC9 {Visual Studio 2008}
 ) else (
+if "%MSC_VER%" == "1600" (
+echo Detected Visual Studio 2010, but
+echo will generate VC9 {Visual Studio 2008}
+echo Use conversion wizard in VS 2010.
+) else (
 echo Will generate VC7 project {Visual Studio 2003 .NET}
 )
 )
 )
+)
 echo                            %ProjectFile%
 echo **************************************************************
 
@@ -118,6 +141,8 @@
 
 :test3
 if not "%HOTSPOTMKSHOME%" == "" goto makedir
+if exist c:\cygwin\bin set HOTSPOTMKSHOME=c:\cygwin\bin
+if not "%HOTSPOTMKSHOME%" == "" goto makedir
 echo Warning: please set variable HOTSPOTMKSHOME to place where 
 echo          your MKS/Cygwin installation is
 echo.
@@ -133,21 +158,24 @@
 REM This is now safe to do.
 :copyfiles
 for /D %%i in (compiler1, compiler2, tiered, core, kernel) do (
-if NOT EXIST %HotSpotBuildSpace%\%%i mkdir %HotSpotBuildSpace%\%%i
-copy %HotSpotWorkSpace%\make\windows\projectfiles\%%i\* %HotSpotBuildSpace%\%%i\ > NUL
+if NOT EXIST %HotSpotBuildSpace%\%%i\generated mkdir %HotSpotBuildSpace%\%%i\generated
+copy %HotSpotWorkSpace%\make\windows\projectfiles\%%i\* %HotSpotBuildSpace%\%%i\generated > NUL
 )
 
 REM force regneration of ProjectFile
 if exist %HotSpotBuildSpace%\%ProjectFile% del %HotSpotBuildSpace%\%ProjectFile%
 
 for /D %%i in (compiler1, compiler2, tiered, core, kernel) do (
-
-echo # Generated file!                                                 >    %HotSpotBuildSpace%\%%i\local.make
+echo -- %%i --
+echo # Generated file!                                                        >    %HotSpotBuildSpace%\%%i\local.make
 echo # Changing a variable below and then deleting %ProjectFile% will cause  >>    %HotSpotBuildSpace%\%%i\local.make
 echo # %ProjectFile% to be regenerated with the new values.  Changing the    >>    %HotSpotBuildSpace%\%%i\local.make
-echo # version requires rerunning create.bat.                         >>    %HotSpotBuildSpace%\%%i\local.make
+echo # version requires rerunning create.bat.                                >>    %HotSpotBuildSpace%\%%i\local.make
 echo.                                      >>    %HotSpotBuildSpace%\%%i\local.make
+echo Variant=%%i			   >>    %HotSpotBuildSpace%\%%i\local.make
+echo WorkSpace=%HotSpotWorkSpace%   	   >>    %HotSpotBuildSpace%\%%i\local.make
 echo HOTSPOTWORKSPACE=%HotSpotWorkSpace%   >>    %HotSpotBuildSpace%\%%i\local.make
+echo HOTSPOTBUILDROOT=%HotSpotBuildRoot%   >>    %HotSpotBuildSpace%\%%i\local.make
 echo HOTSPOTBUILDSPACE=%HotSpotBuildSpace% >>    %HotSpotBuildSpace%\%%i\local.make
 echo HOTSPOTJDKDIST=%HotSpotJDKDist%       >>    %HotSpotBuildSpace%\%%i\local.make
 echo ARCH=%ARCH%                           >>    %HotSpotBuildSpace%\%%i\local.make
@@ -155,42 +183,35 @@
 echo Platform_arch=%Platform_arch%         >>    %HotSpotBuildSpace%\%%i\local.make
 echo Platform_arch_model=%Platform_arch_model% >>    %HotSpotBuildSpace%\%%i\local.make
 
-pushd %HotSpotBuildSpace%\%%i
+for /D %%j in (debug, fastdebug, product) do (
+if NOT EXIST %HotSpotBuildSpace%\%%i\%%j mkdir %HotSpotBuildSpace%\%%i\%%j
+)
+
+pushd %HotSpotBuildSpace%\%%i\generated
 nmake /nologo
 popd
 
 )
 
-pushd %HotSpotBuildSpace%
+pushd %HotSpotBuildRoot%
 
-echo # Generated file!                                                 >    local.make
-echo # Changing a variable below and then deleting %ProjectFile% will cause  >>    local.make
-echo # %ProjectFile% to be regenerated with the new values.  Changing the    >>    local.make
-echo # version requires rerunning create.bat.                         >>    local.make
-echo.                                      >>    local.make
-echo HOTSPOTWORKSPACE=%HotSpotWorkSpace%   >>    local.make
-echo HOTSPOTBUILDSPACE=%HotSpotBuildSpace% >>    local.make
-echo HOTSPOTJDKDIST=%HotSpotJDKDist%       >>    local.make
-echo ARCH=%ARCH%                           >>    local.make
-echo BUILDARCH=%BUILDARCH%                 >>    local.make
-echo Platform_arch=%Platform_arch%         >>    local.make
-echo Platform_arch_model=%Platform_arch_model% >>    local.make
-
-nmake /nologo /F %HotSpotWorkSpace%/make/windows/projectfiles/common/Makefile %HotSpotBuildSpace%/%ProjectFile%
+REM It doesn't matter which variant we use here, "compiler1" is as good as any of the others - we need the common variables
+nmake /nologo /F %HotSpotWorkSpace%/make/windows/projectfiles/common/Makefile LOCAL_MAKE=%HotSpotBuildSpace%\compiler1\local.make %HotSpotBuildRoot%/%ProjectFile%
 
 popd
 
 goto end
 
 :usage
-echo Usage: create HotSpotWorkSpace HotSpotBuildSpace HotSpotJDKDist
+echo Usage: create HotSpotJDKDist
 echo.
-echo This is the interactive build setup script (as opposed to the batch
-echo build execution script). It creates HotSpotBuildSpace if necessary,
-echo copies the appropriate files out of HotSpotWorkSpace into it, and
+echo This is the VS build setup script (as opposed to the batch
+echo build execution script). It creates a build directory if necessary,
+echo copies the appropriate files out of the workspace into it, and
 echo builds and runs ProjectCreator in it. This has the side-effect of creating
 echo the %ProjectFile% file in the build space, which is then used in Visual C++.
-echo The HotSpotJDKDist defines place where JVM binaries should be placed.
+echo.
+echo The HotSpotJDKDist defines the JDK that should be used when running the JVM.
 echo Environment variable FORCE_MSC_VER allows to override MSVC version autodetection.
 echo.
 echo NOTE that it is now NOT safe to modify any of the files in the build
--- a/make/windows/create_obj_files.sh	Thu Dec 16 20:35:33 2010 -0800
+++ b/make/windows/create_obj_files.sh	Thu Dec 16 20:48:11 2010 -0800
@@ -107,8 +107,12 @@
 	"x86_64") Src_Files_EXCLUDE="${Src_Files_EXCLUDE} *x86_32*" ;;
 esac
 
+# Locate all source files in the given directory, excluding files in Src_Files_EXCLUDE.
 function findsrc {
-    $FIND ${1} \( -name \*.c -o -name \*.cpp -o -name \*.s \) -a \! \( -name ${Src_Files_EXCLUDE// / -o -name } \) | sed 's/.*\/\(.*\)/\1/';
+    $FIND ${1}/. ! -name . -prune \
+		-a \( -name \*.c -o -name \*.cpp -o -name \*.s \) \
+		-a \! \( -name ${Src_Files_EXCLUDE// / -o -name } \) \
+		| sed 's/.*\/\(.*\)/\1/';
 }
 
 Src_Files=
--- a/make/windows/makefiles/adlc.make	Thu Dec 16 20:35:33 2010 -0800
+++ b/make/windows/makefiles/adlc.make	Thu Dec 16 20:48:11 2010 -0800
@@ -22,7 +22,6 @@
 #  
 #
 
-!include $(WorkSpace)/make/windows/makefiles/compile.make
 
 # Rules for building adlc.exe
 
@@ -46,15 +45,7 @@
 ADLCFLAGS=-q -T -U_LP64
 !endif
 
-CPP_FLAGS=$(CPP_FLAGS) \
-  /D TARGET_OS_FAMILY_windows \
-  /D TARGET_ARCH_$(Platform_arch) \
-  /D TARGET_ARCH_MODEL_$(Platform_arch_model) \
-  /D TARGET_OS_ARCH_windows_$(Platform_arch) \
-  /D TARGET_OS_ARCH_MODEL_windows_$(Platform_arch_model) \
-  /D TARGET_COMPILER_visCPP
-
-CPP_FLAGS=$(CPP_FLAGS) /D _CRT_SECURE_NO_WARNINGS /D _CRT_SECURE_NO_DEPRECATE
+ADLC_CPP_FLAGS=$(CPP_FLAGS) /D _CRT_SECURE_NO_WARNINGS /D _CRT_SECURE_NO_DEPRECATE
 
 CPP_INCLUDE_DIRS=\
   /I "..\generated" \
@@ -92,10 +83,10 @@
   $(AdlcOutDir)\dfa_$(Platform_arch_model).cpp
 
 {$(WorkSpace)\src\share\vm\adlc}.cpp.obj::
-        $(CPP) $(CPP_FLAGS) $(EXH_FLAGS) $(CPP_INCLUDE_DIRS) /c $<
+        $(CPP) $(ADLC_CPP_FLAGS) $(EXH_FLAGS) $(CPP_INCLUDE_DIRS) /c $<
 
 {$(WorkSpace)\src\share\vm\opto}.cpp.obj::
-        $(CPP) $(CPP_FLAGS) $(EXH_FLAGS) $(CPP_INCLUDE_DIRS) /c $<
+        $(CPP) $(ADLC_CPP_FLAGS) $(EXH_FLAGS) $(CPP_INCLUDE_DIRS) /c $<
 
 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
--- a/make/windows/makefiles/compile.make	Thu Dec 16 20:35:33 2010 -0800
+++ b/make/windows/makefiles/compile.make	Thu Dec 16 20:48:11 2010 -0800
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -80,6 +80,20 @@
 CPP=ARCH_ERROR
 !endif
 
+CPP_FLAGS=$(CPP_FLAGS) /D "WIN32" /D "_WINDOWS"
+
+# Must specify this for sharedRuntimeTrig.cpp
+CPP_FLAGS=$(CPP_FLAGS) /D "VM_LITTLE_ENDIAN"
+
+# Used for platform dispatching
+CPP_FLAGS=$(CPP_FLAGS) /D TARGET_OS_FAMILY_windows
+CPP_FLAGS=$(CPP_FLAGS) /D TARGET_ARCH_$(Platform_arch)
+CPP_FLAGS=$(CPP_FLAGS) /D TARGET_ARCH_MODEL_$(Platform_arch_model)
+CPP_FLAGS=$(CPP_FLAGS) /D TARGET_OS_ARCH_windows_$(Platform_arch)
+CPP_FLAGS=$(CPP_FLAGS) /D TARGET_OS_ARCH_MODEL_windows_$(Platform_arch_model)
+CPP_FLAGS=$(CPP_FLAGS) /D TARGET_COMPILER_visCPP
+
+
 # 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
--- a/make/windows/makefiles/debug.make	Thu Dec 16 20:35:33 2010 -0800
+++ b/make/windows/makefiles/debug.make	Thu Dec 16 20:48:11 2010 -0800
@@ -26,7 +26,6 @@
 HS_FNAME=$(HS_INTERNAL_NAME).dll
 AOUT=$(HS_FNAME)
 SAWINDBG=sawindbg.dll
-LAUNCHER_NAME=hotspot.exe
 GENERATED=../generated
 
 # Allow the user to turn off precompiled headers from the command line.
@@ -34,7 +33,7 @@
 BUILD_PCH_FILE=_build_pch_file.obj
 !endif
 
-default:: $(BUILD_PCH_FILE) $(AOUT) $(LAUNCHER_NAME) checkAndBuildSA
+default:: $(BUILD_PCH_FILE) $(AOUT) launcher checkAndBuildSA
 
 !include ../local.make
 !include compile.make
@@ -49,8 +48,10 @@
 # Force resources to be rebuilt every time
 $(Res_Files): FORCE
 
-$(AOUT): $(Res_Files) $(Obj_Files)
+vm.def: $(Obj_Files)
 	sh $(WorkSpace)/make/windows/build_vm_def.sh
+
+$(AOUT): $(Res_Files) $(Obj_Files) vm.def
 	$(LINK) @<<
   $(LINK_FLAGS) /out:$@ /implib:$*.lib /def:vm.def $(Obj_Files) $(Res_Files)
 <<
--- a/make/windows/makefiles/fastdebug.make	Thu Dec 16 20:35:33 2010 -0800
+++ b/make/windows/makefiles/fastdebug.make	Thu Dec 16 20:48:11 2010 -0800
@@ -26,7 +26,6 @@
 HS_FNAME=$(HS_INTERNAL_NAME).dll
 AOUT=$(HS_FNAME)
 SAWINDBG=sawindbg.dll
-LAUNCHER_NAME=hotspot.exe
 GENERATED=../generated
 
 # Allow the user to turn off precompiled headers from the command line.
@@ -34,7 +33,7 @@
 BUILD_PCH_FILE=_build_pch_file.obj
 !endif
 
-default:: $(BUILD_PCH_FILE) $(AOUT) $(LAUNCHER_NAME) checkAndBuildSA
+default:: $(BUILD_PCH_FILE) $(AOUT) launcher checkAndBuildSA
 
 !include ../local.make
 !include compile.make
@@ -49,8 +48,10 @@
 # Force resources to be rebuilt every time
 $(Res_Files): FORCE
 
-$(AOUT): $(Res_Files) $(Obj_Files)
+vm.def: $(Obj_Files)
 	sh $(WorkSpace)/make/windows/build_vm_def.sh
+
+$(AOUT): $(Res_Files) $(Obj_Files) vm.def
 	$(LINK) @<<
   $(LINK_FLAGS) /out:$@ /implib:$*.lib /def:vm.def $(Obj_Files) $(Res_Files)
 <<
--- a/make/windows/makefiles/generated.make	Thu Dec 16 20:35:33 2010 -0800
+++ b/make/windows/makefiles/generated.make	Thu Dec 16 20:48:11 2010 -0800
@@ -51,6 +51,7 @@
 
 !if ("$(Variant)" == "compiler2") || ("$(Variant)" == "tiered")
 
+!include $(WorkSpace)/make/windows/makefiles/compile.make
 !include $(WorkSpace)/make/windows/makefiles/adlc.make
 
 !endif
--- a/make/windows/makefiles/launcher.make	Thu Dec 16 20:35:33 2010 -0800
+++ b/make/windows/makefiles/launcher.make	Thu Dec 16 20:48:11 2010 -0800
@@ -22,7 +22,8 @@
 #  
 #
 
-LAUNCHER_FLAGS=$(ARCHFLAG) \
+
+LAUNCHER_FLAGS=$(CPP_FLAGS) $(ARCHFLAG) \
 	/D FULL_VERSION=\"$(HOTSPOT_RELEASE_VERSION)\" \
 	/D JDK_MAJOR_VERSION=\"$(JDK_MAJOR_VERSION)\" \
 	/D JDK_MINOR_VERSION=\"$(JDK_MINOR_VERSION)\" \
@@ -32,9 +33,11 @@
 	/D _CRT_SECURE_NO_DEPRECATE \
 	/D LINK_INTO_LIBJVM \
 	/I $(WorkSpace)\src\os\windows\launcher \
-	/I $(WorkSpace)\src\share\tools\launcher
-
-CPP_FLAGS=$(CPP_FLAGS) $(LAUNCHER_FLAGS)
+	/I $(WorkSpace)\src\share\tools\launcher \
+	/I $(WorkSpace)\src\share\vm\prims \
+	/I $(WorkSpace)\src\share\vm \
+	/I $(WorkSpace)\src\cpu\$(Platform_arch)\vm \
+	/I $(WorkSpace)\src\os\windows\vm
 
 LINK_FLAGS=/manifest $(HS_INTERNAL_NAME).lib kernel32.lib user32.lib /nologo /machine:$(MACHINE) /map /debug /subsystem:console 
 
@@ -46,22 +49,23 @@
 LINK_FLAGS = $(LINK_FLAGS) $(BUFFEROVERFLOWLIB)
 !endif
 
-LAUNCHERDIR = $(GAMMADIR)/src/os/windows/launcher
-LAUNCHERDIR_SHARE = $(GAMMADIR)/src/share/tools/launcher
+LAUNCHERDIR = $(WorkSpace)/src/os/windows/launcher
+LAUNCHERDIR_SHARE = $(WorkSpace)/src/share/tools/launcher
 
 OUTDIR = launcher
 
 {$(LAUNCHERDIR)}.c{$(OUTDIR)}.obj:
-	-mkdir $(OUTDIR)
-        $(CPP) $(CPP_FLAGS) /c /Fo$@ $<
+	-mkdir $(OUTDIR) 2>NUL >NUL
+        $(CPP) $(LAUNCHER_FLAGS) /c /Fo$@ $<
 
 {$(LAUNCHERDIR_SHARE)}.c{$(OUTDIR)}.obj:
-	-mkdir $(OUTDIR)
-        $(CPP) $(CPP_FLAGS) /c /Fo$@ $<
+	-mkdir $(OUTDIR) 2>NUL >NUL
+        $(CPP) $(LAUNCHER_FLAGS) /c /Fo$@ $<
 
 $(OUTDIR)\*.obj: $(LAUNCHERDIR)\*.c $(LAUNCHERDIR)\*.h $(LAUNCHERDIR_SHARE)\*.c $(LAUNCHERDIR_SHARE)\*.h
 
-$(LAUNCHER_NAME): $(OUTDIR)\java.obj $(OUTDIR)\java_md.obj $(OUTDIR)\jli_util.obj
-	$(LINK) $(LINK_FLAGS) /out:$@ $**
+launcher: $(OUTDIR)\java.obj $(OUTDIR)\java_md.obj $(OUTDIR)\jli_util.obj
+	echo $(JAVA_HOME) > jdkpath.txt  
+	$(LINK) $(LINK_FLAGS) /out:hotspot.exe $**
 
 
--- a/make/windows/makefiles/product.make	Thu Dec 16 20:35:33 2010 -0800
+++ b/make/windows/makefiles/product.make	Thu Dec 16 20:48:11 2010 -0800
@@ -25,7 +25,6 @@
 HS_INTERNAL_NAME=jvm
 HS_FNAME=$(HS_INTERNAL_NAME).dll
 AOUT=$(HS_FNAME)
-LAUNCHER_NAME=hotspot.exe
 GENERATED=../generated
 
 # Allow the user to turn off precompiled headers from the command line.
@@ -33,7 +32,7 @@
 BUILD_PCH_FILE=_build_pch_file.obj
 !endif
 
-default:: $(BUILD_PCH_FILE) $(AOUT) $(LAUNCHER_NAME) checkAndBuildSA
+default:: $(BUILD_PCH_FILE) $(AOUT) launcher checkAndBuildSA
 
 !include ../local.make
 !include compile.make
@@ -59,8 +58,10 @@
   $(LINK_FLAGS) /out:$@ /implib:$*.lib $(Obj_Files) $(Res_Files)
 <<
 !else
-$(AOUT): $(Res_Files) $(Obj_Files)
+vm.def: $(Obj_Files)
 	sh $(WorkSpace)/make/windows/build_vm_def.sh
+
+$(AOUT): $(Res_Files) $(Obj_Files) vm.def
 	$(LINK) @<<
   $(LINK_FLAGS) /out:$@ /implib:$*.lib /def:vm.def $(Obj_Files) $(Res_Files)
 <<
--- a/make/windows/makefiles/projectcreator.make	Thu Dec 16 20:35:33 2010 -0800
+++ b/make/windows/makefiles/projectcreator.make	Thu Dec 16 20:48:11 2010 -0800
@@ -84,11 +84,12 @@
         -buildBase $(HOTSPOTBUILDSPACE)\%f\%b \
         -startAt src \
         -compiler $(VcVersion) \
-        -projectFileName $(HOTSPOTBUILDSPACE)\$(ProjectFile) \
+        -projectFileName $(HOTSPOTBUILDROOT)\$(ProjectFile) \
         -jdkTargetRoot $(HOTSPOTJDKDIST) \
         -define ALIGN_STACK_FRAMES \
         -define VM_LITTLE_ENDIAN \
         -prelink  "" "Generating vm.def..." "cd $(HOTSPOTBUILDSPACE)\%f\%b	set HOTSPOTMKSHOME=$(HOTSPOTMKSHOME)	$(HOTSPOTMKSHOME)\sh $(HOTSPOTWORKSPACE)\make\windows\build_vm_def.sh $(LINK_VER)" \
+        -postbuild "" "Building hotspot.exe..." "cd $(HOTSPOTBUILDSPACE)\%f\%b	set HOTSPOTMKSHOME=$(HOTSPOTMKSHOME)	nmake -f $(HOTSPOTWORKSPACE)\make\windows\projectfiles\common\Makefile LOCAL_MAKE=$(HOTSPOTBUILDSPACE)\%f\local.make JAVA_HOME=$(HOTSPOTJDKDIST) launcher" \
         -ignoreFile jsig.c \
         -ignoreFile jvmtiEnvRecommended.cpp \
         -ignoreFile jvmtiEnvStub.cpp \
--- a/make/windows/makefiles/rules.make	Thu Dec 16 20:35:33 2010 -0800
+++ b/make/windows/makefiles/rules.make	Thu Dec 16 20:48:11 2010 -0800
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2003, 2009, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -48,7 +48,7 @@
 JAVAC_FLAGS=-g -encoding ascii
 BOOTSTRAP_JAVAC_FLAGS=$(JAVAC_FLAGS) -source $(BOOT_SOURCE_LANGUAGE_VERSION) -target $(BOOT_TARGET_CLASS_VERSION)
 
-ProjectFile=vm.vcproj
+ProjectFile=jvm.vcproj
 
 !if "$(MSC_VER)" == "1200"
 
@@ -63,6 +63,11 @@
 
 VcVersion=VC9
 
+!elseif "$(MSC_VER)" == "1600"
+
+# for compatibility - we don't yet have a ProjectCreator for VC10
+VcVersion=VC9
+
 !else
 
 VcVersion=VC7
--- a/make/windows/makefiles/vm.make	Thu Dec 16 20:35:33 2010 -0800
+++ b/make/windows/makefiles/vm.make	Thu Dec 16 20:48:11 2010 -0800
@@ -71,22 +71,11 @@
 CPP_FLAGS=$(CPP_FLAGS) /D "HOTSPOT_BUILD_USER=\"$(BuildUser)\""
 CPP_FLAGS=$(CPP_FLAGS) /D "HOTSPOT_VM_DISTRO=\"$(HOTSPOT_VM_DISTRO)\""
 
-CPP_FLAGS=$(CPP_FLAGS) /D "WIN32" /D "_WINDOWS" $(CPP_INCLUDE_DIRS)
-
-# Must specify this for sharedRuntimeTrig.cpp
-CPP_FLAGS=$(CPP_FLAGS) /D "VM_LITTLE_ENDIAN"
+CPP_FLAGS=$(CPP_FLAGS) $(CPP_INCLUDE_DIRS)
 
 # Define that so jni.h is on correct side
 CPP_FLAGS=$(CPP_FLAGS) /D "_JNI_IMPLEMENTATION_"
 
-# Used for platform dispatching
-CPP_FLAGS=$(CPP_FLAGS) /D TARGET_OS_FAMILY_windows
-CPP_FLAGS=$(CPP_FLAGS) /D TARGET_ARCH_$(Platform_arch)
-CPP_FLAGS=$(CPP_FLAGS) /D TARGET_ARCH_MODEL_$(Platform_arch_model)
-CPP_FLAGS=$(CPP_FLAGS) /D TARGET_OS_ARCH_windows_$(Platform_arch)
-CPP_FLAGS=$(CPP_FLAGS) /D TARGET_OS_ARCH_MODEL_windows_$(Platform_arch_model)
-CPP_FLAGS=$(CPP_FLAGS) /D TARGET_COMPILER_visCPP
-
 !if "$(BUILDARCH)" == "ia64"
 STACK_SIZE="/STACK:1048576,262144"
 !else
@@ -104,6 +93,8 @@
 !endif
 !endif
 
+# If you modify exports below please do the corresponding changes in
+# src/share/tools/ProjectCreator/WinGammaPlatformVC7.java 
 LINK_FLAGS=$(LINK_FLAGS) $(STACK_SIZE) /subsystem:windows /dll /base:0x8000000 \
   /export:JNI_GetDefaultJavaVMInitArgs       \
   /export:JNI_CreateJavaVM                   \
--- a/make/windows/projectfiles/common/Makefile	Thu Dec 16 20:35:33 2010 -0800
+++ b/make/windows/projectfiles/common/Makefile	Thu Dec 16 20:48:11 2010 -0800
@@ -22,7 +22,10 @@
 #  
 #
 
-!include local.make
+!ifdef LOCAL_MAKE
+!include $(LOCAL_MAKE)
+!endif
+
 
 WorkSpace=$(HOTSPOTWORKSPACE)
 
@@ -34,11 +37,18 @@
 !else
 !ifdef JAVA_HOME
 BootStrapDir=$(JAVA_HOME)
+!else
+!ifdef HOTSPOTJDKDIST
+BootStrapDir=$(HOTSPOTJDKDIST)
+!endif
 !endif
 !endif
 !endif
 
+
+
 !include $(HOTSPOTWORKSPACE)/make/windows/makefiles/projectcreator.make
+!include $(WorkSpace)/make/windows/makefiles/compile.make
 
 # Pick up rules for building JVMTI (JSR-163)
 JvmtiOutDir=$(HOTSPOTBUILDSPACE)\$(Variant)\generated\jvmtifiles
@@ -56,6 +66,9 @@
 !include $(HOTSPOTWORKSPACE)/make/windows/makefiles/adlc.make
 !endif
 
+HS_INTERNAL_NAME=jvm
+!include $(HOTSPOTWORKSPACE)/make/windows/makefiles/launcher.make
+
 default:: $(AdditionalTargets) $(JvmtiGeneratedFiles)
 
 !include $(HOTSPOTWORKSPACE)/make/hotspot_version
@@ -97,7 +110,7 @@
       -define              JRE_RELEASE_VERSION=\\\"$(JRE_RELEASE_VERSION)\\\" \
       -define              HOTSPOT_VM_DISTRO=\\\"$(HOTSPOT_VM_DISTRO)\\\"
 
-$(HOTSPOTBUILDSPACE)/$(ProjectFile): local.make $(HOTSPOTBUILDSPACE)/classes/ProjectCreator.class
+$(HOTSPOTBUILDROOT)/$(ProjectFile): $(HOTSPOTBUILDSPACE)/classes/ProjectCreator.class
 	@$(RUN_JAVA) -Djava.class.path=$(HOTSPOTBUILDSPACE)/classes ProjectCreator WinGammaPlatform$(VcVersion) $(ProjectCreatorIDEOptions)
 
 clean:
--- a/make/windows/projectfiles/compiler1/Makefile	Thu Dec 16 20:35:33 2010 -0800
+++ b/make/windows/projectfiles/compiler1/Makefile	Thu Dec 16 20:48:11 2010 -0800
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -22,7 +22,6 @@
 #  
 #
 
-Variant=compiler1
-!include local.make
+!include ../local.make
 
 !include $(HOTSPOTWORKSPACE)/make/windows/projectfiles/common/Makefile
--- a/make/windows/projectfiles/compiler1/vm.def	Thu Dec 16 20:35:33 2010 -0800
+++ b/make/windows/projectfiles/compiler1/vm.def	Thu Dec 16 20:48:11 2010 -0800
@@ -2,6 +2,6 @@
 ; This .DEF file is a placeholder for one which is automatically
 ; generated during the build process. See
 ; make\windows\build_vm_def.sh and
-; make\windows\makefiles\makedeps.make (esp. the "-prelink"
+; make\windows\makefiles\projectcreator.make (esp. the "-prelink"
 ; options).
 ;
--- a/make/windows/projectfiles/compiler2/Makefile	Thu Dec 16 20:35:33 2010 -0800
+++ b/make/windows/projectfiles/compiler2/Makefile	Thu Dec 16 20:48:11 2010 -0800
@@ -22,8 +22,7 @@
 #  
 #
 
-Variant=compiler2
-!include local.make
+!include ../local.make
 AdlcOutDir=$(HOTSPOTBUILDSPACE)\$(Variant)\generated\adfiles
 AdditionalTargets=$(AdlcOutDir)\ad_$(Platform_arch_model).cpp $(AdlcOutDir)\dfa_$(Platform_arch_model).cpp
 
--- a/make/windows/projectfiles/compiler2/vm.def	Thu Dec 16 20:35:33 2010 -0800
+++ b/make/windows/projectfiles/compiler2/vm.def	Thu Dec 16 20:48:11 2010 -0800
@@ -2,6 +2,6 @@
 ; This .DEF file is a placeholder for one which is automatically
 ; generated during the build process. See
 ; make\windows\build_vm_def.sh and
-; make\windows\makefiles\makedeps.make (esp. the "-prelink"
+; make\windows\makefiles\projectcreator.make (esp. the "-prelink"
 ; options).
 ;
--- a/make/windows/projectfiles/core/Makefile	Thu Dec 16 20:35:33 2010 -0800
+++ b/make/windows/projectfiles/core/Makefile	Thu Dec 16 20:48:11 2010 -0800
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -22,7 +22,6 @@
 #  
 #
 
-Variant=core
-!include local.make
+!include ../local.make
 
 !include $(HOTSPOTWORKSPACE)/make/windows/projectfiles/common/Makefile
--- a/make/windows/projectfiles/core/vm.def	Thu Dec 16 20:35:33 2010 -0800
+++ b/make/windows/projectfiles/core/vm.def	Thu Dec 16 20:48:11 2010 -0800
@@ -2,6 +2,6 @@
 ; This .DEF file is a placeholder for one which is automatically
 ; generated during the build process. See
 ; make\windows\build_vm_def.sh and
-; make\windows\makefiles\makedeps.make (esp. the "-prelink"
+; make\windows\makefiles\projectcreator.make (esp. the "-prelink"
 ; options).
 ;
--- a/make/windows/projectfiles/kernel/Makefile	Thu Dec 16 20:35:33 2010 -0800
+++ b/make/windows/projectfiles/kernel/Makefile	Thu Dec 16 20:48:11 2010 -0800
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2007, 2010 Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #   
 # This code is free software; you can redistribute it and/or modify it
@@ -22,7 +22,6 @@
 #  
 #
 
-Variant=kernel
-!include local.make
+!include ../local.make
 
 !include $(HOTSPOTWORKSPACE)/make/windows/projectfiles/common/Makefile
--- a/make/windows/projectfiles/kernel/vm.def	Thu Dec 16 20:35:33 2010 -0800
+++ b/make/windows/projectfiles/kernel/vm.def	Thu Dec 16 20:48:11 2010 -0800
@@ -2,6 +2,6 @@
 ; This .DEF file is a placeholder for one which is automatically
 ; generated during the build process. See
 ; make\windows\build_vm_def.sh and
-; make\windows\makefiles\makedeps.make (esp. the "-prelink"
+; make\windows\makefiles\projectcreator.make (esp. the "-prelink"
 ; options).
 ;
--- a/make/windows/projectfiles/tiered/Makefile	Thu Dec 16 20:35:33 2010 -0800
+++ b/make/windows/projectfiles/tiered/Makefile	Thu Dec 16 20:48:11 2010 -0800
@@ -22,8 +22,7 @@
 #  
 #
 
-Variant=tiered
-!include local.make
+!include ../local.make
 AdlcOutDir=$(HOTSPOTBUILDSPACE)\$(Variant)\generated\adfiles
 AdditionalTargets=$(AdlcOutDir)\ad_$(Platform_arch_model).cpp $(AdlcOutDir)\dfa_$(Platform_arch_model).cpp
 
--- a/make/windows/projectfiles/tiered/vm.def	Thu Dec 16 20:35:33 2010 -0800
+++ b/make/windows/projectfiles/tiered/vm.def	Thu Dec 16 20:48:11 2010 -0800
@@ -2,6 +2,6 @@
 ; This .DEF file is a placeholder for one which is automatically
 ; generated during the build process. See
 ; make\windows\build_vm_def.sh and
-; make\windows\makefiles\makedeps.make (esp. the "-prelink"
+; make\windows\makefiles\projectcreator.make (esp. the "-prelink"
 ; options).
 ;
--- a/src/cpu/sparc/vm/assembler_sparc.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/cpu/sparc/vm/assembler_sparc.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -909,10 +909,10 @@
 #if defined(COMPILER2) && !defined(_LP64)
     // Save & restore possible 64-bit Long arguments in G-regs
     sllx(L0,32,G2);             // Move old high G1 bits high in G2
-    sllx(G1, 0,G1);             // Clear current high G1 bits
+    srl(G1, 0,G1);              // Clear current high G1 bits
     or3 (G1,G2,G1);             // Recover 64-bit G1
     sllx(L6,32,G2);             // Move old high G4 bits high in G2
-    sllx(G4, 0,G4);             // Clear current high G4 bits
+    srl(G4, 0,G4);              // Clear current high G4 bits
     or3 (G4,G2,G4);             // Recover 64-bit G4
 #endif
     restore(O0, 0, G2_thread);
@@ -1443,6 +1443,45 @@
   }
 }
 
+int MacroAssembler::size_of_set64(jlong value) {
+  v9_dep();
+
+  int hi = (int)(value >> 32);
+  int lo = (int)(value & ~0);
+  int count = 0;
+
+  // (Matcher::isSimpleConstant64 knows about the following optimizations.)
+  if (Assembler::is_simm13(lo) && value == lo) {
+    count++;
+  } else if (hi == 0) {
+    count++;
+    if (low10(lo) != 0)
+      count++;
+  }
+  else if (hi == -1) {
+    count += 2;
+  }
+  else if (lo == 0) {
+    if (Assembler::is_simm13(hi)) {
+      count++;
+    } else {
+      count++;
+      if (low10(hi) != 0)
+        count++;
+    }
+    count++;
+  }
+  else {
+    count += 2;
+    if (low10(hi) != 0)
+      count++;
+    if (low10(lo) != 0)
+      count++;
+    count += 2;
+  }
+  return count;
+}
+
 // compute size in bytes of sparc frame, given
 // number of extraWords
 int MacroAssembler::total_frame_size_in_bytes(int extraWords) {
--- a/src/cpu/sparc/vm/assembler_sparc.hpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/cpu/sparc/vm/assembler_sparc.hpp	Thu Dec 16 20:48:11 2010 -0800
@@ -1621,6 +1621,10 @@
 
   void sub(    Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(sub_op3              ) | rs1(s1) | rs2(s2) ); }
   void sub(    Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(sub_op3              ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
+
+  // Note: offset is added to s2.
+  inline void sub(Register s1, RegisterOrConstant s2, Register d, int offset = 0);
+
   void subcc(  Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(sub_op3 | cc_bit_op3 ) | rs1(s1) | rs2(s2) ); }
   void subcc(  Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(sub_op3 | cc_bit_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
   void subc(   Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(subc_op3             ) | rs1(s1) | rs2(s2) ); }
@@ -1798,6 +1802,7 @@
   // branches that use right instruction for v8 vs. v9
   inline void br( Condition c, bool a, Predict p, address d, relocInfo::relocType rt = relocInfo::none );
   inline void br( Condition c, bool a, Predict p, Label& L );
+
   inline void fb( Condition c, bool a, Predict p, address d, relocInfo::relocType rt = relocInfo::none );
   inline void fb( Condition c, bool a, Predict p, Label& L );
 
@@ -1894,6 +1899,9 @@
   void patchable_set(intptr_t value, Register d);
   void set64(jlong value, Register d, Register tmp);
 
+  // Compute size of set64.
+  static int size_of_set64(jlong value);
+
   // sign-extend 32 to 64
   inline void signx( Register s, Register d ) { sra( s, G0, d); }
   inline void signx( Register d )             { sra( d, G0, d); }
--- a/src/cpu/sparc/vm/assembler_sparc.inline.hpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/cpu/sparc/vm/assembler_sparc.inline.hpp	Thu Dec 16 20:48:11 2010 -0800
@@ -328,6 +328,11 @@
 inline void Assembler::stdcq(  int crd, Register s1, Register s2) { v8_only();  emit_long( op(ldst_op) | fcn(crd) | op3(stdcq_op3) | rs1(s1) | rs2(s2) ); }
 inline void Assembler::stdcq(  int crd, Register s1, int simm13a) { v8_only();  emit_data( op(ldst_op) | fcn(crd) | op3(stdcq_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); }
 
+inline void Assembler::sub(Register s1, RegisterOrConstant s2, Register d, int offset) {
+  if (s2.is_register())  sub(s1, s2.as_register(),          d);
+  else                 { sub(s1, s2.as_constant() + offset, d); offset = 0; }
+  if (offset != 0)       sub(d,  offset,                    d);
+}
 
 // pp 231
 
--- a/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -434,7 +434,7 @@
 
   Register pre_val_reg = pre_val()->as_register();
 
-  ce->mem2reg(addr(), pre_val(), T_OBJECT, patch_code(), info(), false);
+  ce->mem2reg(addr(), pre_val(), T_OBJECT, patch_code(), info(), false /*wide*/, false /*unaligned*/);
   if (__ is_in_wdisp16_range(_continuation)) {
     __ br_on_reg_cond(Assembler::rc_z, /*annul*/false, Assembler::pt,
                       pre_val_reg, _continuation);
--- a/src/cpu/sparc/vm/c1_FrameMap_sparc.hpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/cpu/sparc/vm/c1_FrameMap_sparc.hpp	Thu Dec 16 20:48:11 2010 -0800
@@ -155,4 +155,7 @@
   static bool is_caller_save_register (LIR_Opr  reg);
   static bool is_caller_save_register (Register r);
 
+  static int nof_caller_save_cpu_regs() { return pd_nof_caller_save_cpu_regs_frame_map; }
+  static int last_cpu_reg()             { return pd_last_cpu_reg;  }
+
 #endif // CPU_SPARC_VM_C1_FRAMEMAP_SPARC_HPP
--- a/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -100,6 +100,11 @@
         return false;
       }
 
+      if (UseCompressedOops) {
+        if (dst->is_address() && !dst->is_stack() && (dst->type() == T_OBJECT || dst->type() == T_ARRAY)) return false;
+        if (src->is_address() && !src->is_stack() && (src->type() == T_OBJECT || src->type() == T_ARRAY)) return false;
+      }
+
       if (dst->is_register()) {
         if (src->is_address() && Assembler::is_simm13(src->as_address_ptr()->disp())) {
           return !PatchALot;
@@ -253,7 +258,7 @@
     int offset_offset = java_lang_String::offset_offset_in_bytes(); // first character position
     int  count_offset = java_lang_String:: count_offset_in_bytes();
 
-    __ ld_ptr(str0, value_offset, tmp0);
+    __ load_heap_oop(str0, value_offset, tmp0);
     __ ld(str0, offset_offset, tmp2);
     __ add(tmp0, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp0);
     __ ld(str0, count_offset, str0);
@@ -262,7 +267,7 @@
     // str1 may be null
     add_debug_info_for_null_check_here(info);
 
-    __ ld_ptr(str1, value_offset, tmp1);
+    __ load_heap_oop(str1, value_offset, tmp1);
     __ add(tmp0, tmp2, tmp0);
 
     __ ld(str1, offset_offset, tmp2);
@@ -766,7 +771,7 @@
 
 void LIR_Assembler::vtable_call(LIR_OpJavaCall* op) {
   add_debug_info_for_null_check_here(op->info());
-  __ ld_ptr(O0, oopDesc::klass_offset_in_bytes(), G3_scratch);
+  __ load_klass(O0, G3_scratch);
   if (__ is_simm13(op->vtable_offset())) {
     __ ld_ptr(G3_scratch, op->vtable_offset(), G5_method);
   } else {
@@ -780,138 +785,17 @@
   // the peephole pass fills the delay slot
 }
 
-
-// load with 32-bit displacement
-int LIR_Assembler::load(Register s, int disp, Register d, BasicType ld_type, CodeEmitInfo *info) {
-  int load_offset = code_offset();
-  if (Assembler::is_simm13(disp)) {
-    if (info != NULL) add_debug_info_for_null_check_here(info);
-    switch(ld_type) {
-      case T_BOOLEAN: // fall through
-      case T_BYTE  : __ ldsb(s, disp, d); break;
-      case T_CHAR  : __ lduh(s, disp, d); break;
-      case T_SHORT : __ ldsh(s, disp, d); break;
-      case T_INT   : __ ld(s, disp, d); break;
-      case T_ADDRESS:// fall through
-      case T_ARRAY : // fall through
-      case T_OBJECT: __ ld_ptr(s, disp, d); break;
-      default      : ShouldNotReachHere();
-    }
-  } else {
-    __ set(disp, O7);
-    if (info != NULL) add_debug_info_for_null_check_here(info);
-    load_offset = code_offset();
-    switch(ld_type) {
-      case T_BOOLEAN: // fall through
-      case T_BYTE  : __ ldsb(s, O7, d); break;
-      case T_CHAR  : __ lduh(s, O7, d); break;
-      case T_SHORT : __ ldsh(s, O7, d); break;
-      case T_INT   : __ ld(s, O7, d); break;
-      case T_ADDRESS:// fall through
-      case T_ARRAY : // fall through
-      case T_OBJECT: __ ld_ptr(s, O7, d); break;
-      default      : ShouldNotReachHere();
-    }
-  }
-  if (ld_type == T_ARRAY || ld_type == T_OBJECT) __ verify_oop(d);
-  return load_offset;
-}
-
-
-// store with 32-bit displacement
-void LIR_Assembler::store(Register value, Register base, int offset, BasicType type, CodeEmitInfo *info) {
-  if (Assembler::is_simm13(offset)) {
-    if (info != NULL)  add_debug_info_for_null_check_here(info);
-    switch (type) {
-      case T_BOOLEAN: // fall through
-      case T_BYTE  : __ stb(value, base, offset); break;
-      case T_CHAR  : __ sth(value, base, offset); break;
-      case T_SHORT : __ sth(value, base, offset); break;
-      case T_INT   : __ stw(value, base, offset); break;
-      case T_ADDRESS:// fall through
-      case T_ARRAY : // fall through
-      case T_OBJECT: __ st_ptr(value, base, offset); break;
-      default      : ShouldNotReachHere();
-    }
-  } else {
-    __ set(offset, O7);
-    if (info != NULL) add_debug_info_for_null_check_here(info);
-    switch (type) {
-      case T_BOOLEAN: // fall through
-      case T_BYTE  : __ stb(value, base, O7); break;
-      case T_CHAR  : __ sth(value, base, O7); break;
-      case T_SHORT : __ sth(value, base, O7); break;
-      case T_INT   : __ stw(value, base, O7); break;
-      case T_ADDRESS:// fall through
-      case T_ARRAY : //fall through
-      case T_OBJECT: __ st_ptr(value, base, O7); break;
-      default      : ShouldNotReachHere();
-    }
-  }
-  // Note: Do the store before verification as the code might be patched!
-  if (type == T_ARRAY || type == T_OBJECT) __ verify_oop(value);
-}
-
-
-// load float with 32-bit displacement
-void LIR_Assembler::load(Register s, int disp, FloatRegister d, BasicType ld_type, CodeEmitInfo *info) {
-  FloatRegisterImpl::Width w;
-  switch(ld_type) {
-    case T_FLOAT : w = FloatRegisterImpl::S; break;
-    case T_DOUBLE: w = FloatRegisterImpl::D; break;
-    default      : ShouldNotReachHere();
-  }
-
-  if (Assembler::is_simm13(disp)) {
-    if (info != NULL) add_debug_info_for_null_check_here(info);
-    if (disp % BytesPerLong != 0 && w == FloatRegisterImpl::D) {
-      __ ldf(FloatRegisterImpl::S, s, disp + BytesPerWord, d->successor());
-      __ ldf(FloatRegisterImpl::S, s, disp               , d);
-    } else {
-      __ ldf(w, s, disp, d);
-    }
-  } else {
-    __ set(disp, O7);
-    if (info != NULL) add_debug_info_for_null_check_here(info);
-    __ ldf(w, s, O7, d);
-  }
-}
-
-
-// store float with 32-bit displacement
-void LIR_Assembler::store(FloatRegister value, Register base, int offset, BasicType type, CodeEmitInfo *info) {
-  FloatRegisterImpl::Width w;
-  switch(type) {
-    case T_FLOAT : w = FloatRegisterImpl::S; break;
-    case T_DOUBLE: w = FloatRegisterImpl::D; break;
-    default      : ShouldNotReachHere();
-  }
-
-  if (Assembler::is_simm13(offset)) {
-    if (info != NULL) add_debug_info_for_null_check_here(info);
-    if (w == FloatRegisterImpl::D && offset % BytesPerLong != 0) {
-      __ stf(FloatRegisterImpl::S, value->successor(), base, offset + BytesPerWord);
-      __ stf(FloatRegisterImpl::S, value             , base, offset);
-    } else {
-      __ stf(w, value, base, offset);
-    }
-  } else {
-    __ set(offset, O7);
-    if (info != NULL) add_debug_info_for_null_check_here(info);
-    __ stf(w, value, O7, base);
-  }
-}
-
-
-int LIR_Assembler::store(LIR_Opr from_reg, Register base, int offset, BasicType type, bool unaligned) {
+int LIR_Assembler::store(LIR_Opr from_reg, Register base, int offset, BasicType type, bool wide, bool unaligned) {
   int store_offset;
   if (!Assembler::is_simm13(offset + (type == T_LONG) ? wordSize : 0)) {
     assert(!unaligned, "can't handle this");
     // for offsets larger than a simm13 we setup the offset in O7
     __ set(offset, O7);
-    store_offset = store(from_reg, base, O7, type);
+    store_offset = store(from_reg, base, O7, type, wide);
   } else {
-    if (type == T_ARRAY || type == T_OBJECT) __ verify_oop(from_reg->as_register());
+    if (type == T_ARRAY || type == T_OBJECT) {
+      __ verify_oop(from_reg->as_register());
+    }
     store_offset = code_offset();
     switch (type) {
       case T_BOOLEAN: // fall through
@@ -934,9 +818,22 @@
         __ stw(from_reg->as_register_hi(), base, offset + hi_word_offset_in_bytes);
 #endif
         break;
-      case T_ADDRESS:// fall through
+      case T_ADDRESS:
+        __ st_ptr(from_reg->as_register(), base, offset);
+        break;
       case T_ARRAY : // fall through
-      case T_OBJECT: __ st_ptr(from_reg->as_register(), base, offset); break;
+      case T_OBJECT:
+        {
+          if (UseCompressedOops && !wide) {
+            __ encode_heap_oop(from_reg->as_register(), G3_scratch);
+            store_offset = code_offset();
+            __ stw(G3_scratch, base, offset);
+          } else {
+            __ st_ptr(from_reg->as_register(), base, offset);
+          }
+          break;
+        }
+
       case T_FLOAT : __ stf(FloatRegisterImpl::S, from_reg->as_float_reg(), base, offset); break;
       case T_DOUBLE:
         {
@@ -958,8 +855,10 @@
 }
 
 
-int LIR_Assembler::store(LIR_Opr from_reg, Register base, Register disp, BasicType type) {
-  if (type == T_ARRAY || type == T_OBJECT) __ verify_oop(from_reg->as_register());
+int LIR_Assembler::store(LIR_Opr from_reg, Register base, Register disp, BasicType type, bool wide) {
+  if (type == T_ARRAY || type == T_OBJECT) {
+    __ verify_oop(from_reg->as_register());
+  }
   int store_offset = code_offset();
   switch (type) {
     case T_BOOLEAN: // fall through
@@ -975,9 +874,21 @@
       __ std(from_reg->as_register_hi(), base, disp);
 #endif
       break;
-    case T_ADDRESS:// fall through
+    case T_ADDRESS:
+      __ st_ptr(from_reg->as_register(), base, disp);
+      break;
     case T_ARRAY : // fall through
-    case T_OBJECT: __ st_ptr(from_reg->as_register(), base, disp); break;
+    case T_OBJECT:
+      {
+        if (UseCompressedOops && !wide) {
+          __ encode_heap_oop(from_reg->as_register(), G3_scratch);
+          store_offset = code_offset();
+          __ stw(G3_scratch, base, disp);
+        } else {
+          __ st_ptr(from_reg->as_register(), base, disp);
+        }
+        break;
+      }
     case T_FLOAT : __ stf(FloatRegisterImpl::S, from_reg->as_float_reg(), base, disp); break;
     case T_DOUBLE: __ stf(FloatRegisterImpl::D, from_reg->as_double_reg(), base, disp); break;
     default      : ShouldNotReachHere();
@@ -986,14 +897,14 @@
 }
 
 
-int LIR_Assembler::load(Register base, int offset, LIR_Opr to_reg, BasicType type, bool unaligned) {
+int LIR_Assembler::load(Register base, int offset, LIR_Opr to_reg, BasicType type, bool wide, bool unaligned) {
   int load_offset;
   if (!Assembler::is_simm13(offset + (type == T_LONG) ? wordSize : 0)) {
     assert(base != O7, "destroying register");
     assert(!unaligned, "can't handle this");
     // for offsets larger than a simm13 we setup the offset in O7
     __ set(offset, O7);
-    load_offset = load(base, O7, to_reg, type);
+    load_offset = load(base, O7, to_reg, type, wide);
   } else {
     load_offset = code_offset();
     switch(type) {
@@ -1030,9 +941,18 @@
 #endif
         }
         break;
-      case T_ADDRESS:// fall through
+      case T_ADDRESS:  __ ld_ptr(base, offset, to_reg->as_register()); break;
       case T_ARRAY : // fall through
-      case T_OBJECT: __ ld_ptr(base, offset, to_reg->as_register()); break;
+      case T_OBJECT:
+        {
+          if (UseCompressedOops && !wide) {
+            __ lduw(base, offset, to_reg->as_register());
+            __ decode_heap_oop(to_reg->as_register());
+          } else {
+            __ ld_ptr(base, offset, to_reg->as_register());
+          }
+          break;
+        }
       case T_FLOAT:  __ ldf(FloatRegisterImpl::S, base, offset, to_reg->as_float_reg()); break;
       case T_DOUBLE:
         {
@@ -1048,23 +968,34 @@
         }
       default      : ShouldNotReachHere();
     }
-    if (type == T_ARRAY || type == T_OBJECT) __ verify_oop(to_reg->as_register());
+    if (type == T_ARRAY || type == T_OBJECT) {
+      __ verify_oop(to_reg->as_register());
+    }
   }
   return load_offset;
 }
 
 
-int LIR_Assembler::load(Register base, Register disp, LIR_Opr to_reg, BasicType type) {
+int LIR_Assembler::load(Register base, Register disp, LIR_Opr to_reg, BasicType type, bool wide) {
   int load_offset = code_offset();
   switch(type) {
     case T_BOOLEAN: // fall through
-    case T_BYTE  : __ ldsb(base, disp, to_reg->as_register()); break;
-    case T_CHAR  : __ lduh(base, disp, to_reg->as_register()); break;
-    case T_SHORT : __ ldsh(base, disp, to_reg->as_register()); break;
-    case T_INT   : __ ld(base, disp, to_reg->as_register()); break;
-    case T_ADDRESS:// fall through
+    case T_BYTE  :  __ ldsb(base, disp, to_reg->as_register()); break;
+    case T_CHAR  :  __ lduh(base, disp, to_reg->as_register()); break;
+    case T_SHORT :  __ ldsh(base, disp, to_reg->as_register()); break;
+    case T_INT   :  __ ld(base, disp, to_reg->as_register()); break;
+    case T_ADDRESS: __ ld_ptr(base, disp, to_reg->as_register()); break;
     case T_ARRAY : // fall through
-    case T_OBJECT: __ ld_ptr(base, disp, to_reg->as_register()); break;
+    case T_OBJECT:
+      {
+          if (UseCompressedOops && !wide) {
+            __ lduw(base, disp, to_reg->as_register());
+            __ decode_heap_oop(to_reg->as_register());
+          } else {
+            __ ld_ptr(base, disp, to_reg->as_register());
+          }
+          break;
+      }
     case T_FLOAT:  __ ldf(FloatRegisterImpl::S, base, disp, to_reg->as_float_reg()); break;
     case T_DOUBLE: __ ldf(FloatRegisterImpl::D, base, disp, to_reg->as_double_reg()); break;
     case T_LONG  :
@@ -1078,60 +1009,28 @@
       break;
     default      : ShouldNotReachHere();
   }
-  if (type == T_ARRAY || type == T_OBJECT) __ verify_oop(to_reg->as_register());
+  if (type == T_ARRAY || type == T_OBJECT) {
+    __ verify_oop(to_reg->as_register());
+  }
   return load_offset;
 }
 
-
-// load/store with an Address
-void LIR_Assembler::load(const Address& a, Register d,  BasicType ld_type, CodeEmitInfo *info, int offset) {
-  load(a.base(), a.disp() + offset, d, ld_type, info);
-}
-
-
-void LIR_Assembler::store(Register value, const Address& dest, BasicType type, CodeEmitInfo *info, int offset) {
-  store(value, dest.base(), dest.disp() + offset, type, info);
-}
-
-
-// loadf/storef with an Address
-void LIR_Assembler::load(const Address& a, FloatRegister d, BasicType ld_type, CodeEmitInfo *info, int offset) {
-  load(a.base(), a.disp() + offset, d, ld_type, info);
-}
-
-
-void LIR_Assembler::store(FloatRegister value, const Address& dest, BasicType type, CodeEmitInfo *info, int offset) {
-  store(value, dest.base(), dest.disp() + offset, type, info);
-}
-
-
-// load/store with an Address
-void LIR_Assembler::load(LIR_Address* a, Register d,  BasicType ld_type, CodeEmitInfo *info) {
-  load(as_Address(a), d, ld_type, info);
-}
-
-
-void LIR_Assembler::store(Register value, LIR_Address* dest, BasicType type, CodeEmitInfo *info) {
-  store(value, as_Address(dest), type, info);
-}
-
-
-// loadf/storef with an Address
-void LIR_Assembler::load(LIR_Address* a, FloatRegister d, BasicType ld_type, CodeEmitInfo *info) {
-  load(as_Address(a), d, ld_type, info);
-}
-
-
-void LIR_Assembler::store(FloatRegister value, LIR_Address* dest, BasicType type, CodeEmitInfo *info) {
-  store(value, as_Address(dest), type, info);
-}
-
-
 void LIR_Assembler::const2stack(LIR_Opr src, LIR_Opr dest) {
   LIR_Const* c = src->as_constant_ptr();
   switch (c->type()) {
     case T_INT:
-    case T_FLOAT:
+    case T_FLOAT: {
+      Register src_reg = O7;
+      int value = c->as_jint_bits();
+      if (value == 0) {
+        src_reg = G0;
+      } else {
+        __ set(value, O7);
+      }
+      Address addr = frame_map()->address_for_slot(dest->single_stack_ix());
+      __ stw(src_reg, addr.base(), addr.disp());
+      break;
+    }
     case T_ADDRESS: {
       Register src_reg = O7;
       int value = c->as_jint_bits();
@@ -1141,7 +1040,7 @@
         __ set(value, O7);
       }
       Address addr = frame_map()->address_for_slot(dest->single_stack_ix());
-      __ stw(src_reg, addr.base(), addr.disp());
+      __ st_ptr(src_reg, addr.base(), addr.disp());
       break;
     }
     case T_OBJECT: {
@@ -1178,14 +1077,12 @@
 }
 
 
-void LIR_Assembler::const2mem(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmitInfo* info ) {
+void LIR_Assembler::const2mem(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmitInfo* info, bool wide) {
   LIR_Const* c = src->as_constant_ptr();
   LIR_Address* addr     = dest->as_address_ptr();
   Register base = addr->base()->as_pointer_register();
-
-  if (info != NULL) {
-    add_debug_info_for_null_check_here(info);
-  }
+  int offset = -1;
+
   switch (c->type()) {
     case T_INT:
     case T_FLOAT:
@@ -1199,10 +1096,10 @@
       }
       if (addr->index()->is_valid()) {
         assert(addr->disp() == 0, "must be zero");
-        store(tmp, base, addr->index()->as_pointer_register(), type);
+        offset = store(tmp, base, addr->index()->as_pointer_register(), type, wide);
       } else {
         assert(Assembler::is_simm13(addr->disp()), "can't handle larger addresses");
-        store(tmp, base, addr->disp(), type);
+        offset = store(tmp, base, addr->disp(), type, wide, false);
       }
       break;
     }
@@ -1212,21 +1109,21 @@
       assert(Assembler::is_simm13(addr->disp()) &&
              Assembler::is_simm13(addr->disp() + 4), "can't handle larger addresses");
 
-      Register tmp = O7;
+      LIR_Opr tmp = FrameMap::O7_opr;
       int value_lo = c->as_jint_lo_bits();
       if (value_lo == 0) {
-        tmp = G0;
+        tmp = FrameMap::G0_opr;
       } else {
         __ set(value_lo, O7);
       }
-      store(tmp, base, addr->disp() + lo_word_offset_in_bytes, T_INT);
+      offset = store(tmp, base, addr->disp() + lo_word_offset_in_bytes, T_INT, wide, false);
       int value_hi = c->as_jint_hi_bits();
       if (value_hi == 0) {
-        tmp = G0;
+        tmp = FrameMap::G0_opr;
       } else {
         __ set(value_hi, O7);
       }
-      store(tmp, base, addr->disp() + hi_word_offset_in_bytes, T_INT);
+      offset = store(tmp, base, addr->disp() + hi_word_offset_in_bytes, T_INT, wide, false);
       break;
     }
     case T_OBJECT: {
@@ -1241,10 +1138,10 @@
       // handle either reg+reg or reg+disp address
       if (addr->index()->is_valid()) {
         assert(addr->disp() == 0, "must be zero");
-        store(tmp, base, addr->index()->as_pointer_register(), type);
+        offset = store(tmp, base, addr->index()->as_pointer_register(), type, wide);
       } else {
         assert(Assembler::is_simm13(addr->disp()), "can't handle larger addresses");
-        store(tmp, base, addr->disp(), type);
+        offset = store(tmp, base, addr->disp(), type, wide, false);
       }
 
       break;
@@ -1252,6 +1149,10 @@
     default:
       Unimplemented();
   }
+  if (info != NULL) {
+    assert(offset != -1, "offset should've been set");
+    add_debug_info_for_null_check(offset, info);
+  }
 }
 
 
@@ -1336,7 +1237,7 @@
           assert(to_reg->is_single_cpu(), "Must be a cpu register.");
 
           __ set(const_addrlit, O7);
-          load(O7, 0, to_reg->as_register(), T_INT);
+          __ ld(O7, 0, to_reg->as_register());
         }
       }
       break;
@@ -1429,7 +1330,7 @@
 
 
 void LIR_Assembler::mem2reg(LIR_Opr src_opr, LIR_Opr dest, BasicType type,
-                            LIR_PatchCode patch_code, CodeEmitInfo* info, bool unaligned) {
+                            LIR_PatchCode patch_code, CodeEmitInfo* info, bool wide, bool unaligned) {
 
   LIR_Address* addr = src_opr->as_address_ptr();
   LIR_Opr to_reg = dest;
@@ -1475,16 +1376,15 @@
 
   assert(disp_reg != noreg || Assembler::is_simm13(disp_value), "should have set this up");
   if (disp_reg == noreg) {
-    offset = load(src, disp_value, to_reg, type, unaligned);
+    offset = load(src, disp_value, to_reg, type, wide, unaligned);
   } else {
     assert(!unaligned, "can't handle this");
-    offset = load(src, disp_reg, to_reg, type);
+    offset = load(src, disp_reg, to_reg, type, wide);
   }
 
   if (patch != NULL) {
     patching_epilog(patch, patch_code, src, info);
   }
-
   if (info != NULL) add_debug_info_for_null_check(offset, info);
 }
 
@@ -1518,7 +1418,7 @@
   }
 
   bool unaligned = (addr.disp() - STACK_BIAS) % 8 != 0;
-  load(addr.base(), addr.disp(), dest, dest->type(), unaligned);
+  load(addr.base(), addr.disp(), dest, dest->type(), true /*wide*/, unaligned);
 }
 
 
@@ -1530,7 +1430,7 @@
     addr = frame_map()->address_for_slot(dest->double_stack_ix());
   }
   bool unaligned = (addr.disp() - STACK_BIAS) % 8 != 0;
-  store(from_reg, addr.base(), addr.disp(), from_reg->type(), unaligned);
+  store(from_reg, addr.base(), addr.disp(), from_reg->type(), true /*wide*/, unaligned);
 }
 
 
@@ -1578,7 +1478,7 @@
 
 void LIR_Assembler::reg2mem(LIR_Opr from_reg, LIR_Opr dest, BasicType type,
                             LIR_PatchCode patch_code, CodeEmitInfo* info, bool pop_fpu_stack,
-                            bool unaligned) {
+                            bool wide, bool unaligned) {
   LIR_Address* addr = dest->as_address_ptr();
 
   Register src = addr->base()->as_pointer_register();
@@ -1622,10 +1522,10 @@
 
   assert(disp_reg != noreg || Assembler::is_simm13(disp_value), "should have set this up");
   if (disp_reg == noreg) {
-    offset = store(from_reg, src, disp_value, type, unaligned);
+    offset = store(from_reg, src, disp_value, type, wide, unaligned);
   } else {
     assert(!unaligned, "can't handle this");
-    offset = store(from_reg, src, disp_reg, type);
+    offset = store(from_reg, src, disp_reg, type, wide);
   }
 
   if (patch != NULL) {
@@ -2184,13 +2084,13 @@
   // make sure src and dst are non-null and load array length
   if (flags & LIR_OpArrayCopy::src_null_check) {
     __ tst(src);
-    __ br(Assembler::equal, false, Assembler::pn, *stub->entry());
+    __ brx(Assembler::equal, false, Assembler::pn, *stub->entry());
     __ delayed()->nop();
   }
 
   if (flags & LIR_OpArrayCopy::dst_null_check) {
     __ tst(dst);
-    __ br(Assembler::equal, false, Assembler::pn, *stub->entry());
+    __ brx(Assembler::equal, false, Assembler::pn, *stub->entry());
     __ delayed()->nop();
   }
 
@@ -2232,10 +2132,18 @@
   }
 
   if (flags & LIR_OpArrayCopy::type_check) {
-    __ ld_ptr(src, oopDesc::klass_offset_in_bytes(), tmp);
-    __ ld_ptr(dst, oopDesc::klass_offset_in_bytes(), tmp2);
-    __ cmp(tmp, tmp2);
-    __ br(Assembler::notEqual, false, Assembler::pt, *stub->entry());
+    if (UseCompressedOops) {
+      // We don't need decode because we just need to compare
+      __ lduw(src, oopDesc::klass_offset_in_bytes(), tmp);
+      __ lduw(dst, oopDesc::klass_offset_in_bytes(), tmp2);
+      __ cmp(tmp, tmp2);
+      __ br(Assembler::notEqual, false, Assembler::pt, *stub->entry());
+    } else {
+      __ ld_ptr(src, oopDesc::klass_offset_in_bytes(), tmp);
+      __ ld_ptr(dst, oopDesc::klass_offset_in_bytes(), tmp2);
+      __ cmp(tmp, tmp2);
+      __ brx(Assembler::notEqual, false, Assembler::pt, *stub->entry());
+    }
     __ delayed()->nop();
   }
 
@@ -2250,20 +2158,44 @@
     // but not necessarily exactly of type default_type.
     Label known_ok, halt;
     jobject2reg(op->expected_type()->constant_encoding(), tmp);
-    __ ld_ptr(dst, oopDesc::klass_offset_in_bytes(), tmp2);
-    if (basic_type != T_OBJECT) {
-      __ cmp(tmp, tmp2);
-      __ br(Assembler::notEqual, false, Assembler::pn, halt);
-      __ delayed()->ld_ptr(src, oopDesc::klass_offset_in_bytes(), tmp2);
-      __ cmp(tmp, tmp2);
-      __ br(Assembler::equal, false, Assembler::pn, known_ok);
-      __ delayed()->nop();
+    if (UseCompressedOops) {
+      // tmp holds the default type. It currently comes uncompressed after the
+      // load of a constant, so encode it.
+      __ encode_heap_oop(tmp);
+      // load the raw value of the dst klass, since we will be comparing
+      // uncompressed values directly.
+      __ lduw(dst, oopDesc::klass_offset_in_bytes(), tmp2);
+      if (basic_type != T_OBJECT) {
+        __ cmp(tmp, tmp2);
+        __ br(Assembler::notEqual, false, Assembler::pn, halt);
+        // load the raw value of the src klass.
+        __ delayed()->lduw(src, oopDesc::klass_offset_in_bytes(), tmp2);
+        __ cmp(tmp, tmp2);
+        __ br(Assembler::equal, false, Assembler::pn, known_ok);
+        __ delayed()->nop();
+      } else {
+        __ cmp(tmp, tmp2);
+        __ br(Assembler::equal, false, Assembler::pn, known_ok);
+        __ delayed()->cmp(src, dst);
+        __ brx(Assembler::equal, false, Assembler::pn, known_ok);
+        __ delayed()->nop();
+      }
     } else {
-      __ cmp(tmp, tmp2);
-      __ br(Assembler::equal, false, Assembler::pn, known_ok);
-      __ delayed()->cmp(src, dst);
-      __ br(Assembler::equal, false, Assembler::pn, known_ok);
-      __ delayed()->nop();
+      __ ld_ptr(dst, oopDesc::klass_offset_in_bytes(), tmp2);
+      if (basic_type != T_OBJECT) {
+        __ cmp(tmp, tmp2);
+        __ brx(Assembler::notEqual, false, Assembler::pn, halt);
+        __ delayed()->ld_ptr(src, oopDesc::klass_offset_in_bytes(), tmp2);
+        __ cmp(tmp, tmp2);
+        __ brx(Assembler::equal, false, Assembler::pn, known_ok);
+        __ delayed()->nop();
+      } else {
+        __ cmp(tmp, tmp2);
+        __ brx(Assembler::equal, false, Assembler::pn, known_ok);
+        __ delayed()->cmp(src, dst);
+        __ brx(Assembler::equal, false, Assembler::pn, known_ok);
+        __ delayed()->nop();
+      }
     }
     __ bind(halt);
     __ stop("incorrect type information in arraycopy");
@@ -2471,7 +2403,7 @@
     Label next_test;
     Address recv_addr(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_offset(i)) -
                       mdo_offset_bias);
-    load(recv_addr, tmp1, T_OBJECT);
+    __ ld_ptr(recv_addr, tmp1);
     __ br_notnull(tmp1, false, Assembler::pt, next_test);
     __ delayed()->nop();
     __ st_ptr(recv, recv_addr);
@@ -2487,11 +2419,8 @@
 
 void LIR_Assembler::setup_md_access(ciMethod* method, int bci,
                                     ciMethodData*& md, ciProfileData*& data, int& mdo_offset_bias) {
-  md = method->method_data();
-  if (md == NULL) {
-    bailout("out of memory building methodDataOop");
-    return;
-  }
+  md = method->method_data_or_null();
+  assert(md != NULL, "Sanity");
   data = md->bci_to_data(bci);
   assert(data != NULL,       "need data for checkcast");
   assert(data->is_ReceiverTypeData(), "need ReceiverTypeData for type check");
@@ -2563,7 +2492,7 @@
 
   // get object class
   // not a safepoint as obj null check happens earlier
-  load(obj, oopDesc::klass_offset_in_bytes(), klass_RInfo, T_OBJECT, NULL);
+  __ load_klass(obj, klass_RInfo);
   if (op->fast_check()) {
     assert_different_registers(klass_RInfo, k_RInfo);
     __ cmp(k_RInfo, klass_RInfo);
@@ -2605,7 +2534,7 @@
       __ set(mdo_offset_bias, tmp1);
       __ add(mdo, tmp1, mdo);
     }
-    load(Address(obj, oopDesc::klass_offset_in_bytes()), recv, T_OBJECT);
+    __ load_klass(obj, recv);
     type_profile_helper(mdo, mdo_offset_bias, md, data, recv, tmp1, success);
     // Jump over the failure case
     __ ba(false, *success);
@@ -2674,11 +2603,12 @@
       __ br_null(value, false, Assembler::pn, done);
       __ delayed()->nop();
     }
-    load(array, oopDesc::klass_offset_in_bytes(), k_RInfo, T_OBJECT, op->info_for_exception());
-    load(value, oopDesc::klass_offset_in_bytes(), klass_RInfo, T_OBJECT, NULL);
+    add_debug_info_for_null_check_here(op->info_for_exception());
+    __ load_klass(array, k_RInfo);
+    __ load_klass(value, klass_RInfo);
 
     // get instance klass
-    load(k_RInfo, objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc), k_RInfo, T_OBJECT, NULL);
+    __ ld_ptr(Address(k_RInfo, objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc)), k_RInfo);
     // perform the fast part of the checking logic
     __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, O7, success_target, failure_target, NULL);
 
@@ -2700,7 +2630,7 @@
         __ set(mdo_offset_bias, tmp1);
         __ add(mdo, tmp1, mdo);
       }
-      load(Address(value, oopDesc::klass_offset_in_bytes()), recv, T_OBJECT);
+      __ load_klass(value, recv);
       type_profile_helper(mdo, mdo_offset_bias, md, data, recv, tmp1, &done);
       __ ba(false, done);
       __ delayed()->nop();
@@ -2781,14 +2711,17 @@
     Register t2 = op->tmp2()->as_register();
     __ mov(cmp_value, t1);
     __ mov(new_value, t2);
-#ifdef _LP64
     if (op->code() == lir_cas_obj) {
-      __ casx(addr, t1, t2);
-    } else
-#endif
-      {
+      if (UseCompressedOops) {
+        __ encode_heap_oop(t1);
+        __ encode_heap_oop(t2);
         __ cas(addr, t1, t2);
+      } else {
+        __ cas_ptr(addr, t1, t2);
       }
+    } else {
+      __ cas(addr, t1, t2);
+    }
     __ cmp(t1, t2);
   } else {
     Unimplemented();
@@ -2885,11 +2818,8 @@
   int bci          = op->profiled_bci();
 
   // Update counter for all call types
-  ciMethodData* md = method->method_data();
-  if (md == NULL) {
-    bailout("out of memory building methodDataOop");
-    return;
-  }
+  ciMethodData* md = method->method_data_or_null();
+  assert(md != NULL, "Sanity");
   ciProfileData* data = md->bci_to_data(bci);
   assert(data->is_CounterData(), "need CounterData for calls");
   assert(op->mdo()->is_single_cpu(),  "mdo must be allocated");
@@ -2966,7 +2896,7 @@
         }
       }
     } else {
-      load(Address(recv, oopDesc::klass_offset_in_bytes()), recv, T_OBJECT);
+      __ load_klass(recv, recv);
       Label update_done;
       type_profile_helper(mdo, mdo_offset_bias, md, data, recv, tmp1, &update_done);
       // Receiver did not match any saved receiver and there is no empty row for it.
@@ -3160,7 +3090,7 @@
   } else {
     // use normal move for all other volatiles since they don't need
     // special handling to remain atomic.
-    move_op(src, dest, type, lir_patch_none, info, false, false);
+    move_op(src, dest, type, lir_patch_none, info, false, false, false);
   }
 }
 
--- a/src/cpu/sparc/vm/c1_LIRAssembler_sparc.hpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/cpu/sparc/vm/c1_LIRAssembler_sparc.hpp	Thu Dec 16 20:48:11 2010 -0800
@@ -40,33 +40,11 @@
   //       and then a load or store is emitted with ([O7] + [d]).
   //
 
-  // some load/store variants return the code_offset for proper positioning of debug info for null checks
-
-  // load/store with 32 bit displacement
-  int load(Register s, int disp, Register d, BasicType ld_type, CodeEmitInfo* info = NULL);
-  void store(Register value, Register base, int offset, BasicType type, CodeEmitInfo *info = NULL);
-
-  // loadf/storef with 32 bit displacement
-  void load(Register s, int disp, FloatRegister d, BasicType ld_type, CodeEmitInfo* info = NULL);
-  void store(FloatRegister d, Register s1, int disp, BasicType st_type, CodeEmitInfo* info = NULL);
+  int store(LIR_Opr from_reg, Register base, int offset, BasicType type, bool wide, bool unaligned);
+  int store(LIR_Opr from_reg, Register base, Register disp, BasicType type, bool wide);
 
-  // convienence methods for calling load/store with an Address
-  void load(const Address& a, Register d, BasicType ld_type, CodeEmitInfo* info = NULL, int offset = 0);
-  void store(Register d, const Address& a, BasicType st_type, CodeEmitInfo* info = NULL, int offset = 0);
-  void load(const Address& a, FloatRegister d, BasicType ld_type, CodeEmitInfo* info = NULL, int offset = 0);
-  void store(FloatRegister d, const Address& a, BasicType st_type, CodeEmitInfo* info = NULL, int offset = 0);
-
-  // convienence methods for calling load/store with an LIR_Address
-  void load(LIR_Address* a, Register d, BasicType ld_type, CodeEmitInfo* info = NULL);
-  void store(Register d, LIR_Address* a, BasicType st_type, CodeEmitInfo* info = NULL);
-  void load(LIR_Address* a, FloatRegister d, BasicType ld_type, CodeEmitInfo* info = NULL);
-  void store(FloatRegister d, LIR_Address* a, BasicType st_type, CodeEmitInfo* info = NULL);
-
-  int store(LIR_Opr from_reg, Register base, int offset, BasicType type, bool unaligned = false);
-  int store(LIR_Opr from_reg, Register base, Register disp, BasicType type);
-
-  int load(Register base, int offset, LIR_Opr to_reg, BasicType type, bool unaligned = false);
-  int load(Register base, Register disp, LIR_Opr to_reg, BasicType type);
+  int load(Register base, int offset, LIR_Opr to_reg, BasicType type, bool wide, bool unaligned);
+  int load(Register base, Register disp, LIR_Opr to_reg, BasicType type, bool wide);
 
   void monitorexit(LIR_Opr obj_opr, LIR_Opr lock_opr, Register hdr, int monitor_no);
 
--- a/src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -40,7 +40,7 @@
   const Register temp_reg = G3_scratch;
   // Note: needs more testing of out-of-line vs. inline slow case
   verify_oop(receiver);
-  ld_ptr(receiver, oopDesc::klass_offset_in_bytes(), temp_reg);
+  load_klass(receiver, temp_reg);
   cmp(temp_reg, iCache);
   brx(Assembler::equal, true, Assembler::pt, L);
   delayed()->nop();
@@ -185,9 +185,19 @@
   } else {
     set((intx)markOopDesc::prototype(), t1);
   }
-  st_ptr(t1  , obj, oopDesc::mark_offset_in_bytes       ());
-  st_ptr(klass, obj, oopDesc::klass_offset_in_bytes      ());
-  if (len->is_valid()) st(len  , obj, arrayOopDesc::length_offset_in_bytes());
+  st_ptr(t1, obj, oopDesc::mark_offset_in_bytes());
+  if (UseCompressedOops) {
+    // Save klass
+    mov(klass, t1);
+    encode_heap_oop_not_null(t1);
+    stw(t1, obj, oopDesc::klass_offset_in_bytes());
+  } else {
+    st_ptr(klass, obj, oopDesc::klass_offset_in_bytes());
+  }
+  if (len->is_valid()) st(len, obj, arrayOopDesc::length_offset_in_bytes());
+  else if (UseCompressedOops) {
+    store_klass_gap(G0, obj);
+  }
 }
 
 
@@ -235,7 +245,7 @@
   Register t1,                         // temp register
   Register t2                          // temp register
   ) {
-  const int hdr_size_in_bytes = instanceOopDesc::base_offset_in_bytes();
+  const int hdr_size_in_bytes = instanceOopDesc::header_size() * HeapWordSize;
 
   initialize_header(obj, klass, noreg, t1, t2);
 
--- a/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -612,7 +612,7 @@
         // load the klass and check the has finalizer flag
         Label register_finalizer;
         Register t = O1;
-        __ ld_ptr(O0, oopDesc::klass_offset_in_bytes(), t);
+        __ load_klass(O0, t);
         __ ld(t, Klass::access_flags_offset_in_bytes() + sizeof(oopDesc), t);
         __ set(JVM_ACC_HAS_FINALIZER, G3);
         __ andcc(G3, t, G0);
--- a/src/cpu/sparc/vm/methodHandles_sparc.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/cpu/sparc/vm/methodHandles_sparc.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -689,8 +689,8 @@
     {
       // Perform an in-place conversion to int or an int subword.
       __ ldsw(G3_amh_vmargslot, O0_argslot);
+      Address value;
       Address vmarg = __ argument_address(O0_argslot);
-      Address value;
       bool value_left_justified = false;
 
       switch (ek) {
@@ -700,9 +700,21 @@
       case _adapter_opt_l2i:
         {
           // just delete the extra slot
+#ifdef _LP64
+          // In V9, longs are given 2 64-bit slots in the interpreter, but the
+          // data is passed in only 1 slot.
+          // Keep the second slot.
+          __ add(Gargs, __ argument_offset(O0_argslot, -1), O0_argslot);
+          remove_arg_slots(_masm, -stack_move_unit(), O0_argslot, O1_scratch, O2_scratch, O3_scratch);
+          value = Address(O0_argslot, 4);  // Get least-significant 32-bit of 64-bit value.
+          vmarg = Address(O0_argslot, Interpreter::stackElementSize);
+#else
+          // Keep the first slot.
           __ add(Gargs, __ argument_offset(O0_argslot), O0_argslot);
           remove_arg_slots(_masm, -stack_move_unit(), O0_argslot, O1_scratch, O2_scratch, O3_scratch);
-          value = vmarg = Address(O0_argslot, 0);
+          value = Address(O0_argslot, 0);
+          vmarg = value;
+#endif
         }
         break;
       case _adapter_opt_unboxi:
--- a/src/cpu/sparc/vm/sparc.ad	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/cpu/sparc/vm/sparc.ad	Thu Dec 16 20:48:11 2010 -0800
@@ -667,6 +667,20 @@
   return offset;
 }
 
+static inline jdouble replicate_immI(int con, int count, int width) {
+  // Load a constant replicated "count" times with width "width"
+  int bit_width = width * 8;
+  jlong elt_val = con;
+  elt_val &= (((jlong) 1) << bit_width) - 1;  // mask off sign bits
+  jlong val = elt_val;
+  for (int i = 0; i < count - 1; i++) {
+    val <<= bit_width;
+    val |= elt_val;
+  }
+  jdouble dval = *((jdouble*) &val);  // coerce to double type
+  return dval;
+}
+
 // Standard Sparc opcode form2 field breakdown
 static inline void emit2_19(CodeBuffer &cbuf, int f30, int f29, int f25, int f22, int f20, int f19, int f0 ) {
   f0 &= (1<<19)-1;     // Mask displacement to 19 bits
@@ -1008,6 +1022,90 @@
 
 
 //=============================================================================
+const bool Matcher::constant_table_absolute_addressing = false;
+const RegMask& MachConstantBaseNode::_out_RegMask = PTR_REG_mask;
+
+void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
+  Compile* C = ra_->C;
+  Compile::ConstantTable& constant_table = C->constant_table();
+  MacroAssembler _masm(&cbuf);
+
+  Register r = as_Register(ra_->get_encode(this));
+  CodeSection* cs = __ code()->consts();
+  int consts_size = cs->align_at_start(cs->size());
+
+  if (UseRDPCForConstantTableBase) {
+    // For the following RDPC logic to work correctly the consts
+    // section must be allocated right before the insts section.  This
+    // assert checks for that.  The layout and the SECT_* constants
+    // are defined in src/share/vm/asm/codeBuffer.hpp.
+    assert(CodeBuffer::SECT_CONSTS + 1 == CodeBuffer::SECT_INSTS, "must be");
+    int offset = __ offset();
+    int disp;
+
+    // If the displacement from the current PC to the constant table
+    // base fits into simm13 we set the constant table base to the
+    // current PC.
+    if (__ is_simm13(-(consts_size + offset))) {
+      constant_table.set_table_base_offset(-(consts_size + offset));
+      disp = 0;
+    } else {
+      // If the offset of the top constant (last entry in the table)
+      // fits into simm13 we set the constant table base to the actual
+      // table base.
+      if (__ is_simm13(constant_table.top_offset())) {
+        constant_table.set_table_base_offset(0);
+        disp = consts_size + offset;
+      } else {
+        // Otherwise we set the constant table base in the middle of the
+        // constant table.
+        int half_consts_size = consts_size / 2;
+        assert(half_consts_size * 2 == consts_size, "sanity");
+        constant_table.set_table_base_offset(-half_consts_size);  // table base offset gets added to the load displacement.
+        disp = half_consts_size + offset;
+      }
+    }
+
+    __ rdpc(r);
+
+    if (disp != 0) {
+      assert(r != O7, "need temporary");
+      __ sub(r, __ ensure_simm13_or_reg(disp, O7), r);
+    }
+  }
+  else {
+    // Materialize the constant table base.
+    assert(constant_table.size() == consts_size, err_msg("must be: %d == %d", constant_table.size(), consts_size));
+    address baseaddr = cs->start() + -(constant_table.table_base_offset());
+    RelocationHolder rspec = internal_word_Relocation::spec(baseaddr);
+    AddressLiteral base(baseaddr, rspec);
+    __ set(base, r);
+  }
+}
+
+uint MachConstantBaseNode::size(PhaseRegAlloc*) const {
+  if (UseRDPCForConstantTableBase) {
+    // This is really the worst case but generally it's only 1 instruction.
+    return 4 /*rdpc*/ + 4 /*sub*/ + MacroAssembler::worst_case_size_of_set();
+  } else {
+    return MacroAssembler::worst_case_size_of_set();
+  }
+}
+
+#ifndef PRODUCT
+void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
+  char reg[128];
+  ra_->dump_register(this, reg);
+  if (UseRDPCForConstantTableBase) {
+    st->print("RDPC   %s\t! constant table base", reg);
+  } else {
+    st->print("SET    &constanttable,%s\t! constant table base", reg);
+  }
+}
+#endif
+
+
+//=============================================================================
 
 #ifndef PRODUCT
 void MachPrologNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
@@ -2247,25 +2345,6 @@
     __ delayed()->nop();
   %}
 
-  enc_class jump_enc( iRegX switch_val, o7RegI table) %{
-    MacroAssembler _masm(&cbuf);
-
-    Register switch_reg       = as_Register($switch_val$$reg);
-    Register table_reg        = O7;
-
-    address table_base = __ address_table_constant(_index2label);
-    RelocationHolder rspec = internal_word_Relocation::spec(table_base);
-
-    // Move table address into a register.
-    __ set(table_base, table_reg, rspec);
-
-    // Jump to base address + switch value
-    __ ld_ptr(table_reg, switch_reg, table_reg);
-    __ jmp(table_reg, G0);
-    __ delayed()->nop();
-
-  %}
-
   enc_class enc_ba( Label labl ) %{
     MacroAssembler _masm(&cbuf);
     Label &L = *($labl$$label);
@@ -2384,20 +2463,6 @@
     cbuf.insts()->emit_int32(op);
   %}
 
-  // Utility encoding for loading a 64 bit Pointer into a register
-  // The 64 bit pointer is stored in the generated code stream
-  enc_class SetPtr( immP src, iRegP rd ) %{
-    Register dest = reg_to_register_object($rd$$reg);
-    MacroAssembler _masm(&cbuf);
-    // [RGV] This next line should be generated from ADLC
-    if ( _opnds[1]->constant_is_oop() ) {
-      intptr_t val = $src$$constant;
-      __ set_oop_constant((jobject)val, dest);
-    } else {          // non-oop pointers, e.g. card mark base, heap top
-      __ set($src$$constant, dest);
-    }
-  %}
-
   enc_class Set13( immI13 src, iRegI rd ) %{
     emit3_simm13( cbuf, Assembler::arith_op, $rd$$reg, Assembler::or_op3, 0, $src$$constant );
   %}
@@ -2411,10 +2476,6 @@
     __ set($src$$constant, reg_to_register_object($rd$$reg));
   %}
 
-  enc_class SetNull( iRegI rd ) %{
-    emit3_simm13( cbuf, Assembler::arith_op, $rd$$reg, Assembler::or_op3, 0, 0 );
-  %}
-
   enc_class call_epilog %{
     if( VerifyStackAtCalls ) {
       MacroAssembler _masm(&cbuf);
@@ -2778,35 +2839,6 @@
     __ float_cmp( $primary, -1, Fsrc1, Fsrc2, Rdst);
   %}
 
-  enc_class LdImmL (immL src, iRegL dst, o7RegL tmp) %{   // Load Immediate
-    MacroAssembler _masm(&cbuf);
-    Register dest = reg_to_register_object($dst$$reg);
-    Register temp = reg_to_register_object($tmp$$reg);
-    __ set64( $src$$constant, dest, temp );
-  %}
-
-  enc_class LdReplImmI(immI src, regD dst, o7RegP tmp, int count, int width) %{
-    // Load a constant replicated "count" times with width "width"
-    int bit_width = $width$$constant * 8;
-    jlong elt_val = $src$$constant;
-    elt_val  &= (((jlong)1) << bit_width) - 1; // mask off sign bits
-    jlong val = elt_val;
-    for (int i = 0; i < $count$$constant - 1; i++) {
-        val <<= bit_width;
-        val |= elt_val;
-    }
-    jdouble dval = *(jdouble*)&val; // coerce to double type
-    MacroAssembler _masm(&cbuf);
-    address double_address = __ double_constant(dval);
-    RelocationHolder rspec = internal_word_Relocation::spec(double_address);
-    AddressLiteral addrlit(double_address, rspec);
-
-    __ sethi(addrlit, $tmp$$Register);
-    // XXX This is a quick fix for 6833573.
-    //__ ldf(FloatRegisterImpl::D, $tmp$$Register, addrlit.low10(), $dst$$FloatRegister, rspec);
-    __ ldf(FloatRegisterImpl::D, $tmp$$Register, addrlit.low10(), as_DoubleFloatRegister($dst$$reg), rspec);
-  %}
-
   // Compiler ensures base is doubleword aligned and cnt is count of doublewords
   enc_class enc_Clear_Array(iRegX cnt, iRegP base, iRegX temp) %{
     MacroAssembler _masm(&cbuf);
@@ -3521,6 +3553,29 @@
   interface(CONST_INTER);
 %}
 
+// Pointer Immediate: 32 or 64-bit
+operand immP_set() %{
+  predicate(!VM_Version::is_niagara1_plus());
+  match(ConP);
+
+  op_cost(5);
+  // formats are generated automatically for constants and base registers
+  format %{ %}
+  interface(CONST_INTER);
+%}
+
+// Pointer Immediate: 32 or 64-bit
+// From Niagara2 processors on a load should be better than materializing.
+operand immP_load() %{
+  predicate(VM_Version::is_niagara1_plus());
+  match(ConP);
+
+  op_cost(5);
+  // formats are generated automatically for constants and base registers
+  format %{ %}
+  interface(CONST_INTER);
+%}
+
 operand immP13() %{
   predicate((-4096 < n->get_ptr()) && (n->get_ptr() <= 4095));
   match(ConP);
@@ -3616,6 +3671,26 @@
   interface(CONST_INTER);
 %}
 
+// Long Immediate: cheap (materialize in <= 3 instructions)
+operand immL_cheap() %{
+  predicate(!VM_Version::is_niagara1_plus() || MacroAssembler::size_of_set64(n->get_long()) <= 3);
+  match(ConL);
+  op_cost(0);
+
+  format %{ %}
+  interface(CONST_INTER);
+%}
+
+// Long Immediate: expensive (materialize in > 3 instructions)
+operand immL_expensive() %{
+  predicate(VM_Version::is_niagara1_plus() && MacroAssembler::size_of_set64(n->get_long()) > 3);
+  match(ConL);
+  op_cost(0);
+
+  format %{ %}
+  interface(CONST_INTER);
+%}
+
 // Double Immediate
 operand immD() %{
   match(ConD);
@@ -5981,25 +6056,59 @@
   ins_pipe(ialu_imm);
 %}
 
-instruct loadConP(iRegP dst, immP src) %{
-  match(Set dst src);
+#ifndef _LP64
+instruct loadConP(iRegP dst, immP con) %{
+  match(Set dst con);
+  ins_cost(DEFAULT_COST * 3/2);
+  format %{ "SET    $con,$dst\t!ptr" %}
+  ins_encode %{
+    // [RGV] This next line should be generated from ADLC
+    if (_opnds[1]->constant_is_oop()) {
+      intptr_t val = $con$$constant;
+      __ set_oop_constant((jobject) val, $dst$$Register);
+    } else {          // non-oop pointers, e.g. card mark base, heap top
+      __ set($con$$constant, $dst$$Register);
+    }
+  %}
+  ins_pipe(loadConP);
+%}
+#else
+instruct loadConP_set(iRegP dst, immP_set con) %{
+  match(Set dst con);
   ins_cost(DEFAULT_COST * 3/2);
-  format %{ "SET    $src,$dst\t!ptr" %}
-  // This rule does not use "expand" unlike loadConI because then
-  // the result type is not known to be an Oop.  An ADLC
-  // enhancement will be needed to make that work - not worth it!
-
-  ins_encode( SetPtr( src, dst ) );
+  format %{ "SET    $con,$dst\t! ptr" %}
+  ins_encode %{
+    // [RGV] This next line should be generated from ADLC
+    if (_opnds[1]->constant_is_oop()) {
+      intptr_t val = $con$$constant;
+      __ set_oop_constant((jobject) val, $dst$$Register);
+    } else {          // non-oop pointers, e.g. card mark base, heap top
+      __ set($con$$constant, $dst$$Register);
+    }
+  %}
   ins_pipe(loadConP);
-
-%}
+%}
+
+instruct loadConP_load(iRegP dst, immP_load con) %{
+  match(Set dst con);
+  ins_cost(MEMORY_REF_COST);
+  format %{ "LD     [$constanttablebase + $constantoffset],$dst\t! load from constant table: ptr=$con" %}
+  ins_encode %{
+      RegisterOrConstant con_offset = __ ensure_simm13_or_reg($constantoffset($con), $dst$$Register);
+     __ ld_ptr($constanttablebase, con_offset, $dst$$Register);
+  %}
+  ins_pipe(loadConP);
+%}
+#endif // _LP64
 
 instruct loadConP0(iRegP dst, immP0 src) %{
   match(Set dst src);
 
   size(4);
   format %{ "CLR    $dst\t!ptr" %}
-  ins_encode( SetNull( dst ) );
+  ins_encode %{
+    __ clr($dst$$Register);
+  %}
   ins_pipe(ialu_imm);
 %}
 
@@ -6019,7 +6128,9 @@
 
   size(4);
   format %{ "CLR    $dst\t! compressed NULL ptr" %}
-  ins_encode( SetNull( dst ) );
+  ins_encode %{
+    __ clr($dst$$Register);
+  %}
   ins_pipe(ialu_imm);
 %}
 
@@ -6034,13 +6145,27 @@
   ins_pipe(ialu_hi_lo_reg);
 %}
 
-instruct loadConL(iRegL dst, immL src, o7RegL tmp) %{
-  // %%% maybe this should work like loadConD
-  match(Set dst src);
+// Materialize long value (predicated by immL_cheap).
+instruct loadConL_set64(iRegL dst, immL_cheap con, o7RegL tmp) %{
+  match(Set dst con);
   effect(KILL tmp);
-  ins_cost(DEFAULT_COST * 4);
-  format %{ "SET64   $src,$dst KILL $tmp\t! long" %}
-  ins_encode( LdImmL(src, dst, tmp) );
+  ins_cost(DEFAULT_COST * 3);
+  format %{ "SET64   $con,$dst KILL $tmp\t! cheap long" %}
+  ins_encode %{
+    __ set64($con$$constant, $dst$$Register, $tmp$$Register);
+  %}
+  ins_pipe(loadConL);
+%}
+
+// Load long value from constant table (predicated by immL_expensive).
+instruct loadConL_ldx(iRegL dst, immL_expensive con) %{
+  match(Set dst con);
+  ins_cost(MEMORY_REF_COST);
+  format %{ "LDX     [$constanttablebase + $constantoffset],$dst\t! load from constant table: long=$con" %}
+  ins_encode %{
+      RegisterOrConstant con_offset = __ ensure_simm13_or_reg($constantoffset($con), $dst$$Register);
+    __ ldx($constanttablebase, con_offset, $dst$$Register);
+  %}
   ins_pipe(loadConL);
 %}
 
@@ -6063,50 +6188,26 @@
   ins_pipe(ialu_imm);
 %}
 
-instruct loadConF(regF dst, immF src, o7RegP tmp) %{
-  match(Set dst src);
+instruct loadConF(regF dst, immF con, o7RegI tmp) %{
+  match(Set dst con);
   effect(KILL tmp);
-
-#ifdef _LP64
-  size(8*4);
-#else
-  size(2*4);
-#endif
-
-  format %{ "SETHI  hi(&$src),$tmp\t!get float $src from table\n\t"
-            "LDF    [$tmp+lo(&$src)],$dst" %}
+  format %{ "LDF    [$constanttablebase + $constantoffset],$dst\t! load from constant table: float=$con" %}
   ins_encode %{
-    address float_address = __ float_constant($src$$constant);
-    RelocationHolder rspec = internal_word_Relocation::spec(float_address);
-    AddressLiteral addrlit(float_address, rspec);
-
-    __ sethi(addrlit, $tmp$$Register);
-    __ ldf(FloatRegisterImpl::S, $tmp$$Register, addrlit.low10(), $dst$$FloatRegister, rspec);
+      RegisterOrConstant con_offset = __ ensure_simm13_or_reg($constantoffset($con), $tmp$$Register);
+    __ ldf(FloatRegisterImpl::S, $constanttablebase, con_offset, $dst$$FloatRegister);
   %}
   ins_pipe(loadConFD);
 %}
 
-instruct loadConD(regD dst, immD src, o7RegP tmp) %{
-  match(Set dst src);
+instruct loadConD(regD dst, immD con, o7RegI tmp) %{
+  match(Set dst con);
   effect(KILL tmp);
-
-#ifdef _LP64
-  size(8*4);
-#else
-  size(2*4);
-#endif
-
-  format %{ "SETHI  hi(&$src),$tmp\t!get double $src from table\n\t"
-            "LDDF   [$tmp+lo(&$src)],$dst" %}
+  format %{ "LDDF   [$constanttablebase + $constantoffset],$dst\t! load from constant table: double=$con" %}
   ins_encode %{
-    address double_address = __ double_constant($src$$constant);
-    RelocationHolder rspec = internal_word_Relocation::spec(double_address);
-    AddressLiteral addrlit(double_address, rspec);
-
-    __ sethi(addrlit, $tmp$$Register);
     // XXX This is a quick fix for 6833573.
-    //__ ldf(FloatRegisterImpl::D, $tmp$$Register, addrlit.low10(), $dst$$FloatRegister, rspec);
-    __ ldf(FloatRegisterImpl::D, $tmp$$Register, addrlit.low10(), as_DoubleFloatRegister($dst$$reg), rspec);
+    //__ ldf(FloatRegisterImpl::D, $constanttablebase, $constantoffset($con), $dst$$FloatRegister);
+    RegisterOrConstant con_offset = __ ensure_simm13_or_reg($constantoffset($con), $tmp$$Register);
+    __ ldf(FloatRegisterImpl::D, $constanttablebase, con_offset, as_DoubleFloatRegister($dst$$reg));
   %}
   ins_pipe(loadConFD);
 %}
@@ -8558,16 +8659,16 @@
 %}
 
 // Replicate scalar constant to packed byte values in Double register
-instruct Repl8B_immI(regD dst, immI13 src, o7RegP tmp) %{
-  match(Set dst (Replicate8B src));
-#ifdef _LP64
-  size(36);
-#else
-  size(8);
-#endif
-  format %{ "SETHI  hi(&Repl8($src)),$tmp\t!get Repl8B($src) from table\n\t"
-            "LDDF   [$tmp+lo(&Repl8($src))],$dst" %}
-  ins_encode( LdReplImmI(src, dst, tmp, (8), (1)) );
+instruct Repl8B_immI(regD dst, immI13 con, o7RegI tmp) %{
+  match(Set dst (Replicate8B con));
+  effect(KILL tmp);
+  format %{ "LDDF   [$constanttablebase + $constantoffset],$dst\t! load from constant table: Repl8B($con)" %}
+  ins_encode %{
+    // XXX This is a quick fix for 6833573.
+    //__ ldf(FloatRegisterImpl::D, $constanttablebase, $constantoffset(replicate_immI($con$$constant, 8, 1)), $dst$$FloatRegister);
+    RegisterOrConstant con_offset = __ ensure_simm13_or_reg($constantoffset(replicate_immI($con$$constant, 8, 1)), $tmp$$Register);
+    __ ldf(FloatRegisterImpl::D, $constanttablebase, con_offset, as_DoubleFloatRegister($dst$$reg));
+  %}
   ins_pipe(loadConFD);
 %}
 
@@ -8594,16 +8695,16 @@
 %}
 
 // Replicate scalar constant to packed char values in Double register
-instruct Repl4C_immI(regD dst, immI src, o7RegP tmp) %{
-  match(Set dst (Replicate4C src));
-#ifdef _LP64
-  size(36);
-#else
-  size(8);
-#endif
-  format %{ "SETHI  hi(&Repl4($src)),$tmp\t!get Repl4C($src) from table\n\t"
-            "LDDF   [$tmp+lo(&Repl4($src))],$dst" %}
-  ins_encode( LdReplImmI(src, dst, tmp, (4), (2)) );
+instruct Repl4C_immI(regD dst, immI con, o7RegI tmp) %{
+  match(Set dst (Replicate4C con));
+  effect(KILL tmp);
+  format %{ "LDDF   [$constanttablebase + $constantoffset],$dst\t! load from constant table: Repl4C($con)" %}
+  ins_encode %{
+    // XXX This is a quick fix for 6833573.
+    //__ ldf(FloatRegisterImpl::D, $constanttablebase, $constantoffset(replicate_immI($con$$constant, 4, 2)), $dst$$FloatRegister);
+    RegisterOrConstant con_offset = __ ensure_simm13_or_reg($constantoffset(replicate_immI($con$$constant, 4, 2)), $tmp$$Register);
+    __ ldf(FloatRegisterImpl::D, $constanttablebase, con_offset, as_DoubleFloatRegister($dst$$reg));
+  %}
   ins_pipe(loadConFD);
 %}
 
@@ -8630,16 +8731,16 @@
 %}
 
 // Replicate scalar constant to packed short values in Double register
-instruct Repl4S_immI(regD dst, immI src, o7RegP tmp) %{
-  match(Set dst (Replicate4S src));
-#ifdef _LP64
-  size(36);
-#else
-  size(8);
-#endif
-  format %{ "SETHI  hi(&Repl4($src)),$tmp\t!get Repl4S($src) from table\n\t"
-            "LDDF   [$tmp+lo(&Repl4($src))],$dst" %}
-  ins_encode( LdReplImmI(src, dst, tmp, (4), (2)) );
+instruct Repl4S_immI(regD dst, immI con, o7RegI tmp) %{
+  match(Set dst (Replicate4S con));
+  effect(KILL tmp);
+  format %{ "LDDF   [$constanttablebase + $constantoffset],$dst\t! load from constant table: Repl4S($con)" %}
+  ins_encode %{
+    // XXX This is a quick fix for 6833573.
+    //__ ldf(FloatRegisterImpl::D, $constanttablebase, $constantoffset(replicate_immI($con$$constant, 4, 2)), $dst$$FloatRegister);
+    RegisterOrConstant con_offset = __ ensure_simm13_or_reg($constantoffset(replicate_immI($con$$constant, 4, 2)), $tmp$$Register);
+    __ ldf(FloatRegisterImpl::D, $constanttablebase, con_offset, as_DoubleFloatRegister($dst$$reg));
+  %}
   ins_pipe(loadConFD);
 %}
 
@@ -8664,16 +8765,16 @@
 %}
 
 // Replicate scalar zero constant to packed int values in Double register
-instruct Repl2I_immI(regD dst, immI src, o7RegP tmp) %{
-  match(Set dst (Replicate2I src));
-#ifdef _LP64
-  size(36);
-#else
-  size(8);
-#endif
-  format %{ "SETHI  hi(&Repl2($src)),$tmp\t!get Repl2I($src) from table\n\t"
-            "LDDF   [$tmp+lo(&Repl2($src))],$dst" %}
-  ins_encode( LdReplImmI(src, dst, tmp, (2), (4)) );
+instruct Repl2I_immI(regD dst, immI con, o7RegI tmp) %{
+  match(Set dst (Replicate2I con));
+  effect(KILL tmp);
+  format %{ "LDDF   [$constanttablebase + $constantoffset],$dst\t! load from constant table: Repl2I($con)" %}
+  ins_encode %{
+    // XXX This is a quick fix for 6833573.
+    //__ ldf(FloatRegisterImpl::D, $constanttablebase, $constantoffset(replicate_immI($con$$constant, 2, 4)), $dst$$FloatRegister);
+    RegisterOrConstant con_offset = __ ensure_simm13_or_reg($constantoffset(replicate_immI($con$$constant, 2, 4)), $tmp$$Register);
+    __ ldf(FloatRegisterImpl::D, $constanttablebase, con_offset, as_DoubleFloatRegister($dst$$reg));
+  %}
   ins_pipe(loadConFD);
 %}
 
@@ -8929,12 +9030,27 @@
 
   ins_cost(350);
 
-  format %{  "SETHI  [hi(table_base)],O7\n\t"
-             "ADD    O7, lo(table_base), O7\n\t"
-             "LD     [O7+$switch_val], O7\n\t"
+  format %{  "ADD    $constanttablebase, $constantoffset, O7\n\t"
+             "LD     [O7 + $switch_val], O7\n\t"
              "JUMP   O7"
          %}
-  ins_encode( jump_enc( switch_val, table) );
+  ins_encode %{
+    // Calculate table address into a register.
+    Register table_reg;
+    Register label_reg = O7;
+    if (constant_offset() == 0) {
+      table_reg = $constanttablebase;
+    } else {
+      table_reg = O7;
+      RegisterOrConstant con_offset = __ ensure_simm13_or_reg($constantoffset, O7);
+      __ add($constanttablebase, con_offset, table_reg);
+    }
+
+    // Jump to base address + switch value
+    __ ld_ptr(table_reg, $switch_val$$Register, label_reg);
+    __ jmp(label_reg, G0);
+    __ delayed()->nop();
+  %}
   ins_pc_relative(1);
   ins_pipe(ialu_reg_reg);
 %}
--- a/src/cpu/sparc/vm/vm_version_sparc.hpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/cpu/sparc/vm/vm_version_sparc.hpp	Thu Dec 16 20:48:11 2010 -0800
@@ -80,9 +80,6 @@
   static bool  is_sparc64(int features) { return (features & fmaf_instructions_m) != 0; }
 
   static int maximum_niagara1_processor_count() { return 32; }
-  // Returns true if the platform is in the niagara line and
-  // newer than the niagara1.
-  static bool is_niagara1_plus();
 
 public:
   // Initialization
@@ -105,6 +102,9 @@
   static bool is_ultra3()               { return (_features & ultra3_m) == ultra3_m; }
   static bool is_sun4v()                { return (_features & sun4v_m) != 0; }
   static bool is_niagara1()             { return is_niagara1(_features); }
+  // Returns true if the platform is in the niagara line and
+  // newer than the niagara1.
+  static bool is_niagara1_plus();
   static bool is_sparc64()              { return is_sparc64(_features); }
 
   static bool has_fast_fxtof()          { return has_v9() && !is_ultra3(); }
--- a/src/cpu/x86/vm/assembler_x86.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/cpu/x86/vm/assembler_x86.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -2649,6 +2649,37 @@
   emit_byte(0xC0 | encode);
 }
 
+void Assembler::sqrtsd(XMMRegister dst, Address src) {
+  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
+  InstructionMark im(this);
+  emit_byte(0xF2);
+  prefix(src, dst);
+  emit_byte(0x0F);
+  emit_byte(0x51);
+  emit_operand(dst, src);
+}
+
+void Assembler::sqrtss(XMMRegister dst, XMMRegister src) {
+  // HMM Table D-1 says sse2
+  // NOT_LP64(assert(VM_Version::supports_sse(), ""));
+  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
+  emit_byte(0xF3);
+  int encode = prefix_and_encode(dst->encoding(), src->encoding());
+  emit_byte(0x0F);
+  emit_byte(0x51);
+  emit_byte(0xC0 | encode);
+}
+
+void Assembler::sqrtss(XMMRegister dst, Address src) {
+  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
+  InstructionMark im(this);
+  emit_byte(0xF3);
+  prefix(src, dst);
+  emit_byte(0x0F);
+  emit_byte(0x51);
+  emit_operand(dst, src);
+}
+
 void Assembler::stmxcsr( Address dst) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
   InstructionMark im(this);
@@ -4358,16 +4389,6 @@
   emit_byte(0xE8 | encode);
 }
 
-void Assembler::sqrtsd(XMMRegister dst, Address src) {
-  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  InstructionMark im(this);
-  emit_byte(0xF2);
-  prefix(src, dst);
-  emit_byte(0x0F);
-  emit_byte(0x51);
-  emit_operand(dst, src);
-}
-
 void Assembler::subq(Address dst, int32_t imm32) {
   InstructionMark im(this);
   prefixq(dst);
@@ -4929,10 +4950,6 @@
 }
 
 
-void MacroAssembler::movsd(XMMRegister dst, AddressLiteral src) {
-  movsd(dst, as_Address(src));
-}
-
 void MacroAssembler::pop_callee_saved_registers() {
   pop(rcx);
   pop(rdx);
--- a/src/cpu/x86/vm/assembler_x86.hpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/cpu/x86/vm/assembler_x86.hpp	Thu Dec 16 20:48:11 2010 -0800
@@ -135,6 +135,7 @@
 // Using noreg ensures if the dead code is incorrectly live and executed it
 // will cause an assertion failure
 #define rscratch1 noreg
+#define rscratch2 noreg
 
 #endif // _LP64
 
@@ -1352,6 +1353,10 @@
   void sqrtsd(XMMRegister dst, Address src);
   void sqrtsd(XMMRegister dst, XMMRegister src);
 
+  // Compute Square Root of Scalar Single-Precision Floating-Point Value
+  void sqrtss(XMMRegister dst, Address src);
+  void sqrtss(XMMRegister dst, XMMRegister src);
+
   void std() { emit_byte(0xfd); }
 
   void stmxcsr( Address dst );
@@ -2124,6 +2129,9 @@
   void comisd(XMMRegister dst, Address src) { Assembler::comisd(dst, src); }
   void comisd(XMMRegister dst, AddressLiteral src);
 
+  void fadd_s(Address src)        { Assembler::fadd_s(src); }
+  void fadd_s(AddressLiteral src) { Assembler::fadd_s(as_Address(src)); }
+
   void fldcw(Address src) { Assembler::fldcw(src); }
   void fldcw(AddressLiteral src);
 
@@ -2137,6 +2145,9 @@
   void fld_x(Address src) { Assembler::fld_x(src); }
   void fld_x(AddressLiteral src);
 
+  void fmul_s(Address src)        { Assembler::fmul_s(src); }
+  void fmul_s(AddressLiteral src) { Assembler::fmul_s(as_Address(src)); }
+
   void ldmxcsr(Address src) { Assembler::ldmxcsr(src); }
   void ldmxcsr(AddressLiteral src);
 
@@ -2153,10 +2164,50 @@
 
 public:
 
-  void movsd(XMMRegister dst, XMMRegister src) { Assembler::movsd(dst, src); }
-  void movsd(Address dst, XMMRegister src)     { Assembler::movsd(dst, src); }
-  void movsd(XMMRegister dst, Address src)     { Assembler::movsd(dst, src); }
-  void movsd(XMMRegister dst, AddressLiteral src);
+  void addsd(XMMRegister dst, XMMRegister src)    { Assembler::addsd(dst, src); }
+  void addsd(XMMRegister dst, Address src)        { Assembler::addsd(dst, src); }
+  void addsd(XMMRegister dst, AddressLiteral src) { Assembler::addsd(dst, as_Address(src)); }
+
+  void addss(XMMRegister dst, XMMRegister src)    { Assembler::addss(dst, src); }
+  void addss(XMMRegister dst, Address src)        { Assembler::addss(dst, src); }
+  void addss(XMMRegister dst, AddressLiteral src) { Assembler::addss(dst, as_Address(src)); }
+
+  void divsd(XMMRegister dst, XMMRegister src)    { Assembler::divsd(dst, src); }
+  void divsd(XMMRegister dst, Address src)        { Assembler::divsd(dst, src); }
+  void divsd(XMMRegister dst, AddressLiteral src) { Assembler::divsd(dst, as_Address(src)); }
+
+  void divss(XMMRegister dst, XMMRegister src)    { Assembler::divss(dst, src); }
+  void divss(XMMRegister dst, Address src)        { Assembler::divss(dst, src); }
+  void divss(XMMRegister dst, AddressLiteral src) { Assembler::divss(dst, as_Address(src)); }
+
+  void movsd(XMMRegister dst, XMMRegister src)    { Assembler::movsd(dst, src); }
+  void movsd(Address dst, XMMRegister src)        { Assembler::movsd(dst, src); }
+  void movsd(XMMRegister dst, Address src)        { Assembler::movsd(dst, src); }
+  void movsd(XMMRegister dst, AddressLiteral src) { Assembler::movsd(dst, as_Address(src)); }
+
+  void mulsd(XMMRegister dst, XMMRegister src)    { Assembler::mulsd(dst, src); }
+  void mulsd(XMMRegister dst, Address src)        { Assembler::mulsd(dst, src); }
+  void mulsd(XMMRegister dst, AddressLiteral src) { Assembler::mulsd(dst, as_Address(src)); }
+
+  void mulss(XMMRegister dst, XMMRegister src)    { Assembler::mulss(dst, src); }
+  void mulss(XMMRegister dst, Address src)        { Assembler::mulss(dst, src); }
+  void mulss(XMMRegister dst, AddressLiteral src) { Assembler::mulss(dst, as_Address(src)); }
+
+  void sqrtsd(XMMRegister dst, XMMRegister src)    { Assembler::sqrtsd(dst, src); }
+  void sqrtsd(XMMRegister dst, Address src)        { Assembler::sqrtsd(dst, src); }
+  void sqrtsd(XMMRegister dst, AddressLiteral src) { Assembler::sqrtsd(dst, as_Address(src)); }
+
+  void sqrtss(XMMRegister dst, XMMRegister src)    { Assembler::sqrtss(dst, src); }
+  void sqrtss(XMMRegister dst, Address src)        { Assembler::sqrtss(dst, src); }
+  void sqrtss(XMMRegister dst, AddressLiteral src) { Assembler::sqrtss(dst, as_Address(src)); }
+
+  void subsd(XMMRegister dst, XMMRegister src)    { Assembler::subsd(dst, src); }
+  void subsd(XMMRegister dst, Address src)        { Assembler::subsd(dst, src); }
+  void subsd(XMMRegister dst, AddressLiteral src) { Assembler::subsd(dst, as_Address(src)); }
+
+  void subss(XMMRegister dst, XMMRegister src)    { Assembler::subss(dst, src); }
+  void subss(XMMRegister dst, Address src)        { Assembler::subss(dst, src); }
+  void subss(XMMRegister dst, AddressLiteral src) { Assembler::subss(dst, as_Address(src)); }
 
   void ucomiss(XMMRegister dst, XMMRegister src) { Assembler::ucomiss(dst, src); }
   void ucomiss(XMMRegister dst, Address src) { Assembler::ucomiss(dst, src); }
--- a/src/cpu/x86/vm/c1_CodeStubs_x86.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/cpu/x86/vm/c1_CodeStubs_x86.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -483,7 +483,7 @@
 
   Register pre_val_reg = pre_val()->as_register();
 
-  ce->mem2reg(addr(), pre_val(), T_OBJECT, patch_code(), info(), false);
+  ce->mem2reg(addr(), pre_val(), T_OBJECT, patch_code(), info(), false /*wide*/, false /*unaligned*/);
 
   __ cmpptr(pre_val_reg, (int32_t) NULL_WORD);
   __ jcc(Assembler::equal, _continuation);
--- a/src/cpu/x86/vm/c1_Defs_x86.hpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/cpu/x86/vm/c1_Defs_x86.hpp	Thu Dec 16 20:48:11 2010 -0800
@@ -61,8 +61,8 @@
   pd_nof_xmm_regs_linearscan = pd_nof_xmm_regs_frame_map, // number of registers visible to linear scan
   pd_first_cpu_reg = 0,
   pd_last_cpu_reg = NOT_LP64(5) LP64_ONLY(11),
-  pd_first_byte_reg = 2,
-  pd_last_byte_reg = 5,
+  pd_first_byte_reg = NOT_LP64(2) LP64_ONLY(0),
+  pd_last_byte_reg = NOT_LP64(5) LP64_ONLY(11),
   pd_first_fpu_reg = pd_nof_cpu_regs_frame_map,
   pd_last_fpu_reg =  pd_first_fpu_reg + 7,
   pd_first_xmm_reg = pd_nof_cpu_regs_frame_map + pd_nof_fpu_regs_frame_map,
--- a/src/cpu/x86/vm/c1_FrameMap_x86.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/cpu/x86/vm/c1_FrameMap_x86.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -158,9 +158,11 @@
   map_register( 6, r8);    r8_opr = LIR_OprFact::single_cpu(6);
   map_register( 7, r9);    r9_opr = LIR_OprFact::single_cpu(7);
   map_register( 8, r11);  r11_opr = LIR_OprFact::single_cpu(8);
-  map_register( 9, r12);  r12_opr = LIR_OprFact::single_cpu(9);
-  map_register(10, r13);  r13_opr = LIR_OprFact::single_cpu(10);
-  map_register(11, r14);  r14_opr = LIR_OprFact::single_cpu(11);
+  map_register( 9, r13);  r13_opr = LIR_OprFact::single_cpu(9);
+  map_register(10, r14);  r14_opr = LIR_OprFact::single_cpu(10);
+  // r12 is allocated conditionally. With compressed oops it holds
+  // the heapbase value and is not visible to the allocator.
+  map_register(11, r12);  r12_opr = LIR_OprFact::single_cpu(11);
   // The unallocatable registers are at the end
   map_register(12, r10);  r10_opr = LIR_OprFact::single_cpu(12);
   map_register(13, r15);  r15_opr = LIR_OprFact::single_cpu(13);
@@ -191,9 +193,9 @@
   _caller_save_cpu_regs[6]  = r8_opr;
   _caller_save_cpu_regs[7]  = r9_opr;
   _caller_save_cpu_regs[8]  = r11_opr;
-  _caller_save_cpu_regs[9]  = r12_opr;
-  _caller_save_cpu_regs[10] = r13_opr;
-  _caller_save_cpu_regs[11] = r14_opr;
+  _caller_save_cpu_regs[9]  = r13_opr;
+  _caller_save_cpu_regs[10] = r14_opr;
+  _caller_save_cpu_regs[11] = r12_opr;
 #endif // _LP64
 
 
--- a/src/cpu/x86/vm/c1_FrameMap_x86.hpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/cpu/x86/vm/c1_FrameMap_x86.hpp	Thu Dec 16 20:48:11 2010 -0800
@@ -130,4 +130,15 @@
     return _caller_save_xmm_regs[i];
   }
 
+  static int adjust_reg_range(int range) {
+    // Reduce the number of available regs (to free r12) in case of compressed oops
+    if (UseCompressedOops) return range - 1;
+    return range;
+  }
+
+  static int nof_caller_save_cpu_regs() { return adjust_reg_range(pd_nof_caller_save_cpu_regs_frame_map); }
+  static int last_cpu_reg()             { return adjust_reg_range(pd_last_cpu_reg);  }
+  static int last_byte_reg()            { return adjust_reg_range(pd_last_byte_reg); }
+
 #endif // CPU_X86_VM_C1_FRAMEMAP_X86_HPP
+
--- a/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -343,8 +343,8 @@
   Register receiver = FrameMap::receiver_opr->as_register();
   Register ic_klass = IC_Klass;
   const int ic_cmp_size = LP64_ONLY(10) NOT_LP64(9);
-
-  if (!VerifyOops) {
+  const bool do_post_padding = VerifyOops || UseCompressedOops;
+  if (!do_post_padding) {
     // insert some nops so that the verified entry point is aligned on CodeEntryAlignment
     while ((__ offset() + ic_cmp_size) % CodeEntryAlignment != 0) {
       __ nop();
@@ -352,8 +352,8 @@
   }
   int offset = __ offset();
   __ inline_cache_check(receiver, IC_Klass);
-  assert(__ offset() % CodeEntryAlignment == 0 || VerifyOops, "alignment must be correct");
-  if (VerifyOops) {
+  assert(__ offset() % CodeEntryAlignment == 0 || do_post_padding, "alignment must be correct");
+  if (do_post_padding) {
     // force alignment after the cache check.
     // It's been verified to be aligned if !VerifyOops
     __ align(CodeEntryAlignment);
@@ -559,16 +559,16 @@
   __ movptr (rax, arg1->as_register());
 
   // Get addresses of first characters from both Strings
-  __ movptr (rsi, Address(rax, java_lang_String::value_offset_in_bytes()));
-  __ movptr (rcx, Address(rax, java_lang_String::offset_offset_in_bytes()));
-  __ lea    (rsi, Address(rsi, rcx, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR)));
+  __ load_heap_oop(rsi, Address(rax, java_lang_String::value_offset_in_bytes()));
+  __ movptr       (rcx, Address(rax, java_lang_String::offset_offset_in_bytes()));
+  __ lea          (rsi, Address(rsi, rcx, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR)));
 
 
   // rbx, may be NULL
   add_debug_info_for_null_check_here(info);
-  __ movptr (rdi, Address(rbx, java_lang_String::value_offset_in_bytes()));
-  __ movptr (rcx, Address(rbx, java_lang_String::offset_offset_in_bytes()));
-  __ lea    (rdi, Address(rdi, rcx, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR)));
+  __ load_heap_oop(rdi, Address(rbx, java_lang_String::value_offset_in_bytes()));
+  __ movptr       (rcx, Address(rbx, java_lang_String::offset_offset_in_bytes()));
+  __ lea          (rdi, Address(rdi, rcx, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR)));
 
   // compute minimum length (in rax) and difference of lengths (on top of stack)
   if (VM_Version::supports_cmov()) {
@@ -696,10 +696,15 @@
   LIR_Const* c = src->as_constant_ptr();
 
   switch (c->type()) {
-    case T_INT:
+    case T_INT: {
+      assert(patch_code == lir_patch_none, "no patching handled here");
+      __ movl(dest->as_register(), c->as_jint());
+      break;
+    }
+
     case T_ADDRESS: {
       assert(patch_code == lir_patch_none, "no patching handled here");
-      __ movl(dest->as_register(), c->as_jint());
+      __ movptr(dest->as_register(), c->as_jint());
       break;
     }
 
@@ -780,8 +785,11 @@
   switch (c->type()) {
     case T_INT:  // fall through
     case T_FLOAT:
+      __ movl(frame_map()->address_for_slot(dest->single_stack_ix()), c->as_jint_bits());
+      break;
+
     case T_ADDRESS:
-      __ movl(frame_map()->address_for_slot(dest->single_stack_ix()), c->as_jint_bits());
+      __ movptr(frame_map()->address_for_slot(dest->single_stack_ix()), c->as_jint_bits());
       break;
 
     case T_OBJECT:
@@ -806,7 +814,7 @@
   }
 }
 
-void LIR_Assembler::const2mem(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmitInfo* info ) {
+void LIR_Assembler::const2mem(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmitInfo* info, bool wide) {
   assert(src->is_constant(), "should not call otherwise");
   assert(dest->is_address(), "should not call otherwise");
   LIR_Const* c = src->as_constant_ptr();
@@ -816,14 +824,21 @@
   switch (type) {
     case T_INT:    // fall through
     case T_FLOAT:
+      __ movl(as_Address(addr), c->as_jint_bits());
+      break;
+
     case T_ADDRESS:
-      __ movl(as_Address(addr), c->as_jint_bits());
+      __ movptr(as_Address(addr), c->as_jint_bits());
       break;
 
     case T_OBJECT:  // fall through
     case T_ARRAY:
       if (c->as_jobject() == NULL) {
-        __ movptr(as_Address(addr), NULL_WORD);
+        if (UseCompressedOops && !wide) {
+          __ movl(as_Address(addr), (int32_t)NULL_WORD);
+        } else {
+          __ movptr(as_Address(addr), NULL_WORD);
+        }
       } else {
         if (is_literal_address(addr)) {
           ShouldNotReachHere();
@@ -831,8 +846,14 @@
         } else {
 #ifdef _LP64
           __ movoop(rscratch1, c->as_jobject());
-          null_check_here = code_offset();
-          __ movptr(as_Address_lo(addr), rscratch1);
+          if (UseCompressedOops && !wide) {
+            __ encode_heap_oop(rscratch1);
+            null_check_here = code_offset();
+            __ movl(as_Address_lo(addr), rscratch1);
+          } else {
+            null_check_here = code_offset();
+            __ movptr(as_Address_lo(addr), rscratch1);
+          }
 #else
           __ movoop(as_Address(addr), c->as_jobject());
 #endif
@@ -1009,22 +1030,28 @@
 }
 
 
-void LIR_Assembler::reg2mem(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_PatchCode patch_code, CodeEmitInfo* info, bool pop_fpu_stack, bool /* unaligned */) {
+void LIR_Assembler::reg2mem(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_PatchCode patch_code, CodeEmitInfo* info, bool pop_fpu_stack, bool wide, bool /* unaligned */) {
   LIR_Address* to_addr = dest->as_address_ptr();
   PatchingStub* patch = NULL;
+  Register compressed_src = rscratch1;
 
   if (type == T_ARRAY || type == T_OBJECT) {
     __ verify_oop(src->as_register());
+#ifdef _LP64
+    if (UseCompressedOops && !wide) {
+      __ movptr(compressed_src, src->as_register());
+      __ encode_heap_oop(compressed_src);
+    }
+#endif
   }
+
   if (patch_code != lir_patch_none) {
     patch = new PatchingStub(_masm, PatchingStub::access_field_id);
     Address toa = as_Address(to_addr);
     assert(toa.disp() != 0, "must have");
   }
-  if (info != NULL) {
-    add_debug_info_for_null_check_here(info);
-  }
-
+
+  int null_check_here = code_offset();
   switch (type) {
     case T_FLOAT: {
       if (src->is_single_xmm()) {
@@ -1050,13 +1077,17 @@
       break;
     }
 
-    case T_ADDRESS: // fall through
     case T_ARRAY:   // fall through
     case T_OBJECT:  // fall through
-#ifdef _LP64
+      if (UseCompressedOops && !wide) {
+        __ movl(as_Address(to_addr), compressed_src);
+      } else {
+        __ movptr(as_Address(to_addr), src->as_register());
+      }
+      break;
+    case T_ADDRESS:
       __ movptr(as_Address(to_addr), src->as_register());
       break;
-#endif // _LP64
     case T_INT:
       __ movl(as_Address(to_addr), src->as_register());
       break;
@@ -1113,6 +1144,9 @@
     default:
       ShouldNotReachHere();
   }
+  if (info != NULL) {
+    add_debug_info_for_null_check(null_check_here, info);
+  }
 
   if (patch_code != lir_patch_none) {
     patching_epilog(patch, patch_code, to_addr->base()->as_register(), info);
@@ -1196,7 +1230,7 @@
 }
 
 
-void LIR_Assembler::mem2reg(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_PatchCode patch_code, CodeEmitInfo* info, bool /* unaligned */) {
+void LIR_Assembler::mem2reg(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_PatchCode patch_code, CodeEmitInfo* info, bool wide, bool /* unaligned */) {
   assert(src->is_address(), "should not call otherwise");
   assert(dest->is_register(), "should not call otherwise");
 
@@ -1250,13 +1284,18 @@
       break;
     }
 
-    case T_ADDRESS: // fall through
     case T_OBJECT:  // fall through
     case T_ARRAY:   // fall through
-#ifdef _LP64
+      if (UseCompressedOops && !wide) {
+        __ movl(dest->as_register(), from_addr);
+      } else {
+        __ movptr(dest->as_register(), from_addr);
+      }
+      break;
+
+    case T_ADDRESS:
       __ movptr(dest->as_register(), from_addr);
       break;
-#endif // _L64
     case T_INT:
       __ movl(dest->as_register(), from_addr);
       break;
@@ -1351,6 +1390,11 @@
   }
 
   if (type == T_ARRAY || type == T_OBJECT) {
+#ifdef _LP64
+    if (UseCompressedOops && !wide) {
+      __ decode_heap_oop(dest->as_register());
+    }
+#endif
     __ verify_oop(dest->as_register());
   }
 }
@@ -1672,11 +1716,8 @@
     ciMethod* method = op->profiled_method();
     assert(method != NULL, "Should have method");
     int bci = op->profiled_bci();
-    md = method->method_data();
-    if (md == NULL) {
-      bailout("out of memory building methodDataOop");
-      return;
-    }
+    md = method->method_data_or_null();
+    assert(md != NULL, "Sanity");
     data = md->bci_to_data(bci);
     assert(data != NULL,                "need data for type check");
     assert(data->is_ReceiverTypeData(), "need ReceiverTypeData for type check");
@@ -1690,7 +1731,7 @@
   } else if (obj == klass_RInfo) {
     klass_RInfo = dst;
   }
-  if (k->is_loaded()) {
+  if (k->is_loaded() && !UseCompressedOops) {
     select_different_registers(obj, dst, k_RInfo, klass_RInfo);
   } else {
     Rtmp1 = op->tmp3()->as_register();
@@ -1727,21 +1768,26 @@
   if (op->fast_check()) {
     // get object class
     // not a safepoint as obj null check happens earlier
-    if (k->is_loaded()) {
 #ifdef _LP64
-      __ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes()));
-#else
-      __ cmpoop(Address(obj, oopDesc::klass_offset_in_bytes()), k->constant_encoding());
-#endif // _LP64
+    if (UseCompressedOops) {
+      __ load_klass(Rtmp1, obj);
+      __ cmpptr(k_RInfo, Rtmp1);
     } else {
       __ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes()));
     }
+#else
+    if (k->is_loaded()) {
+      __ cmpoop(Address(obj, oopDesc::klass_offset_in_bytes()), k->constant_encoding());
+    } else {
+      __ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes()));
+    }
+#endif
     __ jcc(Assembler::notEqual, *failure_target);
     // successful cast, fall through to profile or jump
   } else {
     // get object class
     // not a safepoint as obj null check happens earlier
-    __ movptr(klass_RInfo, Address(obj, oopDesc::klass_offset_in_bytes()));
+    __ load_klass(klass_RInfo, obj);
     if (k->is_loaded()) {
       // See if we get an immediate positive hit
 #ifdef _LP64
@@ -1796,7 +1842,7 @@
     Register mdo  = klass_RInfo, recv = k_RInfo;
     __ bind(profile_cast_success);
     __ movoop(mdo, md->constant_encoding());
-    __ movptr(recv, Address(obj, oopDesc::klass_offset_in_bytes()));
+    __ load_klass(recv, obj);
     Label update_done;
     type_profile_helper(mdo, md, data, recv, success);
     __ jmp(*success);
@@ -1830,11 +1876,8 @@
       ciMethod* method = op->profiled_method();
       assert(method != NULL, "Should have method");
       int bci = op->profiled_bci();
-      md = method->method_data();
-      if (md == NULL) {
-        bailout("out of memory building methodDataOop");
-        return;
-      }
+      md = method->method_data_or_null();
+      assert(md != NULL, "Sanity");
       data = md->bci_to_data(bci);
       assert(data != NULL,                "need data for type check");
       assert(data->is_ReceiverTypeData(), "need ReceiverTypeData for type check");
@@ -1860,10 +1903,10 @@
     }
 
     add_debug_info_for_null_check_here(op->info_for_exception());
-    __ movptr(k_RInfo, Address(array, oopDesc::klass_offset_in_bytes()));
-    __ movptr(klass_RInfo, Address(value, oopDesc::klass_offset_in_bytes()));
-
-    // get instance klass
+    __ load_klass(k_RInfo, array);
+    __ load_klass(klass_RInfo, value);
+
+    // get instance klass (it's already uncompressed)
     __ movptr(k_RInfo, Address(k_RInfo, objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc)));
     // perform the fast part of the checking logic
     __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, success_target, failure_target, NULL);
@@ -1882,7 +1925,7 @@
       Register mdo  = klass_RInfo, recv = k_RInfo;
       __ bind(profile_cast_success);
       __ movoop(mdo, md->constant_encoding());
-      __ movptr(recv, Address(value, oopDesc::klass_offset_in_bytes()));
+      __ load_klass(recv, value);
       Label update_done;
       type_profile_helper(mdo, md, data, recv, &done);
       __ jmpb(done);
@@ -1946,12 +1989,31 @@
     assert(cmpval != newval, "cmp and new values must be in different registers");
     assert(cmpval != addr, "cmp and addr must be in different registers");
     assert(newval != addr, "new value and addr must be in different registers");
-    if (os::is_MP()) {
-      __ lock();
-    }
+
     if ( op->code() == lir_cas_obj) {
-      __ cmpxchgptr(newval, Address(addr, 0));
-    } else if (op->code() == lir_cas_int) {
+#ifdef _LP64
+      if (UseCompressedOops) {
+        __ encode_heap_oop(cmpval);
+        __ mov(rscratch1, newval);
+        __ encode_heap_oop(rscratch1);
+        if (os::is_MP()) {
+          __ lock();
+        }
+        // cmpval (rax) is implicitly used by this instruction
+        __ cmpxchgl(rscratch1, Address(addr, 0));
+      } else
+#endif
+      {
+        if (os::is_MP()) {
+          __ lock();
+        }
+        __ cmpxchgptr(newval, Address(addr, 0));
+      }
+    } else {
+      assert(op->code() == lir_cas_int, "lir_cas_int expected");
+      if (os::is_MP()) {
+        __ lock();
+      }
       __ cmpxchgl(newval, Address(addr, 0));
     }
 #ifdef _LP64
@@ -3193,8 +3255,13 @@
   }
 
   if (flags & LIR_OpArrayCopy::type_check) {
-    __ movptr(tmp, src_klass_addr);
-    __ cmpptr(tmp, dst_klass_addr);
+    if (UseCompressedOops) {
+      __ movl(tmp, src_klass_addr);
+      __ cmpl(tmp, dst_klass_addr);
+    } else {
+      __ movptr(tmp, src_klass_addr);
+      __ cmpptr(tmp, dst_klass_addr);
+    }
     __ jcc(Assembler::notEqual, *stub->entry());
   }
 
@@ -3209,13 +3276,23 @@
     // but not necessarily exactly of type default_type.
     Label known_ok, halt;
     __ movoop(tmp, default_type->constant_encoding());
+#ifdef _LP64
+    if (UseCompressedOops) {
+      __ encode_heap_oop(tmp);
+    }
+#endif
+
     if (basic_type != T_OBJECT) {
-      __ cmpptr(tmp, dst_klass_addr);
+
+      if (UseCompressedOops) __ cmpl(tmp, dst_klass_addr);
+      else                   __ cmpptr(tmp, dst_klass_addr);
       __ jcc(Assembler::notEqual, halt);
-      __ cmpptr(tmp, src_klass_addr);
+      if (UseCompressedOops) __ cmpl(tmp, src_klass_addr);
+      else                   __ cmpptr(tmp, src_klass_addr);
       __ jcc(Assembler::equal, known_ok);
     } else {
-      __ cmpptr(tmp, dst_klass_addr);
+      if (UseCompressedOops) __ cmpl(tmp, dst_klass_addr);
+      else                   __ cmpptr(tmp, dst_klass_addr);
       __ jcc(Assembler::equal, known_ok);
       __ cmpptr(src, dst);
       __ jcc(Assembler::equal, known_ok);
@@ -3289,11 +3366,8 @@
   int bci          = op->profiled_bci();
 
   // Update counter for all call types
-  ciMethodData* md = method->method_data();
-  if (md == NULL) {
-    bailout("out of memory building methodDataOop");
-    return;
-  }
+  ciMethodData* md = method->method_data_or_null();
+  assert(md != NULL, "Sanity");
   ciProfileData* data = md->bci_to_data(bci);
   assert(data->is_CounterData(), "need CounterData for calls");
   assert(op->mdo()->is_single_cpu(),  "mdo must be allocated");
@@ -3344,7 +3418,7 @@
         }
       }
     } else {
-      __ movptr(recv, Address(recv, oopDesc::klass_offset_in_bytes()));
+      __ load_klass(recv, recv);
       Label update_done;
       type_profile_helper(mdo, md, data, recv, &update_done);
       // Receiver did not match any saved receiver and there is no empty row for it.
--- a/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -874,6 +874,10 @@
 
 void LIRGenerator::do_ArrayCopy(Intrinsic* x) {
   assert(x->number_of_arguments() == 5, "wrong type");
+
+  // Make all state_for calls early since they can emit code
+  CodeEmitInfo* info = state_for(x, x->state());
+
   LIRItem src(x->argument_at(0), this);
   LIRItem src_pos(x->argument_at(1), this);
   LIRItem dst(x->argument_at(2), this);
@@ -916,7 +920,6 @@
   ciArrayKlass* expected_type;
   arraycopy_helper(x, &flags, &expected_type);
 
-  CodeEmitInfo* info = state_for(x, x->state()); // we may want to have stack (deoptimization?)
   __ arraycopy(src.result(), src_pos.result(), dst.result(), dst_pos.result(), length.result(), tmp, expected_type, flags, info); // does add_safepoint
 }
 
@@ -1151,9 +1154,12 @@
     stub = new SimpleExceptionStub(Runtime1::throw_class_cast_exception_id, obj.result(), info_for_exception);
   }
   LIR_Opr reg = rlock_result(x);
+  LIR_Opr tmp3 = LIR_OprFact::illegalOpr;
+  if (!x->klass()->is_loaded() || UseCompressedOops) {
+    tmp3 = new_register(objectType);
+  }
   __ checkcast(reg, obj.result(), x->klass(),
-               new_register(objectType), new_register(objectType),
-               !x->klass()->is_loaded() ? new_register(objectType) : LIR_OprFact::illegalOpr,
+               new_register(objectType), new_register(objectType), tmp3,
                x->direct_compare(), info_for_exception, patching_info, stub,
                x->profiled_method(), x->profiled_bci());
 }
@@ -1170,9 +1176,12 @@
     patching_info = state_for(x, x->state_before());
   }
   obj.load_item();
+  LIR_Opr tmp3 = LIR_OprFact::illegalOpr;
+  if (!x->klass()->is_loaded() || UseCompressedOops) {
+    tmp3 = new_register(objectType);
+  }
   __ instanceof(reg, obj.result(), x->klass(),
-                new_register(objectType), new_register(objectType),
-                !x->klass()->is_loaded() ? new_register(objectType) : LIR_OprFact::illegalOpr,
+                new_register(objectType), new_register(objectType), tmp3,
                 x->direct_compare(), patching_info, x->profiled_method(), x->profiled_bci());
 }
 
--- a/src/cpu/x86/vm/c1_LinearScan_x86.hpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/cpu/x86/vm/c1_LinearScan_x86.hpp	Thu Dec 16 20:48:11 2010 -0800
@@ -31,18 +31,17 @@
   assert(FrameMap::rsp_opr->cpu_regnr() == 6, "wrong assumption below");
   assert(FrameMap::rbp_opr->cpu_regnr() == 7, "wrong assumption below");
   assert(reg_num >= 0, "invalid reg_num");
-
-  return reg_num < 6 || reg_num > 7;
 #else
-  // rsp and rbp, r10, r15 (numbers 6 ancd 7) are ignored
+  // rsp and rbp, r10, r15 (numbers [12,15]) are ignored
+  // r12 (number 11) is conditional on compressed oops.
+  assert(FrameMap::r12_opr->cpu_regnr() == 11, "wrong assumption below");
   assert(FrameMap::r10_opr->cpu_regnr() == 12, "wrong assumption below");
   assert(FrameMap::r15_opr->cpu_regnr() == 13, "wrong assumption below");
   assert(FrameMap::rsp_opr->cpu_regnrLo() == 14, "wrong assumption below");
   assert(FrameMap::rbp_opr->cpu_regnrLo() == 15, "wrong assumption below");
   assert(reg_num >= 0, "invalid reg_num");
-
-  return reg_num < 12 || reg_num > 15;
 #endif // _LP64
+  return reg_num <= FrameMap::last_cpu_reg() || reg_num >= pd_nof_cpu_regs_frame_map;
 }
 
 inline int LinearScan::num_physical_regs(BasicType type) {
@@ -104,7 +103,7 @@
   if (allocator()->gen()->is_vreg_flag_set(cur->reg_num(), LIRGenerator::byte_reg)) {
     assert(cur->type() != T_FLOAT && cur->type() != T_DOUBLE, "cpu regs only");
     _first_reg = pd_first_byte_reg;
-    _last_reg = pd_last_byte_reg;
+    _last_reg = FrameMap::last_byte_reg();
     return true;
   } else if ((UseSSE >= 1 && cur->type() == T_FLOAT) || (UseSSE >= 2 && cur->type() == T_DOUBLE)) {
     _first_reg = pd_first_xmm_reg;
--- a/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -155,11 +155,26 @@
     // This assumes that all prototype bits fit in an int32_t
     movptr(Address(obj, oopDesc::mark_offset_in_bytes ()), (int32_t)(intptr_t)markOopDesc::prototype());
   }
+#ifdef _LP64
+  if (UseCompressedOops) { // Take care not to kill klass
+    movptr(t1, klass);
+    encode_heap_oop_not_null(t1);
+    movl(Address(obj, oopDesc::klass_offset_in_bytes()), t1);
+  } else
+#endif
+  {
+    movptr(Address(obj, oopDesc::klass_offset_in_bytes()), klass);
+  }
 
-  movptr(Address(obj, oopDesc::klass_offset_in_bytes()), klass);
   if (len->is_valid()) {
     movl(Address(obj, arrayOopDesc::length_offset_in_bytes()), len);
   }
+#ifdef _LP64
+  else if (UseCompressedOops) {
+    xorptr(t1, t1);
+    store_klass_gap(obj, t1);
+  }
+#endif
 }
 
 
@@ -230,7 +245,7 @@
 void C1_MacroAssembler::initialize_object(Register obj, Register klass, Register var_size_in_bytes, int con_size_in_bytes, Register t1, Register t2) {
   assert((con_size_in_bytes & MinObjAlignmentInBytesMask) == 0,
          "con_size_in_bytes is not multiple of alignment");
-  const int hdr_size_in_bytes = instanceOopDesc::base_offset_in_bytes();
+  const int hdr_size_in_bytes = instanceOopDesc::header_size() * HeapWordSize;
 
   initialize_header(obj, klass, noreg, t1, t2);
 
@@ -317,13 +332,19 @@
   // check against inline cache
   assert(!MacroAssembler::needs_explicit_null_check(oopDesc::klass_offset_in_bytes()), "must add explicit null check");
   int start_offset = offset();
-  cmpptr(iCache, Address(receiver, oopDesc::klass_offset_in_bytes()));
+
+  if (UseCompressedOops) {
+    load_klass(rscratch1, receiver);
+    cmpptr(rscratch1, iCache);
+  } else {
+    cmpptr(iCache, Address(receiver, oopDesc::klass_offset_in_bytes()));
+  }
   // if icache check fails, then jump to runtime routine
   // Note: RECEIVER must still contain the receiver!
   jump_cc(Assembler::notEqual,
           RuntimeAddress(SharedRuntime::get_ic_miss_stub()));
   const int ic_cmp_size = LP64_ONLY(10) NOT_LP64(9);
-  assert(offset() - start_offset == ic_cmp_size, "check alignment in emit_method_entry");
+  assert(UseCompressedOops || offset() - start_offset == ic_cmp_size, "check alignment in emit_method_entry");
 }
 
 
--- a/src/cpu/x86/vm/c1_Runtime1_x86.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/cpu/x86/vm/c1_Runtime1_x86.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -1261,7 +1261,7 @@
         // load the klass and check the has finalizer flag
         Label register_finalizer;
         Register t = rsi;
-        __ movptr(t, Address(rax, oopDesc::klass_offset_in_bytes()));
+        __ load_klass(t, rax);
         __ movl(t, Address(t, Klass::access_flags_offset_in_bytes() + sizeof(oopDesc)));
         __ testl(t, JVM_ACC_HAS_FINALIZER);
         __ jcc(Assembler::notZero, register_finalizer);
--- a/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -2197,9 +2197,6 @@
 
     __ enter(); // required for proper stackwalking of RuntimeStub frame
 
-    checkcast_copy_entry  = __ pc();
-    BLOCK_COMMENT("Entry:");
-
 #ifdef ASSERT
     // caller guarantees that the arrays really are different
     // otherwise, we would have to make conjoint checks
@@ -2210,26 +2207,28 @@
     }
 #endif //ASSERT
 
-    // allocate spill slots for r13, r14
-    enum {
-      saved_r13_offset,
-      saved_r14_offset,
-      saved_rbp_offset,
-      saved_rip_offset,
-      saved_rarg0_offset
-    };
-    __ subptr(rsp, saved_rbp_offset * wordSize);
-    __ movptr(Address(rsp, saved_r13_offset * wordSize), r13);
-    __ movptr(Address(rsp, saved_r14_offset * wordSize), r14);
     setup_arg_regs(4); // from => rdi, to => rsi, length => rdx
                        // ckoff => rcx, ckval => r8
                        // r9 and r10 may be used to save non-volatile registers
 #ifdef _WIN64
     // last argument (#4) is on stack on Win64
-    const int ckval_offset = saved_rarg0_offset + 4;
-    __ movptr(ckval, Address(rsp, ckval_offset * wordSize));
+    __ movptr(ckval, Address(rsp, 6 * wordSize));
 #endif
 
+    // Caller of this entry point must set up the argument registers.
+    checkcast_copy_entry  = __ pc();
+    BLOCK_COMMENT("Entry:");
+
+    // allocate spill slots for r13, r14
+    enum {
+      saved_r13_offset,
+      saved_r14_offset,
+      saved_rbp_offset
+    };
+    __ subptr(rsp, saved_rbp_offset * wordSize);
+    __ movptr(Address(rsp, saved_r13_offset * wordSize), r13);
+    __ movptr(Address(rsp, saved_r14_offset * wordSize), r14);
+
     // check that int operands are properly extended to size_t
     assert_clean_int(length, rax);
     assert_clean_int(ckoff, rax);
@@ -2443,11 +2442,10 @@
     const Register src_pos    = c_rarg1;  // source position
     const Register dst        = c_rarg2;  // destination array oop
     const Register dst_pos    = c_rarg3;  // destination position
-    // elements count is on stack on Win64
-#ifdef _WIN64
-#define C_RARG4 Address(rsp, 6 * wordSize)
+#ifndef _WIN64
+    const Register length     = c_rarg4;
 #else
-#define C_RARG4 c_rarg4
+    const Address  length(rsp, 6 * wordSize);  // elements count is on stack on Win64
 #endif
 
     { int modulus = CodeEntryAlignment;
@@ -2514,27 +2512,27 @@
     // registers used as temp
     const Register r11_length    = r11; // elements count to copy
     const Register r10_src_klass = r10; // array klass
-    const Register r9_dst_klass  = r9;  // dest array klass
 
     //  if (length < 0) return -1;
-    __ movl(r11_length, C_RARG4);       // length (elements count, 32-bits value)
+    __ movl(r11_length, length);        // length (elements count, 32-bits value)
     __ testl(r11_length, r11_length);
     __ jccb(Assembler::negative, L_failed_0);
 
     __ load_klass(r10_src_klass, src);
 #ifdef ASSERT
     //  assert(src->klass() != NULL);
-    BLOCK_COMMENT("assert klasses not null");
-    { Label L1, L2;
+    {
+      BLOCK_COMMENT("assert klasses not null {");
+      Label L1, L2;
       __ testptr(r10_src_klass, r10_src_klass);
       __ jcc(Assembler::notZero, L2);   // it is broken if klass is NULL
       __ bind(L1);
       __ stop("broken null klass");
       __ bind(L2);
-      __ load_klass(r9_dst_klass, dst);
-      __ cmpq(r9_dst_klass, 0);
+      __ load_klass(rax, dst);
+      __ cmpq(rax, 0);
       __ jcc(Assembler::equal, L1);     // this would be broken also
-      BLOCK_COMMENT("assert done");
+      BLOCK_COMMENT("} assert klasses not null done");
     }
 #endif
 
@@ -2546,34 +2544,36 @@
     //   array_tag: typeArray = 0x3, objArray = 0x2, non-array = 0x0
     //
 
-    int lh_offset = klassOopDesc::header_size() * HeapWordSize +
-                    Klass::layout_helper_offset_in_bytes();
-
-    const Register rax_lh = rax;  // layout helper
-
-    __ movl(rax_lh, Address(r10_src_klass, lh_offset));
+    const int lh_offset = klassOopDesc::header_size() * HeapWordSize +
+                          Klass::layout_helper_offset_in_bytes();
 
     // Handle objArrays completely differently...
-    jint objArray_lh = Klass::array_layout_helper(T_OBJECT);
-    __ cmpl(rax_lh, objArray_lh);
+    const jint objArray_lh = Klass::array_layout_helper(T_OBJECT);
+    __ cmpl(Address(r10_src_klass, lh_offset), objArray_lh);
     __ jcc(Assembler::equal, L_objArray);
 
     //  if (src->klass() != dst->klass()) return -1;
-    __ load_klass(r9_dst_klass, dst);
-    __ cmpq(r10_src_klass, r9_dst_klass);
+    __ load_klass(rax, dst);
+    __ cmpq(r10_src_klass, rax);
     __ jcc(Assembler::notEqual, L_failed);
 
+    const Register rax_lh = rax;  // layout helper
+    __ movl(rax_lh, Address(r10_src_klass, lh_offset));
+
     //  if (!src->is_Array()) return -1;
     __ cmpl(rax_lh, Klass::_lh_neutral_value);
     __ jcc(Assembler::greaterEqual, L_failed);
 
     // At this point, it is known to be a typeArray (array_tag 0x3).
 #ifdef ASSERT
-    { Label L;
+    {
+      BLOCK_COMMENT("assert primitive array {");
+      Label L;
       __ cmpl(rax_lh, (Klass::_lh_array_tag_type_value << Klass::_lh_array_tag_shift));
       __ jcc(Assembler::greaterEqual, L);
       __ stop("must be a primitive array");
       __ bind(L);
+      BLOCK_COMMENT("} assert primitive array done");
     }
 #endif
 
@@ -2631,11 +2631,14 @@
 
   __ BIND(L_copy_longs);
 #ifdef ASSERT
-    { Label L;
+    {
+      BLOCK_COMMENT("assert long copy {");
+      Label L;
       __ cmpl(rax_elsize, LogBytesPerLong);
       __ jcc(Assembler::equal, L);
       __ stop("must be long copy, but elsize is wrong");
       __ bind(L);
+      BLOCK_COMMENT("} assert long copy done");
     }
 #endif
     __ lea(from, Address(src, src_pos, Address::times_8, 0));// src_addr
@@ -2645,12 +2648,12 @@
 
     // objArrayKlass
   __ BIND(L_objArray);
-    // live at this point:  r10_src_klass, src[_pos], dst[_pos]
+    // live at this point:  r10_src_klass, r11_length, src[_pos], dst[_pos]
 
     Label L_plain_copy, L_checkcast_copy;
     //  test array classes for subtyping
-    __ load_klass(r9_dst_klass, dst);
-    __ cmpq(r10_src_klass, r9_dst_klass); // usual case is exact equality
+    __ load_klass(rax, dst);
+    __ cmpq(r10_src_klass, rax); // usual case is exact equality
     __ jcc(Assembler::notEqual, L_checkcast_copy);
 
     // Identically typed arrays can be copied without element-wise checks.
@@ -2666,41 +2669,33 @@
     __ jump(RuntimeAddress(oop_copy_entry));
 
   __ BIND(L_checkcast_copy);
-    // live at this point:  r10_src_klass, !r11_length
+    // live at this point:  r10_src_klass, r11_length, rax (dst_klass)
     {
-      // assert(r11_length == C_RARG4); // will reload from here
-      Register r11_dst_klass = r11;
-      __ load_klass(r11_dst_klass, dst);
-
       // Before looking at dst.length, make sure dst is also an objArray.
-      __ cmpl(Address(r11_dst_klass, lh_offset), objArray_lh);
+      __ cmpl(Address(rax, lh_offset), objArray_lh);
       __ jcc(Assembler::notEqual, L_failed);
 
       // It is safe to examine both src.length and dst.length.
-#ifndef _WIN64
-      arraycopy_range_checks(src, src_pos, dst, dst_pos, C_RARG4,
-                             rax, L_failed);
-#else
-      __ movl(r11_length, C_RARG4);     // reload
       arraycopy_range_checks(src, src_pos, dst, dst_pos, r11_length,
                              rax, L_failed);
+
+      const Register r11_dst_klass = r11;
       __ load_klass(r11_dst_klass, dst); // reload
-#endif
 
       // Marshal the base address arguments now, freeing registers.
       __ lea(from, Address(src, src_pos, TIMES_OOP,
                    arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
       __ lea(to,   Address(dst, dst_pos, TIMES_OOP,
                    arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
-      __ movl(count, C_RARG4);          // length (reloaded)
+      __ movl(count, length);           // length (reloaded)
       Register sco_temp = c_rarg3;      // this register is free now
       assert_different_registers(from, to, count, sco_temp,
                                  r11_dst_klass, r10_src_klass);
       assert_clean_int(count, sco_temp);
 
       // Generate the type check.
-      int sco_offset = (klassOopDesc::header_size() * HeapWordSize +
-                        Klass::super_check_offset_offset_in_bytes());
+      const int sco_offset = (klassOopDesc::header_size() * HeapWordSize +
+                              Klass::super_check_offset_offset_in_bytes());
       __ movl(sco_temp, Address(r11_dst_klass, sco_offset));
       assert_clean_int(sco_temp, rax);
       generate_type_check(r10_src_klass, sco_temp, r11_dst_klass, L_plain_copy);
@@ -2709,12 +2704,14 @@
       int ek_offset = (klassOopDesc::header_size() * HeapWordSize +
                        objArrayKlass::element_klass_offset_in_bytes());
       __ movptr(r11_dst_klass, Address(r11_dst_klass, ek_offset));
-      __ movl(sco_temp,      Address(r11_dst_klass, sco_offset));
+      __ movl(  sco_temp,      Address(r11_dst_klass, sco_offset));
       assert_clean_int(sco_temp, rax);
 
       // the checkcast_copy loop needs two extra arguments:
       assert(c_rarg3 == sco_temp, "#3 already in place");
-      __ movptr(C_RARG4, r11_dst_klass);  // dst.klass.element_klass
+      // Set up arguments for checkcast_copy_entry.
+      setup_arg_regs(4);
+      __ movptr(r8, r11_dst_klass);  // dst.klass.element_klass, r8 is c_rarg4 on Linux/Solaris
       __ jump(RuntimeAddress(checkcast_copy_entry));
     }
 
@@ -2727,8 +2724,6 @@
     return start;
   }
 
-#undef length_arg
-
   void generate_arraycopy_stubs() {
     // Call the conjoint generation methods immediately after
     // the disjoint ones so that short branches from the former
--- a/src/cpu/x86/vm/x86_32.ad	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/cpu/x86/vm/x86_32.ad	Thu Dec 16 20:48:11 2010 -0800
@@ -507,6 +507,25 @@
 
 
 //=============================================================================
+const bool Matcher::constant_table_absolute_addressing = true;
+const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty;
+
+void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
+  // Empty encoding
+}
+
+uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const {
+  return 0;
+}
+
+#ifndef PRODUCT
+void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
+  st->print("# MachConstantBaseNode (empty encoding)");
+}
+#endif
+
+
+//=============================================================================
 #ifndef PRODUCT
 void MachPrologNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
   Compile* C = ra_->C;
@@ -1320,29 +1339,6 @@
 }
 
 
-static void emit_double_constant(CodeBuffer& cbuf, double x) {
-  int mark = cbuf.insts()->mark_off();
-  MacroAssembler _masm(&cbuf);
-  address double_address = __ double_constant(x);
-  cbuf.insts()->set_mark_off(mark);  // preserve mark across masm shift
-  emit_d32_reloc(cbuf,
-                 (int)double_address,
-                 internal_word_Relocation::spec(double_address),
-                 RELOC_DISP32);
-}
-
-static void emit_float_constant(CodeBuffer& cbuf, float x) {
-  int mark = cbuf.insts()->mark_off();
-  MacroAssembler _masm(&cbuf);
-  address float_address = __ float_constant(x);
-  cbuf.insts()->set_mark_off(mark);  // preserve mark across masm shift
-  emit_d32_reloc(cbuf,
-                 (int)float_address,
-                 internal_word_Relocation::spec(float_address),
-                 RELOC_DISP32);
-}
-
-
 const bool Matcher::match_rule_supported(int opcode) {
   if (!has_match_rule(opcode))
     return false;
@@ -1354,22 +1350,6 @@
   return regnum - 32; // The FP registers are in the second chunk
 }
 
-bool is_positive_zero_float(jfloat f) {
-  return jint_cast(f) == jint_cast(0.0F);
-}
-
-bool is_positive_one_float(jfloat f) {
-  return jint_cast(f) == jint_cast(1.0F);
-}
-
-bool is_positive_zero_double(jdouble d) {
-  return jlong_cast(d) == jlong_cast(0.0);
-}
-
-bool is_positive_one_double(jdouble d) {
-  return jlong_cast(d) == jlong_cast(1.0);
-}
-
 // This is UltraSparc specific, true just means we have fast l2f conversion
 const bool Matcher::convL2FSupported(void) {
   return true;
@@ -2036,67 +2016,6 @@
   %}
 
 
-  enc_class LdImmD (immD src) %{    // Load Immediate
-    if( is_positive_zero_double($src$$constant)) {
-      // FLDZ
-      emit_opcode(cbuf,0xD9);
-      emit_opcode(cbuf,0xEE);
-    } else if( is_positive_one_double($src$$constant)) {
-      // FLD1
-      emit_opcode(cbuf,0xD9);
-      emit_opcode(cbuf,0xE8);
-    } else {
-      emit_opcode(cbuf,0xDD);
-      emit_rm(cbuf, 0x0, 0x0, 0x5);
-      emit_double_constant(cbuf, $src$$constant);
-    }
-  %}
-
-
-  enc_class LdImmF (immF src) %{    // Load Immediate
-    if( is_positive_zero_float($src$$constant)) {
-      emit_opcode(cbuf,0xD9);
-      emit_opcode(cbuf,0xEE);
-    } else if( is_positive_one_float($src$$constant)) {
-      emit_opcode(cbuf,0xD9);
-      emit_opcode(cbuf,0xE8);
-    } else {
-      $$$emit8$primary;
-      // Load immediate does not have a zero or sign extended version
-      // for 8-bit immediates
-      // First load to TOS, then move to dst
-      emit_rm(cbuf, 0x0, 0x0, 0x5);
-      emit_float_constant(cbuf, $src$$constant);
-    }
-  %}
-
-  enc_class LdImmX (regX dst, immXF con) %{    // Load Immediate
-    emit_rm(cbuf, 0x0, $dst$$reg, 0x5);
-    emit_float_constant(cbuf, $con$$constant);
-  %}
-
-  enc_class LdImmXD (regXD dst, immXD con) %{    // Load Immediate
-    emit_rm(cbuf, 0x0, $dst$$reg, 0x5);
-    emit_double_constant(cbuf, $con$$constant);
-  %}
-
-  enc_class load_conXD (regXD dst, immXD con) %{ // Load double constant
-    // UseXmmLoadAndClearUpper ? movsd(dst, con) : movlpd(dst, con)
-    emit_opcode(cbuf, UseXmmLoadAndClearUpper ? 0xF2 : 0x66);
-    emit_opcode(cbuf, 0x0F);
-    emit_opcode(cbuf, UseXmmLoadAndClearUpper ? 0x10 : 0x12);
-    emit_rm(cbuf, 0x0, $dst$$reg, 0x5);
-    emit_double_constant(cbuf, $con$$constant);
-  %}
-
-  enc_class Opc_MemImm_F(immF src) %{
-    cbuf.set_insts_mark();
-    $$$emit8$primary;
-    emit_rm(cbuf, 0x0, $secondary, 0x5);
-    emit_float_constant(cbuf, $src$$constant);
-  %}
-
-
   enc_class MovI2X_reg(regX dst, eRegI src) %{
     emit_opcode(cbuf, 0x66 );     // MOVD dst,src
     emit_opcode(cbuf, 0x0F );
@@ -4801,7 +4720,7 @@
   interface(CONST_INTER);
 %}
 
-// Double Immediate
+// Double Immediate one
 operand immD1() %{
   predicate( UseSSE<=1 && n->getd() == 1.0 );
   match(ConD);
@@ -4844,7 +4763,17 @@
 
 // Float Immediate zero
 operand immF0() %{
-  predicate( UseSSE == 0 && n->getf() == 0.0 );
+  predicate(UseSSE == 0 && n->getf() == 0.0F);
+  match(ConF);
+
+  op_cost(5);
+  format %{ %}
+  interface(CONST_INTER);
+%}
+
+// Float Immediate one
+operand immF1() %{
+  predicate(UseSSE == 0 && n->getf() == 1.0F);
   match(ConF);
 
   op_cost(5);
@@ -7215,24 +7144,53 @@
 %}
 
 // The instruction usage is guarded by predicate in operand immF().
-instruct loadConF(regF dst, immF src) %{
-  match(Set dst src);
+instruct loadConF(regF dst, immF con) %{
+  match(Set dst con);
+  ins_cost(125);
+  format %{ "FLD_S  ST,[$constantaddress]\t# load from constant table: float=$con\n\t"
+            "FSTP   $dst" %}
+  ins_encode %{
+    __ fld_s($constantaddress($con));
+    __ fstp_d($dst$$reg);
+  %}
+  ins_pipe(fpu_reg_con);
+%}
+
+// The instruction usage is guarded by predicate in operand immF0().
+instruct loadConF0(regF dst, immF0 con) %{
+  match(Set dst con);
   ins_cost(125);
-
-  format %{ "FLD_S  ST,$src\n\t"
+  format %{ "FLDZ   ST\n\t"
             "FSTP   $dst" %}
-  opcode(0xD9, 0x00);       /* D9 /0 */
-  ins_encode(LdImmF(src), Pop_Reg_F(dst) );
-  ins_pipe( fpu_reg_con );
+  ins_encode %{
+    __ fldz();
+    __ fstp_d($dst$$reg);
+  %}
+  ins_pipe(fpu_reg_con);
+%}
+
+// The instruction usage is guarded by predicate in operand immF1().
+instruct loadConF1(regF dst, immF1 con) %{
+  match(Set dst con);
+  ins_cost(125);
+  format %{ "FLD1   ST\n\t"
+            "FSTP   $dst" %}
+  ins_encode %{
+    __ fld1();
+    __ fstp_d($dst$$reg);
+  %}
+  ins_pipe(fpu_reg_con);
 %}
 
 // The instruction usage is guarded by predicate in operand immXF().
 instruct loadConX(regX dst, immXF con) %{
   match(Set dst con);
   ins_cost(125);
-  format %{ "MOVSS  $dst,[$con]" %}
-  ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x10), LdImmX(dst, con));
-  ins_pipe( pipe_slow );
+  format %{ "MOVSS  $dst,[$constantaddress]\t# load from constant table: float=$con" %}
+  ins_encode %{
+    __ movflt($dst$$XMMRegister, $constantaddress($con));
+  %}
+  ins_pipe(pipe_slow);
 %}
 
 // The instruction usage is guarded by predicate in operand immXF0().
@@ -7240,28 +7198,63 @@
   match(Set dst src);
   ins_cost(100);
   format %{ "XORPS  $dst,$dst\t# float 0.0" %}
-  ins_encode( Opcode(0x0F), Opcode(0x57), RegReg(dst,dst));
-  ins_pipe( pipe_slow );
+  ins_encode %{
+    __ xorps($dst$$XMMRegister, $dst$$XMMRegister);
+  %}
+  ins_pipe(pipe_slow);
 %}
 
 // The instruction usage is guarded by predicate in operand immD().
-instruct loadConD(regD dst, immD src) %{
-  match(Set dst src);
+instruct loadConD(regD dst, immD con) %{
+  match(Set dst con);
+  ins_cost(125);
+
+  format %{ "FLD_D  ST,[$constantaddress]\t# load from constant table: double=$con\n\t"
+            "FSTP   $dst" %}
+  ins_encode %{
+    __ fld_d($constantaddress($con));
+    __ fstp_d($dst$$reg);
+  %}
+  ins_pipe(fpu_reg_con);
+%}
+
+// The instruction usage is guarded by predicate in operand immD0().
+instruct loadConD0(regD dst, immD0 con) %{
+  match(Set dst con);
   ins_cost(125);
 
-  format %{ "FLD_D  ST,$src\n\t"
+  format %{ "FLDZ   ST\n\t"
             "FSTP   $dst" %}
-  ins_encode(LdImmD(src), Pop_Reg_D(dst) );
-  ins_pipe( fpu_reg_con );
+  ins_encode %{
+    __ fldz();
+    __ fstp_d($dst$$reg);
+  %}
+  ins_pipe(fpu_reg_con);
+%}
+
+// The instruction usage is guarded by predicate in operand immD1().
+instruct loadConD1(regD dst, immD1 con) %{
+  match(Set dst con);
+  ins_cost(125);
+
+  format %{ "FLD1   ST\n\t"
+            "FSTP   $dst" %}
+  ins_encode %{
+    __ fld1();
+    __ fstp_d($dst$$reg);
+  %}
+  ins_pipe(fpu_reg_con);
 %}
 
 // The instruction usage is guarded by predicate in operand immXD().
 instruct loadConXD(regXD dst, immXD con) %{
   match(Set dst con);
   ins_cost(125);
-  format %{ "MOVSD  $dst,[$con]" %}
-  ins_encode(load_conXD(dst, con));
-  ins_pipe( pipe_slow );
+  format %{ "MOVSD  $dst,[$constantaddress]\t# load from constant table: double=$con" %}
+  ins_encode %{
+    __ movdbl($dst$$XMMRegister, $constantaddress($con));
+  %}
+  ins_pipe(pipe_slow);
 %}
 
 // The instruction usage is guarded by predicate in operand immXD0().
@@ -10303,41 +10296,45 @@
   ins_pipe( fpu_reg_mem );
 %}
 
-instruct addD_reg_imm1(regD dst, immD1 src) %{
+instruct addD_reg_imm1(regD dst, immD1 con) %{
   predicate(UseSSE<=1);
-  match(Set dst (AddD dst src));
+  match(Set dst (AddD dst con));
   ins_cost(125);
   format %{ "FLD1\n\t"
             "DADDp  $dst,ST" %}
-  opcode(0xDE, 0x00);
-  ins_encode( LdImmD(src),
-              OpcP, RegOpc(dst) );
-  ins_pipe( fpu_reg );
-%}
-
-instruct addD_reg_imm(regD dst, immD src) %{
+  ins_encode %{
+    __ fld1();
+    __ faddp($dst$$reg);
+  %}
+  ins_pipe(fpu_reg);
+%}
+
+instruct addD_reg_imm(regD dst, immD con) %{
   predicate(UseSSE<=1 && _kids[1]->_leaf->getd() != 0.0 && _kids[1]->_leaf->getd() != 1.0 );
-  match(Set dst (AddD dst src));
+  match(Set dst (AddD dst con));
   ins_cost(200);
-  format %{ "FLD_D  [$src]\n\t"
+  format %{ "FLD_D  [$constantaddress]\t# load from constant table: double=$con\n\t"
             "DADDp  $dst,ST" %}
-  opcode(0xDE, 0x00);       /* DE /0 */
-  ins_encode( LdImmD(src),
-              OpcP, RegOpc(dst));
-  ins_pipe( fpu_reg_mem );
+  ins_encode %{
+    __ fld_d($constantaddress($con));
+    __ faddp($dst$$reg);
+  %}
+  ins_pipe(fpu_reg_mem);
 %}
 
 instruct addD_reg_imm_round(stackSlotD dst, regD src, immD con) %{
   predicate(UseSSE<=1 && _kids[0]->_kids[1]->_leaf->getd() != 0.0 && _kids[0]->_kids[1]->_leaf->getd() != 1.0 );
   match(Set dst (RoundDouble (AddD src con)));
   ins_cost(200);
-  format %{ "FLD_D  [$con]\n\t"
+  format %{ "FLD_D  [$constantaddress]\t# load from constant table: double=$con\n\t"
             "DADD   ST,$src\n\t"
             "FSTP_D $dst\t# D-round" %}
-  opcode(0xD8, 0x00);       /* D8 /0 */
-  ins_encode( LdImmD(con),
-              OpcP, RegOpc(src), Pop_Mem_D(dst));
-  ins_pipe( fpu_mem_reg_con );
+  ins_encode %{
+    __ fld_d($constantaddress($con));
+    __ fadd($src$$reg);
+    __ fstp_d(Address(rsp, $dst$$disp));
+  %}
+  ins_pipe(fpu_mem_reg_con);
 %}
 
 // Add two double precision floating point values in xmm
@@ -10352,9 +10349,11 @@
 instruct addXD_imm(regXD dst, immXD con) %{
   predicate(UseSSE>=2);
   match(Set dst (AddD dst con));
-  format %{ "ADDSD  $dst,[$con]" %}
-  ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x58), LdImmXD(dst, con) );
-  ins_pipe( pipe_slow );
+  format %{ "ADDSD  $dst,[$constantaddress]\t# load from constant table: double=$con" %}
+  ins_encode %{
+    __ addsd($dst$$XMMRegister, $constantaddress($con));
+  %}
+  ins_pipe(pipe_slow);
 %}
 
 instruct addXD_mem(regXD dst, memory mem) %{
@@ -10377,9 +10376,11 @@
 instruct subXD_imm(regXD dst, immXD con) %{
   predicate(UseSSE>=2);
   match(Set dst (SubD dst con));
-  format %{ "SUBSD  $dst,[$con]" %}
-  ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x5C), LdImmXD(dst, con) );
-  ins_pipe( pipe_slow );
+  format %{ "SUBSD  $dst,[$constantaddress]\t# load from constant table: double=$con" %}
+  ins_encode %{
+    __ subsd($dst$$XMMRegister, $constantaddress($con));
+  %}
+  ins_pipe(pipe_slow);
 %}
 
 instruct subXD_mem(regXD dst, memory mem) %{
@@ -10402,9 +10403,11 @@
 instruct mulXD_imm(regXD dst, immXD con) %{
   predicate(UseSSE>=2);
   match(Set dst (MulD dst con));
-  format %{ "MULSD  $dst,[$con]" %}
-  ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x59), LdImmXD(dst, con) );
-  ins_pipe( pipe_slow );
+  format %{ "MULSD  $dst,[$constantaddress]\t# load from constant table: double=$con" %}
+  ins_encode %{
+    __ mulsd($dst$$XMMRegister, $constantaddress($con));
+  %}
+  ins_pipe(pipe_slow);
 %}
 
 instruct mulXD_mem(regXD dst, memory mem) %{
@@ -10428,9 +10431,11 @@
 instruct divXD_imm(regXD dst, immXD con) %{
   predicate(UseSSE>=2);
   match(Set dst (DivD dst con));
-  format %{ "DIVSD  $dst,[$con]" %}
-  ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x5E), LdImmXD(dst, con));
-  ins_pipe( pipe_slow );
+  format %{ "DIVSD  $dst,[$constantaddress]\t# load from constant table: double=$con" %}
+  ins_encode %{
+    __ divsd($dst$$XMMRegister, $constantaddress($con));
+  %}
+  ins_pipe(pipe_slow);
 %}
 
 instruct divXD_mem(regXD dst, memory mem) %{
@@ -10481,16 +10486,17 @@
   ins_pipe( fpu_reg_reg );
 %}
 
-instruct mulD_reg_imm(regD dst, immD src) %{
+instruct mulD_reg_imm(regD dst, immD con) %{
   predicate( UseSSE<=1 && _kids[1]->_leaf->getd() != 0.0 && _kids[1]->_leaf->getd() != 1.0 );
-  match(Set dst (MulD dst src));
+  match(Set dst (MulD dst con));
   ins_cost(200);
-  format %{ "FLD_D  [$src]\n\t"
+  format %{ "FLD_D  [$constantaddress]\t# load from constant table: double=$con\n\t"
             "DMULp  $dst,ST" %}
-  opcode(0xDE, 0x1); /* DE /1 */
-  ins_encode( LdImmD(src),
-              OpcP, RegOpc(dst) );
-  ins_pipe( fpu_reg_mem );
+  ins_encode %{
+    __ fld_d($constantaddress($con));
+    __ fmulp($dst$$reg);
+  %}
+  ins_pipe(fpu_reg_mem);
 %}
 
 
@@ -11224,9 +11230,11 @@
 instruct addX_imm(regX dst, immXF con) %{
   predicate(UseSSE>=1);
   match(Set dst (AddF dst con));
-  format %{ "ADDSS  $dst,[$con]" %}
-  ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x58), LdImmX(dst, con) );
-  ins_pipe( pipe_slow );
+  format %{ "ADDSS  $dst,[$constantaddress]\t# load from constant table: float=$con" %}
+  ins_encode %{
+    __ addss($dst$$XMMRegister, $constantaddress($con));
+  %}
+  ins_pipe(pipe_slow);
 %}
 
 instruct addX_mem(regX dst, memory mem) %{
@@ -11249,9 +11257,11 @@
 instruct subX_imm(regX dst, immXF con) %{
   predicate(UseSSE>=1);
   match(Set dst (SubF dst con));
-  format %{ "SUBSS  $dst,[$con]" %}
-  ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x5C), LdImmX(dst, con) );
-  ins_pipe( pipe_slow );
+  format %{ "SUBSS  $dst,[$constantaddress]\t# load from constant table: float=$con" %}
+  ins_encode %{
+    __ subss($dst$$XMMRegister, $constantaddress($con));
+  %}
+  ins_pipe(pipe_slow);
 %}
 
 instruct subX_mem(regX dst, memory mem) %{
@@ -11274,9 +11284,11 @@
 instruct mulX_imm(regX dst, immXF con) %{
   predicate(UseSSE>=1);
   match(Set dst (MulF dst con));
-  format %{ "MULSS  $dst,[$con]" %}
-  ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x59), LdImmX(dst, con) );
-  ins_pipe( pipe_slow );
+  format %{ "MULSS  $dst,[$constantaddress]\t# load from constant table: float=$con" %}
+  ins_encode %{
+    __ mulss($dst$$XMMRegister, $constantaddress($con));
+  %}
+  ins_pipe(pipe_slow);
 %}
 
 instruct mulX_mem(regX dst, memory mem) %{
@@ -11299,9 +11311,11 @@
 instruct divX_imm(regX dst, immXF con) %{
   predicate(UseSSE>=1);
   match(Set dst (DivF dst con));
-  format %{ "DIVSS  $dst,[$con]" %}
-  ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x5E), LdImmX(dst, con) );
-  ins_pipe( pipe_slow );
+  format %{ "DIVSS  $dst,[$constantaddress]\t# load from constant table: float=$con" %}
+  ins_encode %{
+    __ divss($dst$$XMMRegister, $constantaddress($con));
+  %}
+  ins_pipe(pipe_slow);
 %}
 
 instruct divX_mem(regX dst, memory mem) %{
@@ -11456,31 +11470,33 @@
 
 
 // Spill to obtain 24-bit precision
-instruct addF24_reg_imm(stackSlotF dst, regF src1, immF src2) %{
+instruct addF24_reg_imm(stackSlotF dst, regF src, immF con) %{
   predicate(UseSSE==0 && Compile::current()->select_24_bit_instr());
-  match(Set dst (AddF src1 src2));
-  format %{ "FLD    $src1\n\t"
-            "FADD   $src2\n\t"
+  match(Set dst (AddF src con));
+  format %{ "FLD    $src\n\t"
+            "FADD_S [$constantaddress]\t# load from constant table: float=$con\n\t"
             "FSTP_S $dst"  %}
-  opcode(0xD8, 0x00);       /* D8 /0 */
-  ins_encode( Push_Reg_F(src1),
-              Opc_MemImm_F(src2),
-              Pop_Mem_F(dst));
-  ins_pipe( fpu_mem_reg_con );
+  ins_encode %{
+    __ fld_s($src$$reg - 1);  // FLD ST(i-1)
+    __ fadd_s($constantaddress($con));
+    __ fstp_s(Address(rsp, $dst$$disp));
+  %}
+  ins_pipe(fpu_mem_reg_con);
 %}
 //
 // This instruction does not round to 24-bits
-instruct addF_reg_imm(regF dst, regF src1, immF src2) %{
+instruct addF_reg_imm(regF dst, regF src, immF con) %{
   predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr());
-  match(Set dst (AddF src1 src2));
-  format %{ "FLD    $src1\n\t"
-            "FADD   $src2\n\t"
-            "FSTP_S $dst"  %}
-  opcode(0xD8, 0x00);       /* D8 /0 */
-  ins_encode( Push_Reg_F(src1),
-              Opc_MemImm_F(src2),
-              Pop_Reg_F(dst));
-  ins_pipe( fpu_reg_reg_con );
+  match(Set dst (AddF src con));
+  format %{ "FLD    $src\n\t"
+            "FADD_S [$constantaddress]\t# load from constant table: float=$con\n\t"
+            "FSTP   $dst"  %}
+  ins_encode %{
+    __ fld_s($src$$reg - 1);  // FLD ST(i-1)
+    __ fadd_s($constantaddress($con));
+    __ fstp_d($dst$$reg);
+  %}
+  ins_pipe(fpu_reg_reg_con);
 %}
 
 // Spill to obtain 24-bit precision
@@ -11559,29 +11575,35 @@
 %}
 
 // Spill to obtain 24-bit precision
-instruct mulF24_reg_imm(stackSlotF dst, regF src1, immF src2) %{
+instruct mulF24_reg_imm(stackSlotF dst, regF src, immF con) %{
   predicate(UseSSE==0 && Compile::current()->select_24_bit_instr());
-  match(Set dst (MulF src1 src2));
-
-  format %{ "FMULc $dst,$src1,$src2" %}
-  opcode(0xD8, 0x1);  /* D8 /1*/
-  ins_encode( Push_Reg_F(src1),
-              Opc_MemImm_F(src2),
-              Pop_Mem_F(dst));
-  ins_pipe( fpu_mem_reg_con );
+  match(Set dst (MulF src con));
+
+  format %{ "FLD    $src\n\t"
+            "FMUL_S [$constantaddress]\t# load from constant table: float=$con\n\t"
+            "FSTP_S $dst"  %}
+  ins_encode %{
+    __ fld_s($src$$reg - 1);  // FLD ST(i-1)
+    __ fmul_s($constantaddress($con));
+    __ fstp_s(Address(rsp, $dst$$disp));
+  %}
+  ins_pipe(fpu_mem_reg_con);
 %}
 //
 // This instruction does not round to 24-bits
-instruct mulF_reg_imm(regF dst, regF src1, immF src2) %{
+instruct mulF_reg_imm(regF dst, regF src, immF con) %{
   predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr());
-  match(Set dst (MulF src1 src2));
-
-  format %{ "FMULc $dst. $src1, $src2" %}
-  opcode(0xD8, 0x1);  /* D8 /1*/
-  ins_encode( Push_Reg_F(src1),
-              Opc_MemImm_F(src2),
-              Pop_Reg_F(dst));
-  ins_pipe( fpu_reg_reg_con );
+  match(Set dst (MulF src con));
+
+  format %{ "FLD    $src\n\t"
+            "FMUL_S [$constantaddress]\t# load from constant table: float=$con\n\t"
+            "FSTP   $dst"  %}
+  ins_encode %{
+    __ fld_s($src$$reg - 1);  // FLD ST(i-1)
+    __ fmul_s($constantaddress($con));
+    __ fstp_d($dst$$reg);
+  %}
+  ins_pipe(fpu_reg_reg_con);
 %}
 
 
@@ -12939,16 +12961,11 @@
 instruct jumpXtnd(eRegI switch_val) %{
   match(Jump switch_val);
   ins_cost(350);
-
-  format %{  "JMP    [table_base](,$switch_val,1)\n\t" %}
-
-  ins_encode %{
-    address table_base  = __ address_table_constant(_index2label);
-
+  format %{  "JMP    [$constantaddress](,$switch_val,1)\n\t" %}
+  ins_encode %{
     // Jump to Address(table_base + switch_reg)
-    InternalAddress table(table_base);
     Address index(noreg, $switch_val$$Register, Address::times_1);
-    __ jump(ArrayAddress(table, index));
+    __ jump(ArrayAddress($constantaddress, index));
   %}
   ins_pc_relative(1);
   ins_pipe(pipe_jmp);
--- a/src/cpu/x86/vm/x86_64.ad	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/cpu/x86/vm/x86_64.ad	Thu Dec 16 20:48:11 2010 -0800
@@ -833,6 +833,25 @@
 
 
 //=============================================================================
+const bool Matcher::constant_table_absolute_addressing = true;
+const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty;
+
+void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
+  // Empty encoding
+}
+
+uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const {
+  return 0;
+}
+
+#ifndef PRODUCT
+void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
+  st->print("# MachConstantBaseNode (empty encoding)");
+}
+#endif
+
+
+//=============================================================================
 #ifndef PRODUCT
 void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const
 {
@@ -1922,28 +1941,6 @@
   return offset;
 }
 
-static void emit_double_constant(CodeBuffer& cbuf, double x) {
-  int mark = cbuf.insts()->mark_off();
-  MacroAssembler _masm(&cbuf);
-  address double_address = __ double_constant(x);
-  cbuf.insts()->set_mark_off(mark);  // preserve mark across masm shift
-  emit_d32_reloc(cbuf,
-                 (int) (double_address - cbuf.insts_end() - 4),
-                 internal_word_Relocation::spec(double_address),
-                 RELOC_DISP32);
-}
-
-static void emit_float_constant(CodeBuffer& cbuf, float x) {
-  int mark = cbuf.insts()->mark_off();
-  MacroAssembler _masm(&cbuf);
-  address float_address = __ float_constant(x);
-  cbuf.insts()->set_mark_off(mark);  // preserve mark across masm shift
-  emit_d32_reloc(cbuf,
-                 (int) (float_address - cbuf.insts_end() - 4),
-                 internal_word_Relocation::spec(float_address),
-                 RELOC_DISP32);
-}
-
 
 const bool Matcher::match_rule_supported(int opcode) {
   if (!has_match_rule(opcode))
@@ -2789,43 +2786,6 @@
     }
   %}
 
-  enc_class load_immF(regF dst, immF con)
-  %{
-    // XXX reg_mem doesn't support RIP-relative addressing yet
-    emit_rm(cbuf, 0x0, $dst$$reg & 7, 0x5); // 00 reg 101
-    emit_float_constant(cbuf, $con$$constant);
-  %}
-
-  enc_class load_immD(regD dst, immD con)
-  %{
-    // XXX reg_mem doesn't support RIP-relative addressing yet
-    emit_rm(cbuf, 0x0, $dst$$reg & 7, 0x5); // 00 reg 101
-    emit_double_constant(cbuf, $con$$constant);
-  %}
-
-  enc_class load_conF (regF dst, immF con) %{    // Load float constant
-    emit_opcode(cbuf, 0xF3);
-    if ($dst$$reg >= 8) {
-      emit_opcode(cbuf, Assembler::REX_R);
-    }
-    emit_opcode(cbuf, 0x0F);
-    emit_opcode(cbuf, 0x10);
-    emit_rm(cbuf, 0x0, $dst$$reg & 7, 0x5); // 00 reg 101
-    emit_float_constant(cbuf, $con$$constant);
-  %}
-
-  enc_class load_conD (regD dst, immD con) %{    // Load double constant
-    // UseXmmLoadAndClearUpper ? movsd(dst, con) : movlpd(dst, con)
-    emit_opcode(cbuf, UseXmmLoadAndClearUpper ? 0xF2 : 0x66);
-    if ($dst$$reg >= 8) {
-      emit_opcode(cbuf, Assembler::REX_R);
-    }
-    emit_opcode(cbuf, 0x0F);
-    emit_opcode(cbuf, UseXmmLoadAndClearUpper ? 0x10 : 0x12);
-    emit_rm(cbuf, 0x0, $dst$$reg & 7, 0x5); // 00 reg 101
-    emit_double_constant(cbuf, $con$$constant);
-  %}
-
   // Encode a reg-reg copy.  If it is useless, then empty encoding.
   enc_class enc_copy(rRegI dst, rRegI src)
   %{
@@ -2926,63 +2886,6 @@
     emit_d32(cbuf, 0x00);
   %}
 
-  enc_class jump_enc(rRegL switch_val, rRegI dest) %{
-    MacroAssembler masm(&cbuf);
-
-    Register switch_reg = as_Register($switch_val$$reg);
-    Register dest_reg   = as_Register($dest$$reg);
-    address table_base  = masm.address_table_constant(_index2label);
-
-    // We could use jump(ArrayAddress) except that the macro assembler needs to use r10
-    // to do that and the compiler is using that register as one it can allocate.
-    // So we build it all by hand.
-    // Address index(noreg, switch_reg, Address::times_1);
-    // ArrayAddress dispatch(table, index);
-
-    Address dispatch(dest_reg, switch_reg, Address::times_1);
-
-    masm.lea(dest_reg, InternalAddress(table_base));
-    masm.jmp(dispatch);
-  %}
-
-  enc_class jump_enc_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{
-    MacroAssembler masm(&cbuf);
-
-    Register switch_reg = as_Register($switch_val$$reg);
-    Register dest_reg   = as_Register($dest$$reg);
-    address table_base  = masm.address_table_constant(_index2label);
-
-    // We could use jump(ArrayAddress) except that the macro assembler needs to use r10
-    // to do that and the compiler is using that register as one it can allocate.
-    // So we build it all by hand.
-    // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant, (int)$offset$$constant);
-    // ArrayAddress dispatch(table, index);
-
-    Address dispatch(dest_reg, switch_reg, (Address::ScaleFactor)$shift$$constant, (int)$offset$$constant);
-
-    masm.lea(dest_reg, InternalAddress(table_base));
-    masm.jmp(dispatch);
-  %}
-
-  enc_class jump_enc_offset(rRegL switch_val, immI2 shift, rRegI dest) %{
-    MacroAssembler masm(&cbuf);
-
-    Register switch_reg = as_Register($switch_val$$reg);
-    Register dest_reg   = as_Register($dest$$reg);
-    address table_base  = masm.address_table_constant(_index2label);
-
-    // We could use jump(ArrayAddress) except that the macro assembler needs to use r10
-    // to do that and the compiler is using that register as one it can allocate.
-    // So we build it all by hand.
-    // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant);
-    // ArrayAddress dispatch(table, index);
-
-    Address dispatch(dest_reg, switch_reg, (Address::ScaleFactor)$shift$$constant);
-    masm.lea(dest_reg, InternalAddress(table_base));
-    masm.jmp(dispatch);
-
-  %}
-
   enc_class lock_prefix()
   %{
     if (os::is_MP()) {
@@ -6641,12 +6544,11 @@
   ins_pipe(ialu_reg);
 %}
 
-instruct loadConP(rRegP dst, immP src)
-%{
-  match(Set dst src);
-
-  format %{ "movq    $dst, $src\t# ptr" %}
-  ins_encode(load_immP(dst, src));
+instruct loadConP(rRegP dst, immP con) %{
+  match(Set dst con);
+
+  format %{ "movq    $dst, $con\t# ptr" %}
+  ins_encode(load_immP(dst, con));
   ins_pipe(ialu_reg_fat); // XXX
 %}
 
@@ -6673,13 +6575,13 @@
   ins_pipe(ialu_reg);
 %}
 
-instruct loadConF(regF dst, immF src)
-%{
-  match(Set dst src);
+instruct loadConF(regF dst, immF con) %{
+  match(Set dst con);
   ins_cost(125);
-
-  format %{ "movss   $dst, [$src]" %}
-  ins_encode(load_conF(dst, src));
+  format %{ "movss   $dst, [$constantaddress]\t# load from constant table: float=$con" %}
+  ins_encode %{
+    __ movflt($dst$$XMMRegister, $constantaddress($con));
+  %}
   ins_pipe(pipe_slow);
 %}
 
@@ -6721,13 +6623,13 @@
 %}
 
 // Use the same format since predicate() can not be used here.
-instruct loadConD(regD dst, immD src)
-%{
-  match(Set dst src);
+instruct loadConD(regD dst, immD con) %{
+  match(Set dst con);
   ins_cost(125);
-
-  format %{ "movsd   $dst, [$src]" %}
-  ins_encode(load_conD(dst, src));
+  format %{ "movsd   $dst, [$constantaddress]\t# load from constant table: double=$con" %}
+  ins_encode %{
+    __ movdbl($dst$$XMMRegister, $constantaddress($con));
+  %}
   ins_pipe(pipe_slow);
 %}
 
@@ -7694,9 +7596,18 @@
   predicate(false);
   effect(TEMP dest);
 
-  format %{ "leaq    $dest, table_base\n\t"
+  format %{ "leaq    $dest, [$constantaddress]\n\t"
             "jmp     [$dest + $switch_val << $shift]\n\t" %}
-  ins_encode(jump_enc_offset(switch_val, shift, dest));
+  ins_encode %{
+    // We could use jump(ArrayAddress) except that the macro assembler needs to use r10
+    // to do that and the compiler is using that register as one it can allocate.
+    // So we build it all by hand.
+    // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant);
+    // ArrayAddress dispatch(table, index);
+    Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant);
+    __ lea($dest$$Register, $constantaddress);
+    __ jmp(dispatch);
+  %}
   ins_pipe(pipe_jmp);
   ins_pc_relative(1);
 %}
@@ -7706,9 +7617,18 @@
   ins_cost(350);
   effect(TEMP dest);
 
-  format %{ "leaq    $dest, table_base\n\t"
+  format %{ "leaq    $dest, [$constantaddress]\n\t"
             "jmp     [$dest + $switch_val << $shift + $offset]\n\t" %}
-  ins_encode(jump_enc_addr(switch_val, shift, offset, dest));
+  ins_encode %{
+    // We could use jump(ArrayAddress) except that the macro assembler needs to use r10
+    // to do that and the compiler is using that register as one it can allocate.
+    // So we build it all by hand.
+    // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant);
+    // ArrayAddress dispatch(table, index);
+    Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant);
+    __ lea($dest$$Register, $constantaddress);
+    __ jmp(dispatch);
+  %}
   ins_pipe(pipe_jmp);
   ins_pc_relative(1);
 %}
@@ -7718,9 +7638,18 @@
   ins_cost(350);
   effect(TEMP dest);
 
-  format %{ "leaq    $dest, table_base\n\t"
+  format %{ "leaq    $dest, [$constantaddress]\n\t"
             "jmp     [$dest + $switch_val]\n\t" %}
-  ins_encode(jump_enc(switch_val, dest));
+  ins_encode %{
+    // We could use jump(ArrayAddress) except that the macro assembler needs to use r10
+    // to do that and the compiler is using that register as one it can allocate.
+    // So we build it all by hand.
+    // Address index(noreg, switch_reg, Address::times_1);
+    // ArrayAddress dispatch(table, index);
+    Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1);
+    __ lea($dest$$Register, $constantaddress);
+    __ jmp(dispatch);
+  %}
   ins_pipe(pipe_jmp);
   ins_pc_relative(1);
 %}
@@ -10376,30 +10305,36 @@
   ins_pipe(pipe_slow);
 %}
 
-instruct cmpF_cc_imm(rFlagsRegU cr, regF src1, immF src2)
-%{
-  match(Set cr (CmpF src1 src2));
+instruct cmpF_cc_imm(rFlagsRegU cr, regF src, immF con) %{
+  match(Set cr (CmpF src con));
 
   ins_cost(145);
-  format %{ "ucomiss $src1, $src2\n\t"
+  format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t"
             "jnp,s   exit\n\t"
             "pushfq\t# saw NaN, set CF\n\t"
             "andq    [rsp], #0xffffff2b\n\t"
             "popfq\n"
     "exit:   nop\t# avoid branch to branch" %}
-  opcode(0x0F, 0x2E);
-  ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, load_immF(src1, src2),
-             cmpfp_fixup);
-  ins_pipe(pipe_slow);
-%}
-
-instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src1, immF src2) %{
-  match(Set cr (CmpF src1 src2));
-
+  ins_encode %{
+    Label L_exit;
+    __ ucomiss($src$$XMMRegister, $constantaddress($con));
+    __ jcc(Assembler::noParity, L_exit);
+    __ pushf();
+    __ andq(rsp, 0xffffff2b);
+    __ popf();
+    __ bind(L_exit);
+    __ nop();
+  %}
+  ins_pipe(pipe_slow);
+%}
+
+instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{
+  match(Set cr (CmpF src con));
   ins_cost(100);
-  format %{ "ucomiss $src1, $src2" %}
-  opcode(0x0F, 0x2E);
-  ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, load_immF(src1, src2));
+  format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %}
+  ins_encode %{
+    __ ucomiss($src$$XMMRegister, $constantaddress($con));
+  %}
   ins_pipe(pipe_slow);
 %}
 
@@ -10458,30 +10393,36 @@
   ins_pipe(pipe_slow);
 %}
 
-instruct cmpD_cc_imm(rFlagsRegU cr, regD src1, immD src2)
-%{
-  match(Set cr (CmpD src1 src2));
+instruct cmpD_cc_imm(rFlagsRegU cr, regD src, immD con) %{
+  match(Set cr (CmpD src con));
 
   ins_cost(145);
-  format %{ "ucomisd $src1, [$src2]\n\t"
+  format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t"
             "jnp,s   exit\n\t"
             "pushfq\t# saw NaN, set CF\n\t"
             "andq    [rsp], #0xffffff2b\n\t"
             "popfq\n"
     "exit:   nop\t# avoid branch to branch" %}
-  opcode(0x66, 0x0F, 0x2E);
-  ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, load_immD(src1, src2),
-             cmpfp_fixup);
-  ins_pipe(pipe_slow);
-%}
-
-instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src1, immD src2) %{
-  match(Set cr (CmpD src1 src2));
-
+  ins_encode %{
+    Label L_exit;
+    __ ucomisd($src$$XMMRegister, $constantaddress($con));
+    __ jcc(Assembler::noParity, L_exit);
+    __ pushf();
+    __ andq(rsp, 0xffffff2b);
+    __ popf();
+    __ bind(L_exit);
+    __ nop();
+  %}
+  ins_pipe(pipe_slow);
+%}
+
+instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{
+  match(Set cr (CmpD src con));
   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));
+  format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %}
+  ins_encode %{
+    __ ucomisd($src$$XMMRegister, $constantaddress($con));
+  %}
   ins_pipe(pipe_slow);
 %}
 
@@ -10528,23 +10469,29 @@
 %}
 
 // Compare into -1,0,1
-instruct cmpF_imm(rRegI dst, regF src1, immF src2, rFlagsReg cr)
-%{
-  match(Set dst (CmpF3 src1 src2));
+instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{
+  match(Set dst (CmpF3 src con));
   effect(KILL cr);
 
   ins_cost(275);
-  format %{ "ucomiss $src1, [$src2]\n\t"
+  format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t"
             "movl    $dst, #-1\n\t"
             "jp,s    done\n\t"
             "jb,s    done\n\t"
             "setne   $dst\n\t"
             "movzbl  $dst, $dst\n"
     "done:" %}
-
-  opcode(0x0F, 0x2E);
-  ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, load_immF(src1, src2),
-             cmpfp3(dst));
+  ins_encode %{
+    Label L_done;
+    Register Rdst = $dst$$Register;
+    __ ucomiss($src$$XMMRegister, $constantaddress($con));
+    __ movl(Rdst, -1);
+    __ jcc(Assembler::parity, L_done);
+    __ jcc(Assembler::below, L_done);
+    __ setb(Assembler::notEqual, Rdst);
+    __ movzbl(Rdst, Rdst);
+    __ bind(L_done);
+  %}
   ins_pipe(pipe_slow);
 %}
 
@@ -10591,23 +10538,29 @@
 %}
 
 // Compare into -1,0,1
-instruct cmpD_imm(rRegI dst, regD src1, immD src2, rFlagsReg cr)
-%{
-  match(Set dst (CmpD3 src1 src2));
+instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{
+  match(Set dst (CmpD3 src con));
   effect(KILL cr);
 
   ins_cost(275);
-  format %{ "ucomisd $src1, [$src2]\n\t"
+  format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t"
             "movl    $dst, #-1\n\t"
             "jp,s    done\n\t"
             "jb,s    done\n\t"
             "setne   $dst\n\t"
             "movzbl  $dst, $dst\n"
     "done:" %}
-
-  opcode(0x66, 0x0F, 0x2E);
-  ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, load_immD(src1, src2),
-             cmpfp3(dst));
+  ins_encode %{
+    Register Rdst = $dst$$Register;
+    Label L_done;
+    __ ucomisd($src$$XMMRegister, $constantaddress($con));
+    __ movl(Rdst, -1);
+    __ jcc(Assembler::parity, L_done);
+    __ jcc(Assembler::below, L_done);
+    __ setb(Assembler::notEqual, Rdst);
+    __ movzbl(Rdst, Rdst);
+    __ bind(L_done);
+  %}
   ins_pipe(pipe_slow);
 %}
 
@@ -10633,14 +10586,13 @@
   ins_pipe(pipe_slow);
 %}
 
-instruct addF_imm(regF dst, immF src)
-%{
-  match(Set dst (AddF dst src));
-
-  format %{ "addss   $dst, [$src]" %}
+instruct addF_imm(regF dst, immF con) %{
+  match(Set dst (AddF dst con));
+  format %{ "addss   $dst, [$constantaddress]\t# load from constant table: float=$con" %}
   ins_cost(150); // XXX
-  opcode(0xF3, 0x0F, 0x58);
-  ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immF(dst, src));
+  ins_encode %{
+    __ addss($dst$$XMMRegister, $constantaddress($con));
+  %}
   ins_pipe(pipe_slow);
 %}
 
@@ -10666,14 +10618,13 @@
   ins_pipe(pipe_slow);
 %}
 
-instruct addD_imm(regD dst, immD src)
-%{
-  match(Set dst (AddD dst src));
-
-  format %{ "addsd   $dst, [$src]" %}
+instruct addD_imm(regD dst, immD con) %{
+  match(Set dst (AddD dst con));
+  format %{ "addsd   $dst, [$constantaddress]\t# load from constant table: double=$con" %}
   ins_cost(150); // XXX
-  opcode(0xF2, 0x0F, 0x58);
-  ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immD(dst, src));
+  ins_encode %{
+    __ addsd($dst$$XMMRegister, $constantaddress($con));
+  %}
   ins_pipe(pipe_slow);
 %}
 
@@ -10699,14 +10650,13 @@
   ins_pipe(pipe_slow);
 %}
 
-instruct subF_imm(regF dst, immF src)
-%{
-  match(Set dst (SubF dst src));
-
-  format %{ "subss   $dst, [$src]" %}
+instruct subF_imm(regF dst, immF con) %{
+  match(Set dst (SubF dst con));
+  format %{ "subss   $dst, [$constantaddress]\t# load from constant table: float=$con" %}
   ins_cost(150); // XXX
-  opcode(0xF3, 0x0F, 0x5C);
-  ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immF(dst, src));
+  ins_encode %{
+    __ subss($dst$$XMMRegister, $constantaddress($con));
+  %}
   ins_pipe(pipe_slow);
 %}
 
@@ -10732,14 +10682,13 @@
   ins_pipe(pipe_slow);
 %}
 
-instruct subD_imm(regD dst, immD src)
-%{
-  match(Set dst (SubD dst src));
-
-  format %{ "subsd   $dst, [$src]" %}
+instruct subD_imm(regD dst, immD con) %{
+  match(Set dst (SubD dst con));
+  format %{ "subsd   $dst, [$constantaddress]\t# load from constant table: double=$con" %}
   ins_cost(150); // XXX
-  opcode(0xF2, 0x0F, 0x5C);
-  ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immD(dst, src));
+  ins_encode %{
+    __ subsd($dst$$XMMRegister, $constantaddress($con));
+  %}
   ins_pipe(pipe_slow);
 %}
 
@@ -10765,14 +10714,13 @@
   ins_pipe(pipe_slow);
 %}
 
-instruct mulF_imm(regF dst, immF src)
-%{
-  match(Set dst (MulF dst src));
-
-  format %{ "mulss   $dst, [$src]" %}
+instruct mulF_imm(regF dst, immF con) %{
+  match(Set dst (MulF dst con));
+  format %{ "mulss   $dst, [$constantaddress]\t# load from constant table: float=$con" %}
   ins_cost(150); // XXX
-  opcode(0xF3, 0x0F, 0x59);
-  ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immF(dst, src));
+  ins_encode %{
+    __ mulss($dst$$XMMRegister, $constantaddress($con));
+  %}
   ins_pipe(pipe_slow);
 %}
 
@@ -10798,14 +10746,13 @@
   ins_pipe(pipe_slow);
 %}
 
-instruct mulD_imm(regD dst, immD src)
-%{
-  match(Set dst (MulD dst src));
-
-  format %{ "mulsd   $dst, [$src]" %}
+instruct mulD_imm(regD dst, immD con) %{
+  match(Set dst (MulD dst con));
+  format %{ "mulsd   $dst, [$constantaddress]\t# load from constant table: double=$con" %}
   ins_cost(150); // XXX
-  opcode(0xF2, 0x0F, 0x59);
-  ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immD(dst, src));
+  ins_encode %{
+    __ mulsd($dst$$XMMRegister, $constantaddress($con));
+  %}
   ins_pipe(pipe_slow);
 %}
 
@@ -10831,14 +10778,13 @@
   ins_pipe(pipe_slow);
 %}
 
-instruct divF_imm(regF dst, immF src)
-%{
-  match(Set dst (DivF dst src));
-
-  format %{ "divss   $dst, [$src]" %}
+instruct divF_imm(regF dst, immF con) %{
+  match(Set dst (DivF dst con));
+  format %{ "divss   $dst, [$constantaddress]\t# load from constant table: float=$con" %}
   ins_cost(150); // XXX
-  opcode(0xF3, 0x0F, 0x5E);
-  ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immF(dst, src));
+  ins_encode %{
+    __ divss($dst$$XMMRegister, $constantaddress($con));
+  %}
   ins_pipe(pipe_slow);
 %}
 
@@ -10864,14 +10810,13 @@
   ins_pipe(pipe_slow);
 %}
 
-instruct divD_imm(regD dst, immD src)
-%{
-  match(Set dst (DivD dst src));
-
-  format %{ "divsd   $dst, [$src]" %}
+instruct divD_imm(regD dst, immD con) %{
+  match(Set dst (DivD dst con));
+  format %{ "divsd   $dst, [$constantaddress]\t# load from constant table: double=$con" %}
   ins_cost(150); // XXX
-  opcode(0xF2, 0x0F, 0x5E);
-  ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immD(dst, src));
+  ins_encode %{
+    __ divsd($dst$$XMMRegister, $constantaddress($con));
+  %}
   ins_pipe(pipe_slow);
 %}
 
@@ -10897,14 +10842,13 @@
   ins_pipe(pipe_slow);
 %}
 
-instruct sqrtF_imm(regF dst, immF src)
-%{
-  match(Set dst (ConvD2F (SqrtD (ConvF2D src))));
-
-  format %{ "sqrtss  $dst, [$src]" %}
+instruct sqrtF_imm(regF dst, immF con) %{
+  match(Set dst (ConvD2F (SqrtD (ConvF2D con))));
+  format %{ "sqrtss  $dst, [$constantaddress]\t# load from constant table: float=$con" %}
   ins_cost(150); // XXX
-  opcode(0xF3, 0x0F, 0x51);
-  ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immF(dst, src));
+  ins_encode %{
+    __ sqrtss($dst$$XMMRegister, $constantaddress($con));
+  %}
   ins_pipe(pipe_slow);
 %}
 
@@ -10930,14 +10874,13 @@
   ins_pipe(pipe_slow);
 %}
 
-instruct sqrtD_imm(regD dst, immD src)
-%{
-  match(Set dst (SqrtD src));
-
-  format %{ "sqrtsd  $dst, [$src]" %}
+instruct sqrtD_imm(regD dst, immD con) %{
+  match(Set dst (SqrtD con));
+  format %{ "sqrtsd  $dst, [$constantaddress]\t# load from constant table: double=$con" %}
   ins_cost(150); // XXX
-  opcode(0xF2, 0x0F, 0x51);
-  ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immD(dst, src));
+  ins_encode %{
+    __ sqrtsd($dst$$XMMRegister, $constantaddress($con));
+  %}
   ins_pipe(pipe_slow);
 %}
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os/linux/vm/decoder_linux.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "prims/jvm.h"
+#include "utilities/decoder.hpp"
+
+#include <cxxabi.h>
+
+bool Decoder::demangle(const char* symbol, char *buf, int buflen) {
+  int   status;
+  char* result;
+  size_t size = (size_t)buflen;
+
+  // Don't pass buf to __cxa_demangle. In case of the 'buf' is too small,
+  // __cxa_demangle will call system "realloc" for additional memory, which
+  // may use different malloc/realloc mechanism that allocates 'buf'.
+  if ((result = abi::__cxa_demangle(symbol, NULL, NULL, &status)) != NULL) {
+    jio_snprintf(buf, buflen, "%s", result);
+      // call c library's free
+      ::free(result);
+      return true;
+  }
+  return false;
+}
--- a/src/os/linux/vm/os_linux.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/os/linux/vm/os_linux.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -59,6 +59,7 @@
 #include "services/attachListener.hpp"
 #include "services/runtimeService.hpp"
 #include "thread_linux.inline.hpp"
+#include "utilities/decoder.hpp"
 #include "utilities/defaultStream.hpp"
 #include "utilities/events.hpp"
 #include "utilities/growableArray.hpp"
@@ -114,6 +115,7 @@
 # include <link.h>
 # include <stdint.h>
 # include <inttypes.h>
+# include <sys/ioctl.h>
 
 #define MAX_PATH    (2 * K)
 
@@ -1688,14 +1690,23 @@
   Dl_info dlinfo;
 
   if (dladdr((void*)addr, &dlinfo) && dlinfo.dli_sname != NULL) {
-    if (buf) jio_snprintf(buf, buflen, "%s", dlinfo.dli_sname);
-    if (offset) *offset = addr - (address)dlinfo.dli_saddr;
+    if (buf != NULL) {
+      if(!Decoder::demangle(dlinfo.dli_sname, buf, buflen)) {
+        jio_snprintf(buf, buflen, "%s", dlinfo.dli_sname);
+      }
+    }
+    if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr;
     return true;
-  } else {
-    if (buf) buf[0] = '\0';
-    if (offset) *offset = -1;
-    return false;
+  } else if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != 0) {
+    if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase),
+       dlinfo.dli_fname, buf, buflen, offset) == Decoder::no_error) {
+       return true;
+    }
   }
+
+  if (buf != NULL) buf[0] = '\0';
+  if (offset != NULL) *offset = -1;
+  return false;
 }
 
 struct _address_to_library_name {
@@ -4423,6 +4434,15 @@
   return 1;
 }
 
+int os::socket_available(int fd, jint *pbytes) {
+  // Linux doc says EINTR not returned, unlike Solaris
+  int ret = ::ioctl(fd, FIONREAD, pbytes);
+
+  //%% note ioctl can return 0 when successful, JVM_SocketAvailable
+  // is expected to return 0 on failure and 1 on success to the jdk.
+  return (ret < 0) ? 0 : 1;
+}
+
 // Map a block of memory.
 char* os::map_memory(int fd, const char* file_name, size_t file_offset,
                      char *addr, size_t bytes, bool read_only,
--- a/src/os/linux/vm/os_linux.inline.hpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/os/linux/vm/os_linux.inline.hpp	Thu Dec 16 20:48:11 2010 -0800
@@ -45,7 +45,6 @@
 #include <unistd.h>
 #include <sys/socket.h>
 #include <sys/poll.h>
-#include <sys/ioctl.h>
 #include <netdb.h>
 
 inline void* os::thread_local_storage_at(int index) {
@@ -268,16 +267,6 @@
   RESTARTABLE_RETURN_INT(::sendto(fd, buf, len, (unsigned int) flags, to, tolen));
 }
 
-inline int os::socket_available(int fd, jint *pbytes) {
-  // Linux doc says EINTR not returned, unlike Solaris
-  int ret = ::ioctl(fd, FIONREAD, pbytes);
-
-  //%% note ioctl can return 0 when successful, JVM_SocketAvailable
-  // is expected to return 0 on failure and 1 on success to the jdk.
-  return (ret < 0) ? 0 : 1;
-}
-
-
 inline int os::socket_shutdown(int fd, int howto){
   return ::shutdown(fd, howto);
 }
--- a/src/os/linux/vm/vmError_linux.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/os/linux/vm/vmError_linux.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -44,11 +44,11 @@
     jio_snprintf(p, buflen - len,
                "\n\n"
                "Do you want to debug the problem?\n\n"
-               "To debug, run 'gdb /proc/%d/exe %d'; then switch to thread " INTX_FORMAT "\n"
+               "To debug, run 'gdb /proc/%d/exe %d'; then switch to thread " INTX_FORMAT " (" INTPTR_FORMAT ")\n"
                "Enter 'yes' to launch gdb automatically (PATH must include gdb)\n"
                "Otherwise, press RETURN to abort...",
                os::current_process_id(), os::current_process_id(),
-               os::current_thread_id());
+               os::current_thread_id(), os::current_thread_id());
 
     yes = os::message_box("Unexpected Error", buf);
 
--- a/src/os/posix/launcher/java_md.c	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/os/posix/launcher/java_md.c	Thu Dec 16 20:48:11 2010 -0800
@@ -28,6 +28,7 @@
 #include <dlfcn.h>
 #include <fcntl.h>
 #include <inttypes.h>
+#include <stdint.h>
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
@@ -812,13 +813,10 @@
 
 #ifdef GAMMA
     {
-       /* gamma launcher uses JAVA_HOME or ALT_JAVA_HOME environment variable to find JDK/JRE */
-       char* java_home_var = getenv("ALT_JAVA_HOME");
+       /* gamma launcher uses JAVA_HOME environment variable to find JDK/JRE */
+       char* java_home_var = getenv("JAVA_HOME");
        if (java_home_var == NULL) {
-          java_home_var = getenv("JAVA_HOME");
-       }
-       if (java_home_var == NULL) {
-          printf("JAVA_HOME or ALT_JAVA_HOME must point to a valid JDK/JRE to run gamma\n");
+          printf("JAVA_HOME must point to a valid JDK/JRE to run gamma\n");
           return JNI_FALSE;
        }
        snprintf(buf, bufsize, "%s", java_home_var);
@@ -1837,7 +1835,7 @@
     if (pthread_create(&tid, &attr, (void *(*)(void*))continuation, (void*)args) == 0) {
       void * tmp;
       pthread_join(tid, &tmp);
-      rslt = (int)tmp;
+      rslt = (int)(intptr_t)tmp;
     } else {
      /*
       * Continue execution in current thread if for some reason (e.g. out of
@@ -1855,7 +1853,7 @@
     if (thr_create(NULL, stack_size, (void *(*)(void *))continuation, args, flags, &tid) == 0) {
       void * tmp;
       thr_join(tid, NULL, &tmp);
-      rslt = (int)tmp;
+      rslt = (int)(intptr_t)tmp;
     } else {
       /* See above. Continue in current thread if thr_create() failed */
       rslt = continuation(args);
--- a/src/os/posix/launcher/launcher.script	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/os/posix/launcher/launcher.script	Thu Dec 16 20:48:11 2010 -0800
@@ -95,17 +95,21 @@
         ;;
 esac
 
+# Find out the absolute path to this script
+MYDIR=$(cd $(dirname $SCRIPT) && pwd)
+
+JDK=
 if [ "${ALT_JAVA_HOME}" = "" ]; then
-    if [ "${JAVA_HOME}" = "" ]; then
-	echo "Neither ALT_JAVA_HOME nor JAVA_HOME is set. Aborting.";
-	exit 1;
-    else
-	JDK=${JAVA_HOME%%/jre};
-    fi
+    source ${MYDIR}/jdkpath.sh
 else 
     JDK=${ALT_JAVA_HOME%%/jre};
 fi
 
+if [ "${JDK}" = "" ]; then
+    echo Failed to find JDK. ALT_JAVA_HOME is not set or ./jdkpath.sh is empty or not found.
+    exit 1
+fi
+
 # We will set the LD_LIBRARY_PATH as follows:
 #     o		$JVMPATH (directory portion only)
 #     o		$JRE/lib/$ARCH
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os/solaris/vm/decoder_solaris.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "utilities/decoder.hpp"
+
+#include <demangle.h>
+
+bool Decoder::demangle(const char* symbol, char *buf, int buflen) {
+  return !cplus_demangle(symbol, buf, (size_t)buflen);
+}
--- a/src/os/solaris/vm/os_solaris.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/os/solaris/vm/os_solaris.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -57,6 +57,7 @@
 #include "services/attachListener.hpp"
 #include "services/runtimeService.hpp"
 #include "thread_solaris.inline.hpp"
+#include "utilities/decoder.hpp"
 #include "utilities/defaultStream.hpp"
 #include "utilities/events.hpp"
 #include "utilities/growableArray.hpp"
@@ -1969,27 +1970,42 @@
       Sym * info;
       if (dladdr1_func((void *)addr, &dlinfo, (void **)&info,
                        RTLD_DL_SYMENT)) {
-          if (buf) jio_snprintf(buf, buflen, "%s", dlinfo.dli_sname);
-          if (offset) *offset = addr - (address)dlinfo.dli_saddr;
-
-          // check if the returned symbol really covers addr
-          return ((char *)dlinfo.dli_saddr + info->st_size > (char *)addr);
-      } else {
-          if (buf) buf[0] = '\0';
-          if (offset) *offset  = -1;
-          return false;
+        if ((char *)dlinfo.dli_saddr + info->st_size > (char *)addr) {
+          if (buf != NULL) {
+            if (!Decoder::demangle(dlinfo.dli_sname, buf, buflen))
+              jio_snprintf(buf, buflen, "%s", dlinfo.dli_sname);
+            }
+            if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr;
+            return true;
+        }
       }
+      if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != 0) {
+        if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase),
+          dlinfo.dli_fname, buf, buflen, offset) == Decoder::no_error) {
+          return true;
+        }
+      }
+      if (buf != NULL) buf[0] = '\0';
+      if (offset != NULL) *offset  = -1;
+      return false;
   } else {
       // no, only dladdr is available
-      if(dladdr((void *)addr, &dlinfo)) {
-          if (buf) jio_snprintf(buf, buflen, dlinfo.dli_sname);
-          if (offset) *offset = addr - (address)dlinfo.dli_saddr;
+      if (dladdr((void *)addr, &dlinfo)) {
+        if (buf != NULL) {
+          if (!Decoder::demangle(dlinfo.dli_sname, buf, buflen))
+            jio_snprintf(buf, buflen, dlinfo.dli_sname);
+        }
+        if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr;
+        return true;
+      } else if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != 0) {
+        if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase),
+          dlinfo.dli_fname, buf, buflen, offset) == Decoder::no_error) {
           return true;
-      } else {
-          if (buf) buf[0] = '\0';
-          if (offset) *offset  = -1;
-          return false;
+        }
       }
+      if (buf != NULL) buf[0] = '\0';
+      if (offset != NULL) *offset  = -1;
+      return false;
   }
 }
 
--- a/src/os/windows/launcher/java_md.c	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/os/windows/launcher/java_md.c	Thu Dec 16 20:48:11 2010 -0800
@@ -22,6 +22,7 @@
  *
  */
 
+#include <ctype.h>
 #include <windows.h>
 #include <io.h>
 #include <process.h>
@@ -486,16 +487,62 @@
 
 #else /* ifndef GAMMA */
 
-    /* gamma launcher uses JAVA_HOME or ALT_JAVA_HOME environment variable to find JDK/JRE */
-    char* java_home_var = getenv("ALT_JAVA_HOME");
-    if (java_home_var == NULL) {
-       java_home_var = getenv("JAVA_HOME");
+    char env[MAXPATHLEN + 1];
+
+    /* gamma launcher uses ALT_JAVA_HOME environment variable or jdkpath.txt file to find JDK/JRE */
+
+    if (getenv("ALT_JAVA_HOME") != NULL) {
+       snprintf(buf, bufsize, "%s", getenv("ALT_JAVA_HOME"));
     }
-    if (java_home_var == NULL) {
-       printf("JAVA_HOME or ALT_JAVA_HOME must point to a valid JDK/JRE to run gamma\n");
-       return JNI_FALSE;
+    else {
+       char path[MAXPATHLEN + 1];
+       char* p;
+       int len;
+       FILE* fp;
+
+       // find the path to the currect executable
+       len = GetModuleFileName(NULL, path, MAXPATHLEN + 1);
+       if (len == 0 || len > MAXPATHLEN) {
+          printf("Could not get directory of current executable.");
+          return JNI_FALSE;
+       }
+       // remove last path component ("hotspot.exe")
+       p = strrchr(path, '\\');
+       if (p == NULL) {
+          printf("Could not parse directory of current executable.\n");
+          return JNI_FALSE;
+       }
+       *p = '\0';
+
+       // open jdkpath.txt and read JAVA_HOME from it
+       if (strlen(path) + strlen("\\jdkpath.txt") + 1 >= MAXPATHLEN) {
+          printf("Path too long: %s\n", path);
+          return JNI_FALSE;
+       }
+       strcat(path, "\\jdkpath.txt");
+       fp = fopen(path, "r");
+       if (fp == NULL) {
+          printf("Could not open file %s to get path to JDK.\n", path);
+          return JNI_FALSE;
+       }
+
+       if (fgets(buf, bufsize, fp) == NULL) {
+          printf("Could not read from file %s to get path to JDK.\n", path);
+          fclose(fp);
+          return JNI_FALSE;
+       }
+       // trim the buffer
+       p = buf + strlen(buf) - 1;
+       while(isspace(*p)) {
+          *p = '\0';
+          p--;
+       }
+       fclose(fp);
     }
-    snprintf(buf, bufsize, "%s", java_home_var);
+
+    _snprintf(env, MAXPATHLEN, "JAVA_HOME=%s", buf);
+    _putenv(env);
+
     return JNI_TRUE;
 #endif /* ifndef GAMMA */
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os/windows/vm/decoder_windows.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "prims/jvm.h"
+#include "utilities/decoder.hpp"
+
+HMODULE                   Decoder::_dbghelp_handle = NULL;
+bool                      Decoder::_can_decode_in_vm = false;
+pfn_SymGetSymFromAddr64   Decoder::_pfnSymGetSymFromAddr64 = NULL;
+pfn_UndecorateSymbolName  Decoder::_pfnUndecorateSymbolName = NULL;
+
+void Decoder::initialize() {
+  if (!_initialized) {
+    _initialized = true;
+
+    HMODULE handle = ::LoadLibrary("dbghelp.dll");
+    if (!handle) {
+      _decoder_status = helper_not_found;
+        return;
+    }
+
+    _dbghelp_handle = handle;
+
+    pfn_SymSetOptions _pfnSymSetOptions = (pfn_SymSetOptions)::GetProcAddress(handle, "SymSetOptions");
+    pfn_SymInitialize _pfnSymInitialize = (pfn_SymInitialize)::GetProcAddress(handle, "SymInitialize");
+    _pfnSymGetSymFromAddr64 = (pfn_SymGetSymFromAddr64)::GetProcAddress(handle, "SymGetSymFromAddr64");
+    _pfnUndecorateSymbolName = (pfn_UndecorateSymbolName)GetProcAddress(handle, "UnDecorateSymbolName");
+
+    if (_pfnSymSetOptions == NULL || _pfnSymInitialize == NULL || _pfnSymGetSymFromAddr64 == NULL) {
+      _pfnSymGetSymFromAddr64 = NULL;
+      _pfnUndecorateSymbolName = NULL;
+      ::FreeLibrary(handle);
+      _dbghelp_handle = NULL;
+      _decoder_status = helper_func_error;
+      return;
+    }
+
+    _pfnSymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS);
+    if (!_pfnSymInitialize(GetCurrentProcess(), NULL, TRUE)) {
+      _pfnSymGetSymFromAddr64 = NULL;
+      _pfnUndecorateSymbolName = NULL;
+      ::FreeLibrary(handle);
+      _dbghelp_handle = NULL;
+      _decoder_status = helper_init_error;
+      return;
+    }
+
+     // find out if jvm.dll contains private symbols, by decoding
+     // current function and comparing the result
+     address addr = (address)Decoder::initialize;
+     char buf[MAX_PATH];
+     if (decode(addr, buf, sizeof(buf), NULL) == no_error) {
+       _can_decode_in_vm = !strcmp(buf, "Decoder::initialize");
+     }
+  }
+}
+
+void Decoder::uninitialize() {
+  assert(_initialized, "Decoder not yet initialized");
+  _pfnSymGetSymFromAddr64 = NULL;
+  _pfnUndecorateSymbolName = NULL;
+  if (_dbghelp_handle != NULL) {
+    ::FreeLibrary(_dbghelp_handle);
+  }
+  _initialized = false;
+}
+
+bool Decoder::can_decode_C_frame_in_vm() {
+  initialize();
+  return  _can_decode_in_vm;
+}
+
+
+Decoder::decoder_status Decoder::decode(address addr, char *buf, int buflen, int *offset) {
+  assert(_initialized, "Decoder not yet initialized");
+  if (_pfnSymGetSymFromAddr64 != NULL) {
+    PIMAGEHLP_SYMBOL64 pSymbol;
+    char symbolInfo[MAX_PATH + sizeof(IMAGEHLP_SYMBOL64)];
+    pSymbol = (PIMAGEHLP_SYMBOL64)symbolInfo;
+    pSymbol->MaxNameLength = MAX_PATH;
+    pSymbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64);
+    DWORD64 displacement;
+    if (_pfnSymGetSymFromAddr64(::GetCurrentProcess(), (DWORD64)addr, &displacement, pSymbol)) {
+      if (buf != NULL) {
+        if (!demangle(pSymbol->Name, buf, buflen)) {
+          jio_snprintf(buf, buflen, "%s", pSymbol->Name);
+        }
+      }
+      if (offset != NULL) *offset = (int)displacement;
+      return no_error;
+    }
+  }
+  return helper_not_found;
+}
+
+bool Decoder::demangle(const char* symbol, char *buf, int buflen) {
+  assert(_initialized, "Decoder not yet initialized");
+  return _pfnUndecorateSymbolName != NULL &&
+         _pfnUndecorateSymbolName(symbol, buf, buflen, UNDNAME_COMPLETE);
+}
+
--- a/src/os/windows/vm/os_windows.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/os/windows/vm/os_windows.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -62,6 +62,7 @@
 #include "services/attachListener.hpp"
 #include "services/runtimeService.hpp"
 #include "thread_windows.inline.hpp"
+#include "utilities/decoder.hpp"
 #include "utilities/defaultStream.hpp"
 #include "utilities/events.hpp"
 #include "utilities/growableArray.hpp"
@@ -1365,12 +1366,11 @@
 
 bool os::dll_address_to_function_name(address addr, char *buf,
                                       int buflen, int *offset) {
-  // Unimplemented on Windows - in order to use SymGetSymFromAddr(),
-  // we need to initialize imagehlp/dbghelp, then load symbol table
-  // for every module. That's too much work to do after a fatal error.
-  // For an example on how to implement this function, see 1.4.2.
-  if (offset)  *offset  = -1;
-  if (buf) buf[0] = '\0';
+  if (Decoder::decode(addr, buf, buflen, offset) == Decoder::no_error) {
+    return true;
+  }
+  if (offset != NULL)  *offset  = -1;
+  if (buf != NULL) buf[0] = '\0';
   return false;
 }
 
@@ -1711,14 +1711,11 @@
   buf[0] = '\0';
   if (strcmp(Arguments::sun_java_launcher(), "gamma") == 0) {
      // Support for the gamma launcher. Check for an
-     // ALT_JAVA_HOME or JAVA_HOME environment variable
+     // JAVA_HOME environment variable
      // and fix up the path so it looks like
      // libjvm.so is installed there (append a fake suffix
      // hotspot/libjvm.so).
-     char* java_home_var = ::getenv("ALT_JAVA_HOME");
-     if (java_home_var == NULL) {
-        java_home_var = ::getenv("JAVA_HOME");
-     }
+     char* java_home_var = ::getenv("JAVA_HOME");
      if (java_home_var != NULL && java_home_var[0] != 0) {
 
         strncpy(buf, java_home_var, buflen);
--- a/src/share/tools/ProjectCreator/BuildConfig.java	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/tools/ProjectCreator/BuildConfig.java	Thu Dec 16 20:48:11 2010 -0800
@@ -22,8 +22,11 @@
  *
  */
 
-import java.util.*;
 import java.io.File;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Vector;
 
 class BuildConfig {
     Hashtable vars;
@@ -57,7 +60,6 @@
 
         // ones mentioned above were needed to expand format
         String buildBase = expandFormat(getFieldString(null, "BuildBase"));
-        String jdkDir =  getFieldString(null, "JdkTargetRoot");
         String sourceBase = getFieldString(null, "SourceBase");
         String outDir = buildBase;
 
@@ -65,7 +67,7 @@
         put("OutputDir", outDir);
         put("SourceBase", sourceBase);
         put("BuildBase", buildBase);
-        put("OutputDll", jdkDir + Util.sep + outDll);
+        put("OutputDll", outDir + Util.sep + outDll);
 
         context = new String [] {flavourBuild, flavour, build, null};
     }
@@ -537,68 +539,75 @@
    }
 }
 
-class C1DebugConfig extends GenericDebugConfig {
+abstract class GenericDebugNonKernelConfig extends GenericDebugConfig {
+    protected void init(Vector includes, Vector defines) {
+        super.init(includes, defines);
+        getCI().getAdditionalNonKernelLinkerFlags(getV("LinkerFlags"));
+   }
+}
+
+class C1DebugConfig extends GenericDebugNonKernelConfig {
     String getOptFlag() {
         return getCI().getNoOptFlag();
     }
 
     C1DebugConfig() {
-        initNames("compiler1", "debug", "fastdebug\\jre\\bin\\client\\jvm.dll");
+        initNames("compiler1", "debug", "jvm.dll");
         init(getIncludes(), getDefines());
     }
 }
 
-class C1FastDebugConfig extends GenericDebugConfig {
+class C1FastDebugConfig extends GenericDebugNonKernelConfig {
     String getOptFlag() {
         return getCI().getOptFlag();
     }
 
     C1FastDebugConfig() {
-        initNames("compiler1", "fastdebug", "fastdebug\\jre\\bin\\client\\jvm.dll");
+        initNames("compiler1", "fastdebug", "jvm.dll");
         init(getIncludes(), getDefines());
     }
 }
 
-class C2DebugConfig extends GenericDebugConfig {
+class C2DebugConfig extends GenericDebugNonKernelConfig {
     String getOptFlag() {
         return getCI().getNoOptFlag();
     }
 
     C2DebugConfig() {
-        initNames("compiler2", "debug", "fastdebug\\jre\\bin\\server\\jvm.dll");
+        initNames("compiler2", "debug", "jvm.dll");
         init(getIncludes(), getDefines());
     }
 }
 
-class C2FastDebugConfig extends GenericDebugConfig {
+class C2FastDebugConfig extends GenericDebugNonKernelConfig {
     String getOptFlag() {
         return getCI().getOptFlag();
     }
 
     C2FastDebugConfig() {
-        initNames("compiler2", "fastdebug", "fastdebug\\jre\\bin\\server\\jvm.dll");
+        initNames("compiler2", "fastdebug", "jvm.dll");
         init(getIncludes(), getDefines());
     }
 }
 
-class TieredDebugConfig extends GenericDebugConfig {
+class TieredDebugConfig extends GenericDebugNonKernelConfig {
     String getOptFlag() {
         return getCI().getNoOptFlag();
     }
 
     TieredDebugConfig() {
-        initNames("tiered", "debug", "fastdebug\\jre\\bin\\server\\jvm.dll");
+        initNames("tiered", "debug", "jvm.dll");
         init(getIncludes(), getDefines());
     }
 }
 
-class TieredFastDebugConfig extends GenericDebugConfig {
+class TieredFastDebugConfig extends GenericDebugNonKernelConfig {
     String getOptFlag() {
         return getCI().getOptFlag();
     }
 
     TieredFastDebugConfig() {
-        initNames("tiered", "fastdebug", "fastdebug\\jre\\bin\\server\\jvm.dll");
+        initNames("tiered", "fastdebug", "jvm.dll");
         init(getIncludes(), getDefines());
     }
 }
@@ -618,45 +627,45 @@
 
 class C1ProductConfig extends ProductConfig {
     C1ProductConfig() {
-        initNames("compiler1", "product", "jre\\bin\\client\\jvm.dll");
+        initNames("compiler1", "product", "jvm.dll");
         init(getIncludes(), getDefines());
     }
 }
 
 class C2ProductConfig extends ProductConfig {
     C2ProductConfig() {
-        initNames("compiler2", "product", "jre\\bin\\server\\jvm.dll");
+        initNames("compiler2", "product", "jvm.dll");
         init(getIncludes(), getDefines());
     }
 }
 
 class TieredProductConfig extends ProductConfig {
     TieredProductConfig() {
-        initNames("tiered", "product", "jre\\bin\\server\\jvm.dll");
+        initNames("tiered", "product", "jvm.dll");
         init(getIncludes(), getDefines());
     }
 }
 
 
-class CoreDebugConfig extends GenericDebugConfig {
+class CoreDebugConfig extends GenericDebugNonKernelConfig {
     String getOptFlag() {
         return getCI().getNoOptFlag();
     }
 
     CoreDebugConfig() {
-        initNames("core", "debug", "fastdebug\\jre\\bin\\core\\jvm.dll");
+        initNames("core", "debug", "jvm.dll");
         init(getIncludes(), getDefines());
     }
 }
 
 
-class CoreFastDebugConfig extends GenericDebugConfig {
+class CoreFastDebugConfig extends GenericDebugNonKernelConfig {
     String getOptFlag() {
         return getCI().getOptFlag();
     }
 
     CoreFastDebugConfig() {
-        initNames("core", "fastdebug", "fastdebug\\jre\\bin\\core\\jvm.dll");
+        initNames("core", "fastdebug", "jvm.dll");
         init(getIncludes(), getDefines());
     }
 }
@@ -664,7 +673,7 @@
 
 class CoreProductConfig extends ProductConfig {
     CoreProductConfig() {
-        initNames("core", "product", "jre\\bin\\core\\jvm.dll");
+        initNames("core", "product", "jvm.dll");
         init(getIncludes(), getDefines());
     }
 }
@@ -675,7 +684,7 @@
     }
 
     KernelDebugConfig() {
-        initNames("kernel", "debug", "fastdebug\\jre\\bin\\kernel\\jvm.dll");
+        initNames("kernel", "debug", "jvm.dll");
         init(getIncludes(), getDefines());
     }
 }
@@ -687,7 +696,7 @@
     }
 
     KernelFastDebugConfig() {
-        initNames("kernel", "fastdebug", "fastdebug\\jre\\bin\\kernel\\jvm.dll");
+        initNames("kernel", "fastdebug", "jvm.dll");
         init(getIncludes(), getDefines());
     }
 }
@@ -695,7 +704,7 @@
 
 class KernelProductConfig extends ProductConfig {
     KernelProductConfig() {
-        initNames("kernel", "product", "jre\\bin\\kernel\\jvm.dll");
+        initNames("kernel", "product", "jvm.dll");
         init(getIncludes(), getDefines());
     }
 }
@@ -704,6 +713,7 @@
     abstract Vector getBaseLinkerFlags(String outDir, String outDll);
     abstract Vector getDebugCompilerFlags(String opt);
     abstract Vector getDebugLinkerFlags();
+    abstract void   getAdditionalNonKernelLinkerFlags(Vector rv);
     abstract Vector getProductCompilerFlags();
     abstract Vector getProductLinkerFlags();
     abstract String getOptFlag();
@@ -713,4 +723,14 @@
     void addAttr(Vector receiver, String attr, String value) {
         receiver.add(attr); receiver.add(value);
     }
+    void extAttr(Vector receiver, String attr, String value) {
+        int attr_pos=receiver.indexOf(attr) ;
+        if ( attr_pos == -1) {
+          // If attr IS NOT present in the Vector - add it
+          receiver.add(attr); receiver.add(value);
+        } else {
+          // If attr IS present in the Vector - append value to it
+          receiver.set(attr_pos+1,receiver.get(attr_pos+1)+value);
+        }
+    }
 }
--- a/src/share/tools/ProjectCreator/WinGammaPlatform.java	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/tools/ProjectCreator/WinGammaPlatform.java	Thu Dec 16 20:48:11 2010 -0800
@@ -22,8 +22,15 @@
  *
  */
 
-import java.io.*;
-import java.util.*;
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.TreeSet;
+import java.util.Vector;
 
 abstract class HsArgHandler extends ArgHandler {
     static final int STRING = 1;
@@ -345,11 +352,23 @@
         new ArgsParser(args,
                        new ArgRule[]
             {
-                new HsArgRule("-sourceBase",
-                              "SourceBase",
-                              "   (Did you set the HotSpotWorkSpace environment variable?)",
-                              HsArgHandler.STRING
-                              ),
+                new ArgRule("-sourceBase",
+                            new HsArgHandler() {
+                                public void handle(ArgIterator it) {
+                                   String cfg = getCfg(it.get());
+                                   if (nextNotKey(it)) {
+                                      String sb = (String) it.get();
+                                      if (sb.endsWith(Util.sep)) {
+                                         sb = sb.substring(0, sb.length() - 1);
+                                      }
+                                      BuildConfig.putField(cfg, "SourceBase", sb);
+                                      it.next();
+                                   } else {
+                                      empty("-sourceBase", null);
+                                   }
+                                }
+                            }
+                            ),
 
                 new HsArgRule("-buildBase",
                               "BuildBase",
@@ -512,7 +531,6 @@
                             new HsArgHandler() {
                                 public void handle(ArgIterator it) {
                                     if (nextNotKey(it)) {
-                                        String build = it.get();
                                         if (nextNotKey(it)) {
                                             String description = it.get();
                                             if (nextNotKey(it)) {
@@ -528,7 +546,28 @@
                                     empty(null,  "** Error: wrong number of args to -prelink");
                                 }
                             }
-                            )
+                            ),
+
+                new ArgRule("-postbuild",
+                            new HsArgHandler() {
+                                public void handle(ArgIterator it) {
+                                    if (nextNotKey(it)) {
+                                        if (nextNotKey(it)) {
+                                            String description = it.get();
+                                            if (nextNotKey(it)) {
+                                                String command = it.get();
+                                                BuildConfig.putField(null, "PostbuildDescription", description);
+                                                BuildConfig.putField(null, "PostbuildCommand", command);
+                                                it.next();
+                                                return;
+                                            }
+                                        }
+                                    }
+
+                                    empty(null,  "** Error: wrong number of args to -postbuild");
+                                }
+                            }
+                            ),
             },
                                        new ArgHandler() {
                                            public void handle(ArgIterator it) {
@@ -618,10 +657,6 @@
 
         public int compareTo(Object o) {
             FileInfo oo = (FileInfo)o;
-            // Don't squelch identical short file names where the full
-            // paths are different
-            if (!attr.shortName.equals(oo.attr.shortName))
-              return attr.shortName.compareTo(oo.attr.shortName);
             return full.compareTo(oo.full);
         }
 
--- a/src/share/tools/ProjectCreator/WinGammaPlatformVC6.java	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/tools/ProjectCreator/WinGammaPlatformVC6.java	Thu Dec 16 20:48:11 2010 -0800
@@ -260,6 +260,8 @@
         return rv;
     }
 
+    void getAdditionalNonKernelLinkerFlags(Vector rv) {}
+
     Vector getProductCompilerFlags() {
         Vector rv = new Vector();
 
--- a/src/share/tools/ProjectCreator/WinGammaPlatformVC7.java	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/tools/ProjectCreator/WinGammaPlatformVC7.java	Thu Dec 16 20:48:11 2010 -0800
@@ -22,8 +22,13 @@
  *
  */
 
-import java.io.*;
-import java.util.*;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.TreeSet;
+import java.util.Vector;
 
 public class WinGammaPlatformVC7 extends WinGammaPlatform {
 
@@ -104,7 +109,9 @@
 
 
         boolean match(FileInfo fi) {
-            return fi.full.regionMatches(true, baseLen, dir, 0, dirLen);
+           int lastSlashIndex = fi.full.lastIndexOf('/');
+           String fullDir = fi.full.substring(0, lastSlashIndex);
+           return fullDir.endsWith(dir);
         }
     }
 
@@ -217,65 +224,41 @@
     //   - container filter just provides a container to group together real filters
     //   - real filter can select elements from the set according to some rule, put it into XML
     //     and remove from the list
-    Vector makeFilters(TreeSet files) {
+    Vector makeFilters(TreeSet<FileInfo> files) {
         Vector rv = new Vector();
         String sbase = Util.normalize(BuildConfig.getFieldString(null, "SourceBase")+"/src/");
 
-        ContainerFilter rt = new ContainerFilter("Runtime");
-        rt.add(new DirectoryFilter("share/vm/prims", sbase));
-        rt.add(new DirectoryFilter("share/vm/runtime", sbase));
-        rt.add(new DirectoryFilter("share/vm/oops", sbase));
-        rv.add(rt);
-
-        ContainerFilter gc = new ContainerFilter("GC");
-        gc.add(new DirectoryFilter("share/vm/memory", sbase));
-        gc.add(new DirectoryFilter("share/vm/gc_interface", sbase));
+        String currentDir = "";
+        DirectoryFilter container = null;
+        for(FileInfo fileInfo : files) {
 
-        ContainerFilter gc_impl = new ContainerFilter("Implementations");
-        gc_impl.add(new DirectoryFilter("CMS",
-                                        "share/vm/gc_implementation/concurrentMarkSweep",
-                                        sbase));
-        gc_impl.add(new DirectoryFilter("Parallel Scavenge",
-                                        "share/vm/gc_implementation/parallelScavenge",
-                                        sbase));
-        gc_impl.add(new DirectoryFilter("Shared",
-                                        "share/vm/gc_implementation/shared",
-                                        sbase));
-        // for all leftovers
-        gc_impl.add(new DirectoryFilter("Misc",
-                                        "share/vm/gc_implementation",
-                                        sbase));
-
-        gc.add(gc_impl);
-        rv.add(gc);
+           if (!fileInfo.full.startsWith(sbase)) {
+              continue;
+           }
 
-        rv.add(new DirectoryFilter("C1", "share/vm/c1", sbase));
-
-        rv.add(new DirectoryFilter("C2", "share/vm/opto", sbase));
-
-        ContainerFilter comp = new ContainerFilter("Compiler Common");
-        comp.add(new DirectoryFilter("share/vm/asm", sbase));
-        comp.add(new DirectoryFilter("share/vm/ci", sbase));
-        comp.add(new DirectoryFilter("share/vm/code", sbase));
-        comp.add(new DirectoryFilter("share/vm/compiler", sbase));
-        rv.add(comp);
+           int lastSlash = fileInfo.full.lastIndexOf('/');
+           String dir = fileInfo.full.substring(sbase.length(), lastSlash);
+           if(dir.equals("share/vm")) {
+              // skip files directly in share/vm - should only be precompiled.hpp which is handled below
+              continue;
+           }
+           if (!dir.equals(currentDir)) {
+              currentDir = dir;
+              if (container != null) {
+                 rv.add(container);
+              }
 
-        rv.add(new DirectoryFilter("Interpreter",
-                                   "share/vm/interpreter",
-                                   sbase));
-
-        ContainerFilter misc = new ContainerFilter("Misc");
-        misc.add(new DirectoryFilter("share/vm/libadt", sbase));
-        misc.add(new DirectoryFilter("share/vm/services", sbase));
-        misc.add(new DirectoryFilter("share/vm/utilities", sbase));
-        misc.add(new DirectoryFilter("share/vm/classfile", sbase));
-        rv.add(misc);
-
-        rv.add(new DirectoryFilter("os_cpu", sbase));
-
-        rv.add(new DirectoryFilter("cpu", sbase));
-
-        rv.add(new DirectoryFilter("os", sbase));
+              // remove "share/vm/" from names
+              String name = dir;
+              if (dir.startsWith("share/vm/")) {
+                 name = dir.substring("share/vm/".length(), dir.length());
+              }
+              container = new DirectoryFilter(name, dir, sbase);
+           }
+        }
+        if (container != null) {
+           rv.add(container);
+        }
 
         ContainerFilter generated = new ContainerFilter("Generated");
         ContainerFilter c1Generated = new ContainerFilter("C1");
@@ -397,7 +380,6 @@
                                          "Name", cfg,
                                          "ExcludedFromBuild", "TRUE"
                                      });
-                            tag("Tool", new String[] {"Name", "VCCLCompilerTool"});
                             endTag("FileConfiguration");
 
                         }
@@ -441,7 +423,11 @@
 
         tag("Tool",
             new String[] {
-                "Name", "VCPostBuildEventTool"
+               "Name", "VCPostBuildEventTool",
+                "Description", BuildConfig.getFieldString(null, "PostbuildDescription"),
+                //Caution: String.replace(String,String) is available from JDK5 onwards only
+                "CommandLine", cfg.expandFormat(BuildConfig.getFieldString(null, "PostbuildCommand").replace
+                   ("\t", "&#x0D;&#x0A;"))
             }
             );
 
@@ -469,33 +455,6 @@
                 "Culture", "1033"
             }
             );
-        tag("Tool",
-            new String[] {
-              "Name", "VCWebServiceProxyGeneratorTool"
-            }
-            );
-
-        tag ("Tool",
-             new String[] {
-              "Name", "VCXMLDataGeneratorTool"
-             }
-             );
-
-        tag("Tool",
-            new String[] {
-              "Name", "VCWebDeploymentTool"
-            }
-            );
-        tag("Tool",
-             new String[] {
-            "Name", "VCManagedWrapperGeneratorTool"
-             }
-            );
-        tag("Tool",
-            new String[] {
-              "Name", "VCAuxiliaryManagedWrapperGeneratorTool"
-            }
-            );
 
         tag("Tool",
             new String[] {
@@ -597,7 +556,7 @@
         addAttr(rv, "PrecompiledHeaderFile", outDir+Util.sep+"vm.pch");
         addAttr(rv, "AssemblerListingLocation", outDir);
         addAttr(rv, "ObjectFile", outDir+Util.sep);
-        addAttr(rv, "ProgramDataBaseFileName", outDir+Util.sep+"vm.pdb");
+        addAttr(rv, "ProgramDataBaseFileName", outDir+Util.sep+"jvm.pdb");
         // Set /nologo optin
         addAttr(rv, "SuppressStartupBanner", "TRUE");
         // Surpass the default /Tc or /Tp. 0 is compileAsDefault
@@ -631,17 +590,22 @@
         addAttr(rv, "AdditionalOptions",
                 "/export:JNI_GetDefaultJavaVMInitArgs " +
                 "/export:JNI_CreateJavaVM " +
+                "/export:JVM_FindClassFromBootLoader "+
                 "/export:JNI_GetCreatedJavaVMs "+
                 "/export:jio_snprintf /export:jio_printf "+
                 "/export:jio_fprintf /export:jio_vfprintf "+
-                "/export:jio_vsnprintf ");
+                "/export:jio_vsnprintf "+
+                "/export:JVM_GetVersionInfo "+
+                "/export:JVM_GetThreadStateNames "+
+                "/export:JVM_GetThreadStateValues "+
+                "/export:JVM_InitAgentProperties ");
         addAttr(rv, "AdditionalDependencies", "Wsock32.lib winmm.lib");
         addAttr(rv, "OutputFile", outDll);
         // Set /INCREMENTAL option. 1 is linkIncrementalNo
         addAttr(rv, "LinkIncremental", "1");
         addAttr(rv, "SuppressStartupBanner", "TRUE");
         addAttr(rv, "ModuleDefinitionFile", outDir+Util.sep+"vm.def");
-        addAttr(rv, "ProgramDatabaseFile", outDir+Util.sep+"vm.pdb");
+        addAttr(rv, "ProgramDatabaseFile", outDir+Util.sep+"jvm.pdb");
         // Set /SUBSYSTEM option. 2 is subSystemWindows
         addAttr(rv, "SubSystem", "2");
         addAttr(rv, "BaseAddress", "0x8000000");
@@ -682,6 +646,11 @@
         return rv;
     }
 
+    void getAdditionalNonKernelLinkerFlags(Vector rv) {
+        extAttr(rv, "AdditionalOptions",
+                "/export:AsyncGetCallTrace ");
+    }
+
     void getProductCompilerFlags_common(Vector rv) {
         // Set /O2 option. 2 is optimizeMaxSpeed
         addAttr(rv, "Optimization", "2");
--- a/src/share/tools/ProjectCreator/WinGammaPlatformVC8.java	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/tools/ProjectCreator/WinGammaPlatformVC8.java	Thu Dec 16 20:48:11 2010 -0800
@@ -22,7 +22,7 @@
  *
  */
 
-import java.util.*;
+import java.util.Vector;
 
 public class WinGammaPlatformVC8 extends WinGammaPlatformVC7 {
 
@@ -41,6 +41,9 @@
         // Set /EHsc- option. 0 is cppExceptionHandlingNo
         addAttr(rv, "ExceptionHandling", "0");
 
+        // enable multi process builds
+        extAttr(rv, "AdditionalOptions", "/MP");
+
         return rv;
     }
 
--- a/src/share/tools/launcher/java.c	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/tools/launcher/java.c	Thu Dec 16 20:48:11 2010 -0800
@@ -275,6 +275,8 @@
                                jvmpath, sizeof(jvmpath),
                                original_argv);
 
+    printf("Using java runtime at: %s\n", jrepath);
+
     ifn.CreateJavaVM = 0;
     ifn.GetDefaultJavaVMInitArgs = 0;
 
--- a/src/share/tools/launcher/jli_util.c	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/tools/launcher/jli_util.c	Thu Dec 16 20:48:11 2010 -0800
@@ -1,3 +1,4 @@
+
 /*
  * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -27,7 +28,7 @@
 #include "jli_util.h"
 
 #ifdef GAMMA
-#ifdef _WINDOWS
+#ifdef TARGET_OS_FAMILY_windows
 #define strdup _strdup
 #endif
 #endif
--- a/src/share/vm/adlc/adlparse.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/adlc/adlparse.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -95,7 +95,7 @@
     if (ident == NULL) {         // Empty line
       continue;                  // Get the next line
     }
-    if (!strcmp(ident, "instruct"))        instr_parse();
+         if (!strcmp(ident, "instruct"))   instr_parse();
     else if (!strcmp(ident, "operand"))    oper_parse();
     else if (!strcmp(ident, "opclass"))    opclass_parse();
     else if (!strcmp(ident, "ins_attrib")) ins_attr_parse();
@@ -216,24 +216,23 @@
     else if (!strcmp(ident, "encode"))  {
       parse_err(SYNERR, "Instructions specify ins_encode, not encode\n");
     }
-    else if (!strcmp(ident, "ins_encode"))
-      instr->_insencode = ins_encode_parse(*instr);
-    else if (!strcmp(ident, "opcode"))  instr->_opcode = opcode_parse(instr);
-    else if (!strcmp(ident, "size"))    instr->_size = size_parse(instr);
-    else if (!strcmp(ident, "effect"))  effect_parse(instr);
-    else if (!strcmp(ident, "expand"))  instr->_exprule = expand_parse(instr);
-    else if (!strcmp(ident, "rewrite")) instr->_rewrule = rewrite_parse();
+    else if (!strcmp(ident, "ins_encode"))     ins_encode_parse(*instr);
+    else if (!strcmp(ident, "opcode"))         instr->_opcode    = opcode_parse(instr);
+    else if (!strcmp(ident, "size"))           instr->_size      = size_parse(instr);
+    else if (!strcmp(ident, "effect"))         effect_parse(instr);
+    else if (!strcmp(ident, "expand"))         instr->_exprule   = expand_parse(instr);
+    else if (!strcmp(ident, "rewrite"))        instr->_rewrule   = rewrite_parse();
     else if (!strcmp(ident, "constraint")) {
       parse_err(SYNERR, "Instructions do not specify a constraint\n");
     }
     else if (!strcmp(ident, "construct")) {
       parse_err(SYNERR, "Instructions do not specify a construct\n");
     }
-    else if (!strcmp(ident, "format"))  instr->_format  = format_parse();
+    else if (!strcmp(ident, "format"))         instr->_format    = format_parse();
     else if (!strcmp(ident, "interface")) {
       parse_err(SYNERR, "Instructions do not specify an interface\n");
     }
-    else if (!strcmp(ident, "ins_pipe")) ins_pipe_parse(*instr);
+    else if (!strcmp(ident, "ins_pipe"))        ins_pipe_parse(*instr);
     else {  // Done with staticly defined parts of instruction definition
       // Check identifier to see if it is the name of an attribute
       const Form    *form = _globalNames[ident];
@@ -323,7 +322,8 @@
       const char *optype2  = NULL;
       // Can not have additional base operands in right side of match!
       if ( ! right->base_operand( position, _globalNames, result2, name2, optype2) ) {
-        assert( instr->_predicate == NULL, "ADLC does not support instruction chain rules with predicates");
+        if (instr->_predicate != NULL)
+          parse_err(SYNERR, "ADLC does not support instruction chain rules with predicates");
         // Chain from input  _ideal_operand_type_,
         // Needed for shared roots of match-trees
         ChainList *lst = (ChainList *)_AD._chainRules[optype];
@@ -935,9 +935,9 @@
     // (2)
     // If we are at a replacement variable,
     // copy it and record in EncClass
-    if ( _curchar == '$' ) {
+    if (_curchar == '$') {
       // Found replacement Variable
-      char *rep_var = get_rep_var_ident_dup();
+      char* rep_var = get_rep_var_ident_dup();
       // Add flag to _strings list indicating we should check _rep_vars
       encoding->add_rep_var(rep_var);
     }
@@ -2774,47 +2774,122 @@
 
 //------------------------------ins_encode_parse_block-------------------------
 // Parse the block form of ins_encode.  See ins_encode_parse for more details
-InsEncode *ADLParser::ins_encode_parse_block(InstructForm &inst) {
+void ADLParser::ins_encode_parse_block(InstructForm& inst) {
   // Create a new encoding name based on the name of the instruction
   // definition, which should be unique.
-  const char * prefix = "__enc_";
-  char* ec_name = (char*)malloc(strlen(inst._ident) + strlen(prefix) + 1);
+  const char* prefix = "__ins_encode_";
+  char* ec_name = (char*) malloc(strlen(inst._ident) + strlen(prefix) + 1);
   sprintf(ec_name, "%s%s", prefix, inst._ident);
 
   assert(_AD._encode->encClass(ec_name) == NULL, "shouldn't already exist");
-  EncClass  *encoding = _AD._encode->add_EncClass(ec_name);
+  EncClass* encoding = _AD._encode->add_EncClass(ec_name);
   encoding->_linenum = linenum();
 
   // synthesize the arguments list for the enc_class from the
   // arguments to the instruct definition.
-  const char * param = NULL;
+  const char* param = NULL;
   inst._parameters.reset();
   while ((param = inst._parameters.iter()) != NULL) {
-    OperandForm *opForm = (OperandForm*)inst._localNames[param];
+    OperandForm* opForm = (OperandForm*) inst._localNames[param];
     encoding->add_parameter(opForm->_ident, param);
   }
 
-  // Add the prologue to create the MacroAssembler
-  encoding->add_code("\n"
-  "    // Define a MacroAssembler instance for use by the encoding.  The\n"
-  "    // name is chosen to match the __ idiom used for assembly in other\n"
-  "    // parts of hotspot and assumes the existence of the standard\n"
-  "    // #define __ _masm.\n"
-  "    MacroAssembler _masm(&cbuf);\n");
+  // Define a MacroAssembler instance for use by the encoding.  The
+  // name is chosen to match the __ idiom used for assembly in other
+  // parts of hotspot and assumes the existence of the standard
+  // #define __ _masm.
+  encoding->add_code("    MacroAssembler _masm(&cbuf);\n");
 
   // Parse the following %{ }% block
-  enc_class_parse_block(encoding, ec_name);
+  ins_encode_parse_block_impl(inst, encoding, ec_name);
 
   // Build an encoding rule which invokes the encoding rule we just
   // created, passing all arguments that we received.
-  InsEncode *encrule  = new InsEncode(); // Encode class for instruction
-  NameAndList *params = encrule->add_encode(ec_name);
+  InsEncode*   encrule = new InsEncode(); // Encode class for instruction
+  NameAndList* params  = encrule->add_encode(ec_name);
   inst._parameters.reset();
   while ((param = inst._parameters.iter()) != NULL) {
     params->add_entry(param);
   }
 
-  return encrule;
+  // Set encode class of this instruction.
+  inst._insencode = encrule;
+}
+
+
+void ADLParser::ins_encode_parse_block_impl(InstructForm& inst, EncClass* encoding, char* ec_name) {
+  skipws_no_preproc();              // Skip leading whitespace
+  // Prepend location descriptor, for debugging; cf. ADLParser::find_cpp_block
+  if (_AD._adlocation_debug) {
+    encoding->add_code(get_line_string());
+  }
+
+  // Collect the parts of the encode description
+  // (1) strings that are passed through to output
+  // (2) replacement/substitution variable, preceeded by a '$'
+  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
+      encoding->add_code(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();
+
+      // Add flag to _strings list indicating we should check _rep_vars
+      encoding->add_rep_var(rep_var);
+
+      skipws();
+
+      // Check if this instruct is a MachConstantNode.
+      if (strcmp(rep_var, "constanttablebase") == 0) {
+        // This instruct is a MachConstantNode.
+        inst.set_is_mach_constant(true);
+
+        if (_curchar == '(')  {
+          parse_err(SYNERR, "constanttablebase in instruct %s cannot have an argument (only constantaddress and constantoffset)", ec_name);
+          return;
+        }
+      }
+      else if ((strcmp(rep_var, "constantaddress")   == 0) ||
+               (strcmp(rep_var, "constantoffset")    == 0)) {
+        // This instruct is a MachConstantNode.
+        inst.set_is_mach_constant(true);
+
+        // If the constant keyword has an argument, parse it.
+        if (_curchar == '(')  constant_parse(inst);
+      }
+    }
+  } // end while part of format description
+  next_char();                      // Skip '%'
+  next_char();                      // Skip '}'
+
+  skipws();
+
+  if (_AD._adlocation_debug) {
+    encoding->add_code(end_line_marker());
+  }
+
+  // Debug Stuff
+  if (_AD._adl_debug > 1)  fprintf(stderr, "EncodingClass Form: %s\n", ec_name);
 }
 
 
@@ -2838,7 +2913,7 @@
 //
 //  making it more compact to take advantage of the MacroAssembler and
 //  placing the assembly closer to it's use by instructions.
-InsEncode *ADLParser::ins_encode_parse(InstructForm &inst) {
+void ADLParser::ins_encode_parse(InstructForm& inst) {
 
   // Parse encode class name
   skipws();                        // Skip whitespace
@@ -2849,11 +2924,12 @@
       next_char();                      // Skip '{'
 
       // Parse the block form of ins_encode
-      return ins_encode_parse_block(inst);
+      ins_encode_parse_block(inst);
+      return;
     }
 
     parse_err(SYNERR, "missing '%%{' or '(' in ins_encode definition\n");
-    return NULL;
+    return;
   }
   next_char();                     // move past '('
   skipws();
@@ -2866,7 +2942,7 @@
     ec_name = get_ident();
     if (ec_name == NULL) {
       parse_err(SYNERR, "Invalid encode class name after 'ins_encode('.\n");
-      return NULL;
+      return;
     }
     // Check that encoding is defined in the encode section
     EncClass *encode_class = _AD._encode->encClass(ec_name);
@@ -2898,7 +2974,7 @@
                (Opcode::as_opcode_type(param) == Opcode::NOT_AN_OPCODE) &&
                ((_AD._register == NULL ) || (_AD._register->getRegDef(param) == NULL)) ) {
             parse_err(SYNERR, "Using non-locally defined parameter %s for encoding %s.\n", param, ec_name);
-            return NULL;
+            return;
           }
           params->add_entry(param);
 
@@ -2915,7 +2991,7 @@
             // Only ',' or ')' are valid after a parameter name
             parse_err(SYNERR, "expected ',' or ')' after parameter %s.\n",
                       ec_name);
-            return NULL;
+            return;
           }
 
         } else {
@@ -2923,11 +2999,11 @@
           // Did not find a parameter
           if (_curchar == ',') {
             parse_err(SYNERR, "Expected encode parameter before ',' in encoding %s.\n", ec_name);
-            return NULL;
+            return;
           }
           if (_curchar != ')') {
             parse_err(SYNERR, "Expected ')' after encode parameters.\n");
-            return NULL;
+            return;
           }
         }
       } // WHILE loop collecting parameters
@@ -2944,7 +3020,7 @@
     else if ( _curchar != ')' ) {
       // If not a ',' then only a ')' is allowed
       parse_err(SYNERR, "Expected ')' after encoding %s.\n", ec_name);
-      return NULL;
+      return;
     }
 
     // Check for ',' separating parameters
@@ -2956,14 +3032,14 @@
   } // done parsing ins_encode methods and their parameters
   if (_curchar != ')') {
     parse_err(SYNERR, "Missing ')' at end of ins_encode description.\n");
-    return NULL;
+    return;
   }
   next_char();                     // move past ')'
   skipws();                        // Skip leading whitespace
 
   if ( _curchar != ';' ) {
     parse_err(SYNERR, "Missing ';' at end of ins_encode.\n");
-    return NULL;
+    return;
   }
   next_char();                     // move past ';'
   skipws();                        // be friendly to oper_parse()
@@ -2971,7 +3047,113 @@
   // Debug Stuff
   if (_AD._adl_debug > 1) fprintf(stderr,"Instruction Encode: %s\n", ec_name);
 
-  return encrule;
+  // Set encode class of this instruction.
+  inst._insencode = encrule;
+}
+
+
+//------------------------------constant_parse---------------------------------
+// Parse a constant expression.
+void ADLParser::constant_parse(InstructForm& inst) {
+  // Create a new encoding name based on the name of the instruction
+  // definition, which should be unique.
+  const char* prefix = "__constant_";
+  char* ec_name = (char*) malloc(strlen(inst._ident) + strlen(prefix) + 1);
+  sprintf(ec_name, "%s%s", prefix, inst._ident);
+
+  assert(_AD._encode->encClass(ec_name) == NULL, "shouldn't already exist");
+  EncClass* encoding = _AD._encode->add_EncClass(ec_name);
+  encoding->_linenum = linenum();
+
+  // synthesize the arguments list for the enc_class from the
+  // arguments to the instruct definition.
+  const char* param = NULL;
+  inst._parameters.reset();
+  while ((param = inst._parameters.iter()) != NULL) {
+    OperandForm* opForm = (OperandForm*) inst._localNames[param];
+    encoding->add_parameter(opForm->_ident, param);
+  }
+
+  // Parse the following ( ) expression.
+  constant_parse_expression(encoding, ec_name);
+
+  // Build an encoding rule which invokes the encoding rule we just
+  // created, passing all arguments that we received.
+  InsEncode*   encrule = new InsEncode(); // Encode class for instruction
+  NameAndList* params  = encrule->add_encode(ec_name);
+  inst._parameters.reset();
+  while ((param = inst._parameters.iter()) != NULL) {
+    params->add_entry(param);
+  }
+
+  // Set encode class of this instruction.
+  inst._constant = encrule;
+}
+
+
+//------------------------------constant_parse_expression----------------------
+void ADLParser::constant_parse_expression(EncClass* encoding, char* ec_name) {
+  skipws();
+
+  // Prepend location descriptor, for debugging; cf. ADLParser::find_cpp_block
+  if (_AD._adlocation_debug) {
+    encoding->add_code(get_line_string());
+  }
+
+  // Start code line.
+  encoding->add_code("    _constant = C->constant_table().add");
+
+  // Parse everything in ( ) expression.
+  encoding->add_code("(");
+  next_char();  // Skip '('
+  int parens_depth = 1;
+
+  // Collect the parts of the constant expression.
+  // (1) strings that are passed through to output
+  // (2) replacement/substitution variable, preceeded by a '$'
+  while (parens_depth > 0) {
+    if (_curchar == '(') {
+      parens_depth++;
+      encoding->add_code("(");
+      next_char();
+    }
+    else if (_curchar == ')') {
+      parens_depth--;
+      encoding->add_code(")");
+      next_char();
+    }
+    else {
+      // (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 != ')')) {
+        next_char();
+      }
+      // If a string was found, terminate it and record in EncClass
+      if (start != _ptr) {
+        *_ptr = '\0';  // Terminate the string
+        encoding->add_code(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();
+        encoding->add_rep_var(rep_var);
+      }
+    }
+  }
+
+  // Finish code line.
+  encoding->add_code(";");
+
+  if (_AD._adlocation_debug) {
+    encoding->add_code(end_line_marker());
+  }
+
+  // Debug Stuff
+  if (_AD._adl_debug > 1)  fprintf(stderr, "EncodingClass Form: %s\n", ec_name);
 }
 
 
--- a/src/share/vm/adlc/adlparse.hpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/adlc/adlparse.hpp	Thu Dec 16 20:48:11 2010 -0800
@@ -156,8 +156,13 @@
 
   Attribute     *attr_parse(char *ident);// Parse instr/operand attribute rule
   // Parse instruction encode rule
-  InsEncode     *ins_encode_parse(InstructForm &inst);
-  InsEncode     *ins_encode_parse_block(InstructForm &inst);
+  void           ins_encode_parse(InstructForm &inst);
+  void           ins_encode_parse_block(InstructForm &inst);
+  void           ins_encode_parse_block_impl(InstructForm& inst, EncClass* encoding, char* ec_name);
+
+  void           constant_parse(InstructForm& inst);
+  void           constant_parse_expression(EncClass* encoding, char* ec_name);
+
   Opcode        *opcode_parse(InstructForm *insr); // Parse instruction opcode
   char          *size_parse(InstructForm *insr); // Parse instruction size
   Interface     *interface_parse();      // Parse operand interface rule
--- a/src/share/vm/adlc/archDesc.hpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/adlc/archDesc.hpp	Thu Dec 16 20:48:11 2010 -0800
@@ -126,7 +126,6 @@
   void chain_rule(FILE *fp, const char *indent, const char *ideal,
                   const Expr *icost, const char *irule,
                   Dict &operands_chained_from, ProductionState &status);
-  void chain_rule_c(FILE *fp, char *indent, char *ideal, char *irule);  // %%%%% TODO: remove this
   void expand_opclass(FILE *fp, const char *indent, const Expr *cost,
                       const char *result_type, ProductionState &status);
   Expr *calc_cost(FILE *fp, const char *spaces, MatchList &mList, ProductionState &status);
@@ -301,13 +300,18 @@
   void buildMachNodeGenerator(FILE *fp_cpp);
 
   // Generator for Expand methods for instructions with expand rules
-  void defineExpand(FILE *fp, InstructForm *node);
+  void defineExpand      (FILE *fp, InstructForm *node);
   // Generator for Peephole methods for instructions with peephole rules
-  void definePeephole(FILE *fp, InstructForm *node);
+  void definePeephole    (FILE *fp, InstructForm *node);
   // Generator for Size methods for instructions
-  void defineSize(FILE *fp, InstructForm &node);
+  void defineSize        (FILE *fp, InstructForm &node);
+
+public:
+  // Generator for EvalConstantValue methods for instructions
+  void defineEvalConstant(FILE *fp, InstructForm &node);
   // Generator for Emit methods for instructions
-  void defineEmit(FILE *fp, InstructForm &node);
+  void defineEmit        (FILE *fp, InstructForm &node);
+
   // Define a MachOper encode method
   void define_oper_interface(FILE *fp, OperandForm &oper, FormDict &globals,
                              const char *name, const char *encoding);
--- a/src/share/vm/adlc/formssel.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/adlc/formssel.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -30,11 +30,14 @@
 InstructForm::InstructForm(const char *id, bool ideal_only)
   : _ident(id), _ideal_only(ideal_only),
     _localNames(cmpstr, hashstr, Form::arena),
-    _effects(cmpstr, hashstr, Form::arena) {
+    _effects(cmpstr, hashstr, Form::arena),
+    _is_mach_constant(false)
+{
       _ftype = Form::INS;
 
       _matrule   = NULL;
       _insencode = NULL;
+      _constant  = NULL;
       _opcode    = NULL;
       _size      = NULL;
       _attribs   = NULL;
@@ -58,11 +61,14 @@
 InstructForm::InstructForm(const char *id, InstructForm *instr, MatchRule *rule)
   : _ident(id), _ideal_only(false),
     _localNames(instr->_localNames),
-    _effects(instr->_effects) {
+    _effects(instr->_effects),
+    _is_mach_constant(false)
+{
       _ftype = Form::INS;
 
       _matrule   = rule;
       _insencode = instr->_insencode;
+      _constant  = instr->_constant;
       _opcode    = instr->_opcode;
       _size      = instr->_size;
       _attribs   = instr->_attribs;
@@ -1094,6 +1100,9 @@
   else if (is_ideal_nop()) {
     return "MachNopNode";
   }
+  else if (is_mach_constant()) {
+    return "MachConstantNode";
+  }
   else if (captures_bottom_type(globals)) {
     return "MachTypeNode";
   } else {
@@ -1190,6 +1199,21 @@
 //
 // Generate the format call for the replacement variable
 void InstructForm::rep_var_format(FILE *fp, const char *rep_var) {
+  // Handle special constant table variables.
+  if (strcmp(rep_var, "constanttablebase") == 0) {
+    fprintf(fp, "char reg[128];  ra->dump_register(in(mach_constant_base_node_input()), reg);\n");
+    fprintf(fp, "st->print(\"%%s\");\n");
+    return;
+  }
+  if (strcmp(rep_var, "constantoffset") == 0) {
+    fprintf(fp, "st->print(\"#%%d\", constant_offset());\n");
+    return;
+  }
+  if (strcmp(rep_var, "constantaddress") == 0) {
+    fprintf(fp, "st->print(\"constant table base + #%%d\", constant_offset());\n");
+    return;
+  }
+
   // Find replacement variable's type
   const Form *form   = _localNames[rep_var];
   if (form == NULL) {
@@ -1348,6 +1372,7 @@
   fprintf(fp,"\nInstruction: %s\n", (_ident?_ident:""));
   if (_matrule)   _matrule->output(fp);
   if (_insencode) _insencode->output(fp);
+  if (_constant)  _constant->output(fp);
   if (_opcode)    _opcode->output(fp);
   if (_attribs)   _attribs->output(fp);
   if (_predicate) _predicate->output(fp);
--- a/src/share/vm/adlc/formssel.hpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/adlc/formssel.hpp	Thu Dec 16 20:48:11 2010 -0800
@@ -74,15 +74,16 @@
 //------------------------------InstructForm-----------------------------------
 class InstructForm : public Form {
 private:
-  bool          _ideal_only;       // Not a user-defined instruction
+  bool           _ideal_only;       // Not a user-defined instruction
   // Members used for tracking CISC-spilling
-  uint          _cisc_spill_operand;// Which operand may cisc-spill
+  uint           _cisc_spill_operand;// Which operand may cisc-spill
   void           set_cisc_spill_operand(uint op_index) { _cisc_spill_operand = op_index; }
-  bool          _is_cisc_alternate;
+  bool           _is_cisc_alternate;
   InstructForm  *_cisc_spill_alternate;// cisc possible replacement
   const char    *_cisc_reg_mask_name;
   InstructForm  *_short_branch_form;
   bool           _is_short_branch;
+  bool           _is_mach_constant;   // true if Node is a MachConstantNode
   uint           _alignment;
 
 public:
@@ -94,6 +95,7 @@
   Opcode        *_opcode;          // Encoding of the opcode for instruction
   char          *_size;            // Size of instruction
   InsEncode     *_insencode;       // Encoding class instruction belongs to
+  InsEncode     *_constant;        // Encoding class constant value belongs to
   Attribute     *_attribs;         // List of Attribute rules
   Predicate     *_predicate;       // Predicate test for this instruction
   FormDict       _effects;         // Dictionary of effect rules
@@ -251,6 +253,9 @@
   bool                is_short_branch() { return _is_short_branch; }
   void                set_short_branch(bool val) { _is_short_branch = val; }
 
+  bool                    is_mach_constant() const { return _is_mach_constant;     }
+  void                set_is_mach_constant(bool x) {        _is_mach_constant = x; }
+
   InstructForm       *short_branch_form() { return _short_branch_form; }
   bool                has_short_branch_form() { return _short_branch_form != NULL; }
   // Output short branch prototypes and method bodies
--- a/src/share/vm/adlc/output_c.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/adlc/output_c.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -1496,8 +1496,8 @@
   unsigned      i;
 
   // Generate Expand function header
-  fprintf(fp,"MachNode *%sNode::Expand(State *state, Node_List &proj_list, Node* mem) {\n", node->_ident);
-  fprintf(fp,"Compile* C = Compile::current();\n");
+  fprintf(fp, "MachNode* %sNode::Expand(State* state, Node_List& proj_list, Node* mem) {\n", node->_ident);
+  fprintf(fp, "  Compile* C = Compile::current();\n");
   // Generate expand code
   if( node->expands() ) {
     const char   *opid;
@@ -1818,6 +1818,12 @@
     }
   }
 
+  // If the node is a MachConstantNode, insert the MachConstantBaseNode edge.
+  // NOTE: this edge must be the last input (see MachConstantNode::mach_constant_base_node_input).
+  if (node->is_mach_constant()) {
+    fprintf(fp,"  add_req(C->mach_constant_base_node());\n");
+  }
+
   fprintf(fp,"\n");
   if( node->expands() ) {
     fprintf(fp,"  return result;\n");
@@ -1924,7 +1930,17 @@
         // No state needed.
         assert( _opclass == NULL,
                 "'primary', 'secondary' and 'tertiary' don't follow operand.");
-      } else {
+      }
+      else if ((strcmp(rep_var, "constanttablebase") == 0) ||
+               (strcmp(rep_var, "constantoffset")    == 0) ||
+               (strcmp(rep_var, "constantaddress")   == 0)) {
+        if (!_inst.is_mach_constant()) {
+          _AD.syntax_err(_encoding._linenum,
+                         "Replacement variable %s not allowed in instruct %s (only in MachConstantNode).\n",
+                         rep_var, _encoding._name);
+        }
+      }
+      else {
         // Lookup its position in parameter list
         int   param_no  = _encoding.rep_var_index(rep_var);
         if ( param_no == -1 ) {
@@ -2380,6 +2396,15 @@
                         rep_var, _inst._ident, _encoding._name);
       }
     }
+    else if (strcmp(rep_var, "constanttablebase") == 0) {
+      fprintf(_fp, "as_Register(ra_->get_encode(in(mach_constant_base_node_input())))");
+    }
+    else if (strcmp(rep_var, "constantoffset") == 0) {
+      fprintf(_fp, "constant_offset()");
+    }
+    else if (strcmp(rep_var, "constantaddress") == 0) {
+      fprintf(_fp, "InternalAddress(__ code()->consts()->start() + constant_offset())");
+    }
     else {
       // Lookup its position in parameter list
       int   param_no  = _encoding.rep_var_index(rep_var);
@@ -2465,37 +2490,39 @@
   fprintf(fp,"}\n");
 }
 
-void ArchDesc::defineEmit(FILE *fp, InstructForm &inst) {
-  InsEncode *ins_encode = inst._insencode;
+// defineEmit -----------------------------------------------------------------
+void ArchDesc::defineEmit(FILE* fp, InstructForm& inst) {
+  InsEncode* encode = inst._insencode;
 
   // (1)
   // Output instruction's emit prototype
-  fprintf(fp,"void  %sNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {\n",
-          inst._ident);
+  fprintf(fp, "void %sNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {\n", inst._ident);
 
   // If user did not define an encode section,
   // provide stub that does not generate any machine code.
-  if( (_encode == NULL) || (ins_encode == NULL) ) {
+  if( (_encode == NULL) || (encode == NULL) ) {
     fprintf(fp, "  // User did not define an encode section.\n");
-    fprintf(fp,"}\n");
+    fprintf(fp, "}\n");
     return;
   }
 
   // Save current instruction's starting address (helps with relocation).
-  fprintf(fp, "    cbuf.set_insts_mark();\n");
-
-  // // // idx0 is only needed for syntactic purposes and only by "storeSSI"
-  // fprintf( fp, "    unsigned idx0  = 0;\n");
+  fprintf(fp, "  cbuf.set_insts_mark();\n");
+
+  // For MachConstantNodes which are ideal jump nodes, fill the jump table.
+  if (inst.is_mach_constant() && inst.is_ideal_jump()) {
+    fprintf(fp, "  ra_->C->constant_table().fill_jump_table(cbuf, (MachConstantNode*) this, _index2label);\n");
+  }
 
   // Output each operand's offset into the array of registers.
-  inst.index_temps( fp, _globalNames );
+  inst.index_temps(fp, _globalNames);
 
   // Output this instruction's encodings
   const char *ec_name;
   bool        user_defined = false;
-  ins_encode->reset();
-  while ( (ec_name = ins_encode->encode_class_iter()) != NULL ) {
-    fprintf(fp, "  {");
+  encode->reset();
+  while ((ec_name = encode->encode_class_iter()) != NULL) {
+    fprintf(fp, "  {\n");
     // Output user-defined encoding
     user_defined           = true;
 
@@ -2507,25 +2534,25 @@
       abort();
     }
 
-    if (ins_encode->current_encoding_num_args() != encoding->num_args()) {
-      globalAD->syntax_err(ins_encode->_linenum, "In %s: passing %d arguments to %s but expecting %d",
-                           inst._ident, ins_encode->current_encoding_num_args(),
+    if (encode->current_encoding_num_args() != encoding->num_args()) {
+      globalAD->syntax_err(encode->_linenum, "In %s: passing %d arguments to %s but expecting %d",
+                           inst._ident, encode->current_encoding_num_args(),
                            ec_name, encoding->num_args());
     }
 
-    DefineEmitState  pending(fp, *this, *encoding, *ins_encode, inst );
+    DefineEmitState pending(fp, *this, *encoding, *encode, inst);
     encoding->_code.reset();
     encoding->_rep_vars.reset();
     // Process list of user-defined strings,
     // and occurrences of replacement variables.
     // Replacement Vars are pushed into a list and then output
-    while ( (ec_code = encoding->_code.iter()) != NULL ) {
-      if ( ! encoding->_code.is_signal( ec_code ) ) {
+    while ((ec_code = encoding->_code.iter()) != NULL) {
+      if (!encoding->_code.is_signal(ec_code)) {
         // Emit pending code
         pending.emit();
         pending.clear();
         // Emit this code section
-        fprintf(fp,"%s", ec_code);
+        fprintf(fp, "%s", ec_code);
       } else {
         // A replacement variable or one of its subfields
         // Obtain replacement variable from list
@@ -2536,7 +2563,7 @@
     // Emit pending code
     pending.emit();
     pending.clear();
-    fprintf(fp, "}\n");
+    fprintf(fp, "  }\n");
   } // end while instruction's encodings
 
   // Check if user stated which encoding to user
@@ -2545,7 +2572,86 @@
   }
 
   // (3) and (4)
-  fprintf(fp,"}\n");
+  fprintf(fp, "}\n");
+}
+
+// defineEvalConstant ---------------------------------------------------------
+void ArchDesc::defineEvalConstant(FILE* fp, InstructForm& inst) {
+  InsEncode* encode = inst._constant;
+
+  // (1)
+  // Output instruction's emit prototype
+  fprintf(fp, "void %sNode::eval_constant(Compile* C) {\n", inst._ident);
+
+  // For ideal jump nodes, allocate a jump table.
+  if (inst.is_ideal_jump()) {
+    fprintf(fp, "  _constant = C->constant_table().allocate_jump_table(this);\n");
+  }
+
+  // If user did not define an encode section,
+  // provide stub that does not generate any machine code.
+  if ((_encode == NULL) || (encode == NULL)) {
+    fprintf(fp, "  // User did not define an encode section.\n");
+    fprintf(fp, "}\n");
+    return;
+  }
+
+  // Output this instruction's encodings
+  const char *ec_name;
+  bool        user_defined = false;
+  encode->reset();
+  while ((ec_name = encode->encode_class_iter()) != NULL) {
+    fprintf(fp, "  {\n");
+    // Output user-defined encoding
+    user_defined           = true;
+
+    const char *ec_code    = NULL;
+    const char *ec_rep_var = NULL;
+    EncClass   *encoding   = _encode->encClass(ec_name);
+    if (encoding == NULL) {
+      fprintf(stderr, "User did not define contents of this encode_class: %s\n", ec_name);
+      abort();
+    }
+
+    if (encode->current_encoding_num_args() != encoding->num_args()) {
+      globalAD->syntax_err(encode->_linenum, "In %s: passing %d arguments to %s but expecting %d",
+                           inst._ident, encode->current_encoding_num_args(),
+                           ec_name, encoding->num_args());
+    }
+
+    DefineEmitState pending(fp, *this, *encoding, *encode, inst);
+    encoding->_code.reset();
+    encoding->_rep_vars.reset();
+    // Process list of user-defined strings,
+    // and occurrences of replacement variables.
+    // Replacement Vars are pushed into a list and then output
+    while ((ec_code = encoding->_code.iter()) != NULL) {
+      if (!encoding->_code.is_signal(ec_code)) {
+        // Emit pending code
+        pending.emit();
+        pending.clear();
+        // Emit this code section
+        fprintf(fp, "%s", ec_code);
+      } else {
+        // A replacement variable or one of its subfields
+        // Obtain replacement variable from list
+        ec_rep_var  = encoding->_rep_vars.iter();
+        pending.add_rep_var(ec_rep_var);
+      }
+    }
+    // Emit pending code
+    pending.emit();
+    pending.clear();
+    fprintf(fp, "  }\n");
+  } // end while instruction's encodings
+
+  // Check if user stated which encoding to user
+  if (user_defined == false) {
+    fprintf(fp, "  // User did not define which encode class to use.\n");
+  }
+
+  // (3) and (4)
+  fprintf(fp, "}\n");
 }
 
 // ---------------------------------------------------------------------------
@@ -2952,6 +3058,7 @@
     // If there are multiple defs/kills, or an explicit expand rule, build rule
     if( instr->expands() || instr->needs_projections() ||
         instr->has_temps() ||
+        instr->is_mach_constant() ||
         instr->_matrule != NULL &&
         instr->num_opnds() != instr->num_unique_opnds() )
       defineExpand(_CPP_EXPAND_file._fp, instr);
@@ -3032,8 +3139,9 @@
     // Ensure this is a machine-world instruction
     if ( instr->ideal_only() ) continue;
 
-    if (instr->_insencode) defineEmit(fp, *instr);
-    if (instr->_size)      defineSize(fp, *instr);
+    if (instr->_insencode)         defineEmit        (fp, *instr);
+    if (instr->is_mach_constant()) defineEvalConstant(fp, *instr);
+    if (instr->_size)              defineSize        (fp, *instr);
 
     // side-call to generate output that used to be in the header file:
     extern void gen_inst_format(FILE *fp, FormDict &globals, InstructForm &oper, bool for_c_file);
--- a/src/share/vm/adlc/output_h.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/adlc/output_h.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -1550,7 +1550,12 @@
     }
 
     // virtual functions for encode and format
-    //
+
+    // Virtual function for evaluating the constant.
+    if (instr->is_mach_constant()) {
+      fprintf(fp,"  virtual void           eval_constant(Compile* C);\n");
+    }
+
     // Output the opcode function and the encode function here using the
     // encoding class information in the _insencode slot.
     if ( instr->_insencode ) {
@@ -1559,7 +1564,7 @@
 
     // virtual function for getting the size of an instruction
     if ( instr->_size ) {
-       fprintf(fp,"  virtual uint           size(PhaseRegAlloc *ra_) const;\n");
+      fprintf(fp,"  virtual uint           size(PhaseRegAlloc *ra_) const;\n");
     }
 
     // Return the top-level ideal opcode.
@@ -1752,6 +1757,7 @@
     // Virtual methods which are only generated to override base class
     if( instr->expands() || instr->needs_projections() ||
         instr->has_temps() ||
+        instr->is_mach_constant() ||
         instr->_matrule != NULL &&
         instr->num_opnds() != instr->num_unique_opnds() ) {
       fprintf(fp,"  virtual MachNode      *Expand(State *state, Node_List &proj_list, Node* mem);\n");
@@ -1780,24 +1786,6 @@
     // Declare short branch methods, if applicable
     instr->declare_short_branch_methods(fp);
 
-    // Instructions containing a constant that will be entered into the
-    // float/double table redefine the base virtual function
-#ifdef SPARC
-    // Sparc doubles entries in the constant table require more space for
-    // alignment. (expires 9/98)
-    int table_entries = (3 * instr->num_consts( _globalNames, Form::idealD ))
-      + instr->num_consts( _globalNames, Form::idealF );
-#else
-    int table_entries = instr->num_consts( _globalNames, Form::idealD )
-      + instr->num_consts( _globalNames, Form::idealF );
-#endif
-    if( table_entries != 0 ) {
-      fprintf(fp,"  virtual int            const_size() const {");
-      fprintf(fp,   " return %d;", table_entries);
-      fprintf(fp, " }\n");
-    }
-
-
     // See if there is an "ins_pipe" declaration for this instruction
     if (instr->_ins_pipe) {
       fprintf(fp,"  static  const Pipeline *pipeline_class();\n");
--- a/src/share/vm/asm/assembler.hpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/asm/assembler.hpp	Thu Dec 16 20:48:11 2010 -0800
@@ -292,7 +292,16 @@
   address    start_a_const(int required_space, int required_align = sizeof(double));
   void       end_a_const();
 
-  // fp constants support
+  // constants support
+  address long_constant(jlong c) {
+    address ptr = start_a_const(sizeof(c), sizeof(c));
+    if (ptr != NULL) {
+      *(jlong*)ptr = c;
+      _code_pos = ptr + sizeof(c);
+      end_a_const();
+    }
+    return ptr;
+  }
   address double_constant(jdouble c) {
     address ptr = start_a_const(sizeof(c), sizeof(c));
     if (ptr != NULL) {
@@ -311,6 +320,15 @@
     }
     return ptr;
   }
+  address address_constant(address c) {
+    address ptr = start_a_const(sizeof(c), sizeof(c));
+    if (ptr != NULL) {
+      *(address*)ptr = c;
+      _code_pos = ptr + sizeof(c);
+      end_a_const();
+    }
+    return ptr;
+  }
   address address_constant(address c, RelocationHolder const& rspec) {
     address ptr = start_a_const(sizeof(c), sizeof(c));
     if (ptr != NULL) {
@@ -321,8 +339,6 @@
     }
     return ptr;
   }
-  inline address address_constant(Label& L);
-  inline address address_table_constant(GrowableArray<Label*> label);
 
   // Bootstrapping aid to cope with delayed determination of constants.
   // Returns a static address which will eventually contain the constant.
--- a/src/share/vm/asm/assembler.inline.hpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/asm/assembler.inline.hpp	Thu Dec 16 20:48:11 2010 -0800
@@ -114,32 +114,4 @@
   bind_loc(CodeBuffer::locator(pos, sect));
 }
 
-address AbstractAssembler::address_constant(Label& L) {
-  address c = NULL;
-  address ptr = start_a_const(sizeof(c), sizeof(c));
-  if (ptr != NULL) {
-    relocate(Relocation::spec_simple(relocInfo::internal_word_type));
-    *(address*)ptr = c = code_section()->target(L, ptr);
-    _code_pos = ptr + sizeof(c);
-    end_a_const();
-  }
-  return ptr;
-}
-
-address AbstractAssembler::address_table_constant(GrowableArray<Label*> labels) {
-  int addressSize = sizeof(address);
-  int sizeLabel = addressSize * labels.length();
-  address ptr = start_a_const(sizeLabel, addressSize);
-
-  if (ptr != NULL) {
-    address *labelLoc = (address*)ptr;
-    for (int i=0; i < labels.length(); i++) {
-      emit_address(code_section()->target(*labels.at(i), (address)&labelLoc[i]));
-      code_section()->relocate((address)&labelLoc[i], relocInfo::internal_word_type);
-    }
-    end_a_const();
-  }
-  return ptr;
-}
-
 #endif // SHARE_VM_ASM_ASSEMBLER_INLINE_HPP
--- a/src/share/vm/asm/codeBuffer.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/asm/codeBuffer.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -131,6 +131,7 @@
 #ifdef ASSERT
   // Save allocation type to execute assert in ~ResourceObj()
   // which is called after this destructor.
+  assert(_default_oop_recorder.allocated_on_stack(), "should be embedded object");
   ResourceObj::allocation_type at = _default_oop_recorder.get_allocation_type();
   Copy::fill_to_bytes(this, sizeof(*this), badResourceValue);
   ResourceObj::set_allocation_type((address)(&_default_oop_recorder), at);
--- a/src/share/vm/c1/c1_Compilation.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/c1/c1_Compilation.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -298,8 +298,8 @@
 
   CHECK_BAILOUT_(no_frame_size);
 
-  if (is_profiling()) {
-    method()->build_method_data();
+  if (is_profiling() && !method()->ensure_method_data()) {
+    BAILOUT_("mdo allocation failed", no_frame_size);
   }
 
   {
@@ -484,11 +484,11 @@
     if (is_profiling()) {
       // Compilation failed, create MDO, which would signal the interpreter
       // to start profiling on its own.
-      _method->build_method_data();
+      _method->ensure_method_data();
     }
   } else if (is_profiling() && _would_profile) {
-    ciMethodData *md = method->method_data();
-    assert (md != NULL, "Should have MDO");
+    ciMethodData *md = method->method_data_or_null();
+    assert(md != NULL, "Sanity");
     md->set_would_profile(_would_profile);
   }
 }
--- a/src/share/vm/c1/c1_FrameMap.hpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/c1/c1_FrameMap.hpp	Thu Dec 16 20:48:11 2010 -0800
@@ -76,8 +76,8 @@
     nof_cpu_regs_reg_alloc = pd_nof_cpu_regs_reg_alloc,
     nof_fpu_regs_reg_alloc = pd_nof_fpu_regs_reg_alloc,
 
-    nof_caller_save_cpu_regs = pd_nof_caller_save_cpu_regs_frame_map,
-    nof_caller_save_fpu_regs = pd_nof_caller_save_fpu_regs_frame_map,
+    max_nof_caller_save_cpu_regs = pd_nof_caller_save_cpu_regs_frame_map,
+    nof_caller_save_fpu_regs     = pd_nof_caller_save_fpu_regs_frame_map,
 
     spill_slot_size_in_bytes = 4
   };
@@ -97,7 +97,7 @@
   static Register     _cpu_rnr2reg [nof_cpu_regs];
   static int          _cpu_reg2rnr [nof_cpu_regs];
 
-  static LIR_Opr      _caller_save_cpu_regs [nof_caller_save_cpu_regs];
+  static LIR_Opr      _caller_save_cpu_regs [max_nof_caller_save_cpu_regs];
   static LIR_Opr      _caller_save_fpu_regs [nof_caller_save_fpu_regs];
 
   int                 _framesize;
@@ -243,7 +243,7 @@
   VMReg regname(LIR_Opr opr) const;
 
   static LIR_Opr caller_save_cpu_reg_at(int i) {
-    assert(i >= 0 && i < nof_caller_save_cpu_regs, "out of bounds");
+    assert(i >= 0 && i < max_nof_caller_save_cpu_regs, "out of bounds");
     return _caller_save_cpu_regs[i];
   }
 
--- a/src/share/vm/c1/c1_GraphBuilder.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/c1/c1_GraphBuilder.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -2795,7 +2795,7 @@
       get = append(new UnsafeGetRaw(as_BasicType(local->type()), e,
                                     append(new Constant(new IntConstant(offset))),
                                     0,
-                                    true));
+                                    true /*unaligned*/, true /*wide*/));
     }
     _state->store_local(index, get);
   }
@@ -3377,6 +3377,9 @@
     INLINE_BAILOUT("total inlining greater than DesiredMethodLimit");
   }
 
+  if (is_profiling() && !callee->ensure_method_data()) {
+    INLINE_BAILOUT("mdo allocation failed");
+  }
 #ifndef PRODUCT
       // printing
   if (PrintInlining) {
--- a/src/share/vm/c1/c1_IR.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/c1/c1_IR.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -504,7 +504,12 @@
   count_edges(start_block, NULL);
 
   if (compilation()->is_profiling()) {
-    compilation()->method()->method_data()->set_compilation_stats(_num_loops, _num_blocks);
+    ciMethod *method = compilation()->method();
+    if (!method->is_accessor()) {
+      ciMethodData* md = method->method_data_or_null();
+      assert(md != NULL, "Sanity");
+      md->set_compilation_stats(_num_loops, _num_blocks);
+    }
   }
 
   if (_num_loops > 0) {
--- a/src/share/vm/c1/c1_Instruction.hpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/c1/c1_Instruction.hpp	Thu Dec 16 20:48:11 2010 -0800
@@ -2110,20 +2110,23 @@
 
 LEAF(UnsafeGetRaw, UnsafeRawOp)
  private:
-  bool _may_be_unaligned;  // For OSREntry
+ bool _may_be_unaligned, _is_wide;  // For OSREntry
 
  public:
-  UnsafeGetRaw(BasicType basic_type, Value addr, bool may_be_unaligned)
+ UnsafeGetRaw(BasicType basic_type, Value addr, bool may_be_unaligned, bool is_wide = false)
   : UnsafeRawOp(basic_type, addr, false) {
     _may_be_unaligned = may_be_unaligned;
+    _is_wide = is_wide;
   }
 
-  UnsafeGetRaw(BasicType basic_type, Value base, Value index, int log2_scale, bool may_be_unaligned)
+ UnsafeGetRaw(BasicType basic_type, Value base, Value index, int log2_scale, bool may_be_unaligned, bool is_wide = false)
   : UnsafeRawOp(basic_type, base, index, log2_scale, false) {
     _may_be_unaligned = may_be_unaligned;
+    _is_wide = is_wide;
   }
 
-  bool may_be_unaligned()                               { return _may_be_unaligned; }
+  bool may_be_unaligned()                         { return _may_be_unaligned; }
+  bool is_wide()                                  { return _is_wide; }
 };
 
 
--- a/src/share/vm/c1/c1_LIR.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/c1/c1_LIR.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -1742,6 +1742,8 @@
       return "unaligned move";
     case lir_move_volatile:
       return "volatile_move";
+    case lir_move_wide:
+      return "wide_move";
     default:
       ShouldNotReachHere();
     return "illegal_op";
--- a/src/share/vm/c1/c1_LIR.hpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/c1/c1_LIR.hpp	Thu Dec 16 20:48:11 2010 -0800
@@ -985,6 +985,7 @@
   lir_move_normal,
   lir_move_volatile,
   lir_move_unaligned,
+  lir_move_wide,
   lir_move_max_flag
 };
 
@@ -1932,7 +1933,20 @@
   void move(LIR_Opr src, LIR_Opr dst, CodeEmitInfo* info = NULL) { append(new LIR_Op1(lir_move, src, dst, dst->type(), lir_patch_none, info)); }
   void move(LIR_Address* src, LIR_Opr dst, CodeEmitInfo* info = NULL) { append(new LIR_Op1(lir_move, LIR_OprFact::address(src), dst, src->type(), lir_patch_none, info)); }
   void move(LIR_Opr src, LIR_Address* dst, CodeEmitInfo* info = NULL) { append(new LIR_Op1(lir_move, src, LIR_OprFact::address(dst), dst->type(), lir_patch_none, info)); }
-
+  void move_wide(LIR_Address* src, LIR_Opr dst, CodeEmitInfo* info = NULL) {
+    if (UseCompressedOops) {
+      append(new LIR_Op1(lir_move, LIR_OprFact::address(src), dst, src->type(), lir_patch_none, info, lir_move_wide));
+    } else {
+      move(src, dst, info);
+    }
+  }
+  void move_wide(LIR_Opr src, LIR_Address* dst, CodeEmitInfo* info = NULL) {
+    if (UseCompressedOops) {
+      append(new LIR_Op1(lir_move, src, LIR_OprFact::address(dst), dst->type(), lir_patch_none, info, lir_move_wide));
+    } else {
+      move(src, dst, info);
+    }
+  }
   void volatile_move(LIR_Opr src, LIR_Opr dst, BasicType type, CodeEmitInfo* info = NULL, LIR_PatchCode patch_code = lir_patch_none) { append(new LIR_Op1(lir_move, src, dst, type, patch_code, info, lir_move_volatile)); }
 
   void oop2reg  (jobject o, LIR_Opr reg)         { append(new LIR_Op1(lir_move, LIR_OprFact::oopConst(o),    reg));   }
--- a/src/share/vm/c1/c1_LIRAssembler.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/c1/c1_LIRAssembler.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -489,7 +489,9 @@
         volatile_move_op(op->in_opr(), op->result_opr(), op->type(), op->info());
       } else {
         move_op(op->in_opr(), op->result_opr(), op->type(),
-                op->patch_code(), op->info(), op->pop_fpu_stack(), op->move_kind() == lir_move_unaligned);
+                op->patch_code(), op->info(), op->pop_fpu_stack(),
+                op->move_kind() == lir_move_unaligned,
+                op->move_kind() == lir_move_wide);
       }
       break;
 
@@ -758,7 +760,7 @@
 }
 
 
-void LIR_Assembler::move_op(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_PatchCode patch_code, CodeEmitInfo* info, bool pop_fpu_stack, bool unaligned) {
+void LIR_Assembler::move_op(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_PatchCode patch_code, CodeEmitInfo* info, bool pop_fpu_stack, bool unaligned, bool wide) {
   if (src->is_register()) {
     if (dest->is_register()) {
       assert(patch_code == lir_patch_none && info == NULL, "no patching and info allowed here");
@@ -767,7 +769,7 @@
       assert(patch_code == lir_patch_none && info == NULL, "no patching and info allowed here");
       reg2stack(src, dest, type, pop_fpu_stack);
     } else if (dest->is_address()) {
-      reg2mem(src, dest, type, patch_code, info, pop_fpu_stack, unaligned);
+      reg2mem(src, dest, type, patch_code, info, pop_fpu_stack, wide, unaligned);
     } else {
       ShouldNotReachHere();
     }
@@ -790,13 +792,13 @@
       const2stack(src, dest);
     } else if (dest->is_address()) {
       assert(patch_code == lir_patch_none, "no patching allowed here");
-      const2mem(src, dest, type, info);
+      const2mem(src, dest, type, info, wide);
     } else {
       ShouldNotReachHere();
     }
 
   } else if (src->is_address()) {
-    mem2reg(src, dest, type, patch_code, info, unaligned);
+    mem2reg(src, dest, type, patch_code, info, wide, unaligned);
 
   } else {
     ShouldNotReachHere();
--- a/src/share/vm/c1/c1_LIRAssembler.hpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/c1/c1_LIRAssembler.hpp	Thu Dec 16 20:48:11 2010 -0800
@@ -165,15 +165,17 @@
 
   void const2reg  (LIR_Opr src, LIR_Opr dest, LIR_PatchCode patch_code, CodeEmitInfo* info);
   void const2stack(LIR_Opr src, LIR_Opr dest);
-  void const2mem  (LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmitInfo* info);
+  void const2mem  (LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmitInfo* info, bool wide);
   void reg2stack  (LIR_Opr src, LIR_Opr dest, BasicType type, bool pop_fpu_stack);
   void reg2reg    (LIR_Opr src, LIR_Opr dest);
-  void reg2mem    (LIR_Opr src, LIR_Opr dest, BasicType type, LIR_PatchCode patch_code, CodeEmitInfo* info, bool pop_fpu_stack, bool unaligned);
+  void reg2mem    (LIR_Opr src, LIR_Opr dest, BasicType type,
+                   LIR_PatchCode patch_code, CodeEmitInfo* info,
+                   bool pop_fpu_stack, bool wide, bool unaligned);
   void stack2reg  (LIR_Opr src, LIR_Opr dest, BasicType type);
   void stack2stack(LIR_Opr src, LIR_Opr dest, BasicType type);
   void mem2reg    (LIR_Opr src, LIR_Opr dest, BasicType type,
-                   LIR_PatchCode patch_code = lir_patch_none,
-                   CodeEmitInfo* info = NULL, bool unaligned = false);
+                   LIR_PatchCode patch_code,
+                   CodeEmitInfo* info, bool wide, bool unaligned);
 
   void prefetchr  (LIR_Opr src);
   void prefetchw  (LIR_Opr src);
@@ -211,7 +213,7 @@
 
   void roundfp_op(LIR_Opr src, LIR_Opr tmp, LIR_Opr dest, bool pop_fpu_stack);
   void move_op(LIR_Opr src, LIR_Opr result, BasicType type,
-               LIR_PatchCode patch_code, CodeEmitInfo* info, bool pop_fpu_stack, bool unaligned);
+               LIR_PatchCode patch_code, CodeEmitInfo* info, bool pop_fpu_stack, bool unaligned, bool wide);
   void volatile_move_op(LIR_Opr src, LIR_Opr result, BasicType type, CodeEmitInfo* info);
   void comp_mem_op(LIR_Opr src, LIR_Opr result, BasicType type, CodeEmitInfo* info);  // info set for null exceptions
   void comp_fl2i(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr result, LIR_Op2* op);
--- a/src/share/vm/c1/c1_LIRGenerator.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/c1/c1_LIRGenerator.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -836,11 +836,8 @@
   if (if_instr->should_profile()) {
     ciMethod* method = if_instr->profiled_method();
     assert(method != NULL, "method should be set if branch is profiled");
-    ciMethodData* md = method->method_data();
-    if (md == NULL) {
-      bailout("out of memory building methodDataOop");
-      return;
-    }
+    ciMethodData* md = method->method_data_or_null();
+    assert(md != NULL, "Sanity");
     ciProfileData* data = md->bci_to_data(if_instr->profiled_bci());
     assert(data != NULL, "must have profiling data");
     assert(data->is_BranchData(), "need BranchData for two-way branches");
@@ -864,11 +861,11 @@
     // MDO cells are intptr_t, so the data_reg width is arch-dependent.
     LIR_Opr data_reg = new_pointer_register();
     LIR_Address* data_addr = new LIR_Address(md_reg, data_offset_reg, data_reg->type());
-    __ move(LIR_OprFact::address(data_addr), data_reg);
+    __ move(data_addr, data_reg);
     // Use leal instead of add to avoid destroying condition codes on x86
     LIR_Address* fake_incr_value = new LIR_Address(data_reg, DataLayout::counter_increment, T_INT);
     __ leal(LIR_OprFact::address(fake_incr_value), data_reg);
-    __ move(data_reg, LIR_OprFact::address(data_addr));
+    __ move(data_reg, data_addr);
   }
 }
 
@@ -1009,12 +1006,12 @@
                    operand_for_instruction(phi));
 
   LIR_Opr thread_reg = getThreadPointer();
-  __ move(new LIR_Address(thread_reg, in_bytes(JavaThread::exception_oop_offset()), T_OBJECT),
-          exceptionOopOpr());
-  __ move(LIR_OprFact::oopConst(NULL),
-          new LIR_Address(thread_reg, in_bytes(JavaThread::exception_oop_offset()), T_OBJECT));
-  __ move(LIR_OprFact::oopConst(NULL),
-          new LIR_Address(thread_reg, in_bytes(JavaThread::exception_pc_offset()), T_OBJECT));
+  __ move_wide(new LIR_Address(thread_reg, in_bytes(JavaThread::exception_oop_offset()), T_OBJECT),
+               exceptionOopOpr());
+  __ move_wide(LIR_OprFact::oopConst(NULL),
+               new LIR_Address(thread_reg, in_bytes(JavaThread::exception_oop_offset()), T_OBJECT));
+  __ move_wide(LIR_OprFact::oopConst(NULL),
+               new LIR_Address(thread_reg, in_bytes(JavaThread::exception_pc_offset()), T_OBJECT));
 
   LIR_Opr result = new_register(T_OBJECT);
   __ move(exceptionOopOpr(), result);
@@ -1085,7 +1082,7 @@
 void LIRGenerator::do_Return(Return* x) {
   if (compilation()->env()->dtrace_method_probes()) {
     BasicTypeList signature;
-    signature.append(T_INT);    // thread
+    signature.append(LP64_ONLY(T_LONG) NOT_LP64(T_INT));    // thread
     signature.append(T_OBJECT); // methodOop
     LIR_OprList* args = new LIR_OprList();
     args->append(getThreadPointer());
@@ -1122,8 +1119,8 @@
     info = state_for(x);
   }
   __ move(new LIR_Address(rcvr.result(), oopDesc::klass_offset_in_bytes(), T_OBJECT), result, info);
-  __ move(new LIR_Address(result, Klass::java_mirror_offset_in_bytes() +
-                          klassOopDesc::klass_part_offset_in_bytes(), T_OBJECT), result);
+  __ move_wide(new LIR_Address(result, Klass::java_mirror_offset_in_bytes() +
+                               klassOopDesc::klass_part_offset_in_bytes(), T_OBJECT), result);
 }
 
 
@@ -1131,7 +1128,7 @@
 void LIRGenerator::do_currentThread(Intrinsic* x) {
   assert(x->number_of_arguments() == 0, "wrong type");
   LIR_Opr reg = rlock_result(x);
-  __ load(new LIR_Address(getThreadPointer(), in_bytes(JavaThread::threadObj_offset()), T_OBJECT), reg);
+  __ move_wide(new LIR_Address(getThreadPointer(), in_bytes(JavaThread::threadObj_offset()), T_OBJECT), reg);
 }
 
 
@@ -1908,7 +1905,11 @@
   if (x->may_be_unaligned() && (dst_type == T_LONG || dst_type == T_DOUBLE)) {
     __ unaligned_move(addr, reg);
   } else {
-    __ move(addr, reg);
+    if (dst_type == T_OBJECT && x->is_wide()) {
+      __ move_wide(addr, reg);
+    } else {
+      __ move(addr, reg);
+    }
   }
 }
 
@@ -2215,11 +2216,8 @@
   if (x->should_profile()) {
     ciMethod* method = x->profiled_method();
     assert(method != NULL, "method should be set if branch is profiled");
-    ciMethodData* md = method->method_data();
-    if (md == NULL) {
-      bailout("out of memory building methodDataOop");
-      return;
-    }
+    ciMethodData* md = method->method_data_or_null();
+    assert(md != NULL, "Sanity");
     ciProfileData* data = md->bci_to_data(x->profiled_bci());
     assert(data != NULL, "must have profiling data");
     int offset;
@@ -2287,7 +2285,7 @@
 
   if (compilation()->env()->dtrace_method_probes()) {
     BasicTypeList signature;
-    signature.append(T_INT);    // thread
+    signature.append(LP64_ONLY(T_LONG) NOT_LP64(T_INT));    // thread
     signature.append(T_OBJECT); // methodOop
     LIR_OprList* args = new LIR_OprList();
     args->append(getThreadPointer());
@@ -2352,11 +2350,14 @@
     } else {
       LIR_Address* addr = loc->as_address_ptr();
       param->load_for_store(addr->type());
-      if (addr->type() == T_LONG || addr->type() == T_DOUBLE) {
-        __ unaligned_move(param->result(), addr);
-      } else {
-        __ move(param->result(), addr);
-      }
+      if (addr->type() == T_OBJECT) {
+        __ move_wide(param->result(), addr);
+      } else
+        if (addr->type() == T_LONG || addr->type() == T_DOUBLE) {
+          __ unaligned_move(param->result(), addr);
+        } else {
+          __ move(param->result(), addr);
+        }
     }
   }
 
@@ -2368,7 +2369,7 @@
     } else {
       assert(loc->is_address(), "just checking");
       receiver->load_for_store(T_OBJECT);
-      __ move(receiver->result(), loc);
+      __ move_wide(receiver->result(), loc->as_address_ptr());
     }
   }
 }
@@ -2716,7 +2717,9 @@
   } else if (level == CompLevel_full_profile) {
     offset = in_bytes(backedge ? methodDataOopDesc::backedge_counter_offset() :
                                  methodDataOopDesc::invocation_counter_offset());
-    __ oop2reg(method->method_data()->constant_encoding(), counter_holder);
+    ciMethodData* md = method->method_data_or_null();
+    assert(md != NULL, "Sanity");
+    __ oop2reg(md->constant_encoding(), counter_holder);
     meth = new_register(T_OBJECT);
     __ oop2reg(method->constant_encoding(), meth);
   } else {
--- a/src/share/vm/c1/c1_LinearScan.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/c1/c1_LinearScan.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -1273,7 +1273,7 @@
   int caller_save_registers[LinearScan::nof_regs];
 
   int i;
-  for (i = 0; i < FrameMap::nof_caller_save_cpu_regs; i++) {
+  for (i = 0; i < FrameMap::nof_caller_save_cpu_regs(); i++) {
     LIR_Opr opr = FrameMap::caller_save_cpu_reg_at(i);
     assert(opr->is_valid() && opr->is_register(), "FrameMap should not return invalid operands");
     assert(reg_numHi(opr) == -1, "missing addition of range for hi-register");
@@ -3557,7 +3557,7 @@
 
     // invalidate all caller save registers at calls
     if (visitor.has_call()) {
-      for (j = 0; j < FrameMap::nof_caller_save_cpu_regs; j++) {
+      for (j = 0; j < FrameMap::nof_caller_save_cpu_regs(); j++) {
         state_put(input_state, reg_num(FrameMap::caller_save_cpu_reg_at(j)), NULL);
       }
       for (j = 0; j < FrameMap::nof_caller_save_fpu_regs; j++) {
@@ -5596,7 +5596,7 @@
     _last_reg = pd_last_fpu_reg;
   } else {
     _first_reg = pd_first_cpu_reg;
-    _last_reg = pd_last_cpu_reg;
+    _last_reg = FrameMap::last_cpu_reg();
   }
 
   assert(0 <= _first_reg && _first_reg < LinearScan::nof_regs, "out of range");
--- a/src/share/vm/c1/c1_Runtime1.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/c1/c1_Runtime1.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -1174,7 +1174,7 @@
     memmove(dst_addr, src_addr, length << l2es);
     return ac_ok;
   } else if (src->is_objArray() && dst->is_objArray()) {
-    if (UseCompressedOops) {  // will need for tiered
+    if (UseCompressedOops) {
       narrowOop *src_addr  = objArrayOop(src)->obj_at_addr<narrowOop>(src_pos);
       narrowOop *dst_addr  = objArrayOop(dst)->obj_at_addr<narrowOop>(dst_pos);
       return obj_arraycopy_work(src, src_addr, dst, dst_addr, length);
@@ -1210,10 +1210,11 @@
   assert(bs->has_write_ref_array_pre_opt(), "For pre-barrier as well.");
   if (UseCompressedOops) {
     bs->write_ref_array_pre((narrowOop*)dst, num);
+    Copy::conjoint_oops_atomic((narrowOop*) src, (narrowOop*) dst, num);
   } else {
     bs->write_ref_array_pre((oop*)dst, num);
+    Copy::conjoint_oops_atomic((oop*) src, (oop*) dst, num);
   }
-  Copy::conjoint_oops_atomic((oop*) src, (oop*) dst, num);
   bs->write_ref_array(dst, num);
 JRT_END
 
--- a/src/share/vm/ci/ciMethod.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/ci/ciMethod.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -797,12 +797,13 @@
 
 
 // ------------------------------------------------------------------
-// ciMethod::build_method_data
+// ciMethod::ensure_method_data
 //
 // Generate new methodDataOop objects at compile time.
-void ciMethod::build_method_data(methodHandle h_m) {
+// Return true if allocation was successful or no MDO is required.
+bool ciMethod::ensure_method_data(methodHandle h_m) {
   EXCEPTION_CONTEXT;
-  if (is_native() || is_abstract() || h_m()->is_accessor()) return;
+  if (is_native() || is_abstract() || h_m()->is_accessor()) return true;
   if (h_m()->method_data() == NULL) {
     methodOopDesc::build_interpreter_method_data(h_m, THREAD);
     if (HAS_PENDING_EXCEPTION) {
@@ -812,18 +813,22 @@
   if (h_m()->method_data() != NULL) {
     _method_data = CURRENT_ENV->get_object(h_m()->method_data())->as_method_data();
     _method_data->load_data();
+    return true;
   } else {
     _method_data = CURRENT_ENV->get_empty_methodData();
+    return false;
   }
 }
 
 // public, retroactive version
-void ciMethod::build_method_data() {
+bool ciMethod::ensure_method_data() {
+  bool result = true;
   if (_method_data == NULL || _method_data->is_empty()) {
     GUARDED_VM_ENTRY({
-      build_method_data(get_methodOop());
+      result = ensure_method_data(get_methodOop());
     });
   }
+  return result;
 }
 
 
@@ -839,11 +844,6 @@
   Thread* my_thread = JavaThread::current();
   methodHandle h_m(my_thread, get_methodOop());
 
-  // Create an MDO for the inlinee
-  if (TieredCompilation && is_c1_compile(env->comp_level())) {
-    build_method_data(h_m);
-  }
-
   if (h_m()->method_data() != NULL) {
     _method_data = CURRENT_ENV->get_object(h_m()->method_data())->as_method_data();
     _method_data->load_data();
@@ -854,6 +854,15 @@
 
 }
 
+// ------------------------------------------------------------------
+// ciMethod::method_data_or_null
+// Returns a pointer to ciMethodData if MDO exists on the VM side,
+// NULL otherwise.
+ciMethodData* ciMethod::method_data_or_null() {
+  ciMethodData *md = method_data();
+  if (md->is_empty()) return NULL;
+  return md;
+}
 
 // ------------------------------------------------------------------
 // ciMethod::will_link
--- a/src/share/vm/ci/ciMethod.hpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/ci/ciMethod.hpp	Thu Dec 16 20:48:11 2010 -0800
@@ -106,7 +106,7 @@
 
   void check_is_loaded() const                   { assert(is_loaded(), "not loaded"); }
 
-  void build_method_data(methodHandle h_m);
+  bool ensure_method_data(methodHandle h_m);
 
   void code_at_put(int bci, Bytecodes::Code code) {
     Bytecodes::check(code);
@@ -121,6 +121,7 @@
   ciSymbol* name() const                         { return _name; }
   ciInstanceKlass* holder() const                { return _holder; }
   ciMethodData* method_data();
+  ciMethodData* method_data_or_null();
 
   // Signature information.
   ciSignature* signature() const                 { return _signature; }
@@ -230,7 +231,7 @@
   bool has_unloaded_classes_in_signature();
   bool is_klass_loaded(int refinfo_index, bool must_be_resolved) const;
   bool check_call(int refinfo_index, bool is_static) const;
-  void build_method_data();  // make sure it exists in the VM also
+  bool ensure_method_data();  // make sure it exists in the VM also
   int scale_count(int count, float prof_factor = 1.);  // make MDO count commensurate with IIC
 
   // JSR 292 support
--- a/src/share/vm/classfile/classFileParser.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/classfile/classFileParser.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -99,12 +99,6 @@
   unsigned int hashValues[SymbolTable::symbol_alloc_batch_size];
   int names_count = 0;
 
-  // Side buffer for operands of variable-sized (InvokeDynamic) entries.
-  GrowableArray<int>* operands = NULL;
-#ifdef ASSERT
-  GrowableArray<int>* indy_instructions = new GrowableArray<int>(THREAD, 10);
-#endif
-
   // parsing  Index 0 is unused
   for (int index = 1; index < length; index++) {
     // Each of the following case guarantees one more byte in the stream
@@ -184,36 +178,20 @@
                "Class file version does not support constant tag %u in class file %s"),
               tag, CHECK);
           }
-          if (!AllowTransitionalJSR292 && tag == JVM_CONSTANT_InvokeDynamicTrans) {
-            classfile_parse_error(
+          cfs->guarantee_more(5, CHECK);  // bsm_index, nt, tag/access_flags
+          u2 bootstrap_specifier_index = cfs->get_u2_fast();
+          u2 name_and_type_index = cfs->get_u2_fast();
+          if (tag == JVM_CONSTANT_InvokeDynamicTrans) {
+            if (!AllowTransitionalJSR292)
+              classfile_parse_error(
                 "This JVM does not support transitional InvokeDynamic tag %u in class file %s",
                 tag, CHECK);
+            cp->invoke_dynamic_trans_at_put(index, bootstrap_specifier_index, name_and_type_index);
+            break;
           }
-          bool trans_no_argc = AllowTransitionalJSR292 && (tag == JVM_CONSTANT_InvokeDynamicTrans);
-          cfs->guarantee_more(7, CHECK);  // bsm_index, nt, argc, ..., tag/access_flags
-          u2 bootstrap_method_index = cfs->get_u2_fast();
-          u2 name_and_type_index = cfs->get_u2_fast();
-          int argument_count = trans_no_argc ? 0 : cfs->get_u2_fast();
-          cfs->guarantee_more(2*argument_count + 1, CHECK);  // argv[argc]..., tag/access_flags
-          int argv_offset = constantPoolOopDesc::_indy_argv_offset;
-          int op_count = argv_offset + argument_count;  // bsm, nt, argc, argv[]...
-          int op_base = start_operand_group(operands, op_count, CHECK);
-          assert(argv_offset == 3, "else adjust next 3 assignments");
-          operands->at_put(op_base + constantPoolOopDesc::_indy_bsm_offset, bootstrap_method_index);
-          operands->at_put(op_base + constantPoolOopDesc::_indy_nt_offset, name_and_type_index);
-          operands->at_put(op_base + constantPoolOopDesc::_indy_argc_offset, argument_count);
-          for (int arg_i = 0; arg_i < argument_count; arg_i++) {
-            int arg = cfs->get_u2_fast();
-            operands->at_put(op_base + constantPoolOopDesc::_indy_argv_offset + arg_i, arg);
-          }
-          cp->invoke_dynamic_at_put(index, op_base, op_count);
-#ifdef ASSERT
-          // Record the steps just taken for later checking.
-          indy_instructions->append(index);
-          indy_instructions->append(bootstrap_method_index);
-          indy_instructions->append(name_and_type_index);
-          indy_instructions->append(argument_count);
-#endif //ASSERT
+          if (_max_bootstrap_specifier_index < (int) bootstrap_specifier_index)
+            _max_bootstrap_specifier_index = (int) bootstrap_specifier_index;  // collect for later
+          cp->invoke_dynamic_at_put(index, bootstrap_specifier_index, name_and_type_index);
         }
         break;
       case JVM_CONSTANT_Integer :
@@ -316,23 +294,6 @@
     oopFactory::new_symbols(cp, names_count, names, lengths, indices, hashValues, CHECK);
   }
 
-  if (operands != NULL && operands->length() > 0) {
-    store_operand_array(operands, cp, CHECK);
-  }
-#ifdef ASSERT
-  // Re-assert the indy structures, now that assertion checking can work.
-  for (int indy_i = 0; indy_i < indy_instructions->length(); ) {
-    int index                  = indy_instructions->at(indy_i++);
-    int bootstrap_method_index = indy_instructions->at(indy_i++);
-    int name_and_type_index    = indy_instructions->at(indy_i++);
-    int argument_count         = indy_instructions->at(indy_i++);
-    assert(cp->check_invoke_dynamic_at(index,
-                                       bootstrap_method_index, name_and_type_index,
-                                       argument_count),
-           "indy structure is OK");
-  }
-#endif //ASSERT
-
   // Copy _current pointer of local copy back to stream().
 #ifdef ASSERT
   assert(cfs0->current() == old_current, "non-exclusive use of stream()");
@@ -340,41 +301,6 @@
   cfs0->set_current(cfs1.current());
 }
 
-int ClassFileParser::start_operand_group(GrowableArray<int>* &operands, int op_count, TRAPS) {
-  if (operands == NULL) {
-    operands = new GrowableArray<int>(THREAD, 100);
-    int fillp_offset = constantPoolOopDesc::_multi_operand_buffer_fill_pointer_offset;
-    while (operands->length() <= fillp_offset)
-      operands->append(0);  // force op_base > 0, for an error check
-    DEBUG_ONLY(operands->at_put(fillp_offset, (int)badHeapWordVal));
-  }
-  int cnt_pos = operands->append(op_count);
-  int arg_pos = operands->length();
-  operands->at_grow(arg_pos + op_count - 1);  // grow to include the operands
-  assert(operands->length() == arg_pos + op_count, "");
-  int op_base = cnt_pos - constantPoolOopDesc::_multi_operand_count_offset;
-  return op_base;
-}
-
-void ClassFileParser::store_operand_array(GrowableArray<int>* operands, constantPoolHandle cp, TRAPS) {
-  // Collect the buffer of operands from variable-sized entries into a permanent array.
-  int arraylen = operands->length();
-  int fillp_offset = constantPoolOopDesc::_multi_operand_buffer_fill_pointer_offset;
-  assert(operands->at(fillp_offset) == (int)badHeapWordVal, "value unused so far");
-  operands->at_put(fillp_offset, arraylen);
-  cp->multi_operand_buffer_grow(arraylen, CHECK);
-  typeArrayOop operands_oop = cp->operands();
-  assert(operands_oop->length() == arraylen, "");
-  for (int i = 0; i < arraylen; i++) {
-    operands_oop->int_at_put(i, operands->at(i));
-  }
-  cp->set_operands(operands_oop);
-  // The fill_pointer is used only by constantPoolOop::copy_entry_to and friends,
-  // when constant pools need to be merged.  Make sure it is sane now.
-  assert(cp->multi_operand_buffer_fill_pointer() == arraylen, "");
-}
-
-
 bool inline valid_cp_range(int index, int length) { return (index > 0 && index < length); }
 
 constantPoolHandle ClassFileParser::parse_constant_pool(TRAPS) {
@@ -401,7 +327,8 @@
 
   // first verification pass - validate cross references and fixup class and string constants
   for (index = 1; index < length; index++) {          // Index 0 is unused
-    switch (cp->tag_at(index).value()) {
+    jbyte tag = cp->tag_at(index).value();
+    switch (tag) {
       case JVM_CONSTANT_Class :
         ShouldNotReachHere();     // Only JVM_CONSTANT_ClassIndex should be present
         break;
@@ -543,35 +470,23 @@
         }
         break;
       case JVM_CONSTANT_InvokeDynamicTrans :
-        ShouldNotReachHere();  // this tag does not appear in the heap
       case JVM_CONSTANT_InvokeDynamic :
         {
-          int bootstrap_method_ref_index = cp->invoke_dynamic_bootstrap_method_ref_index_at(index);
           int name_and_type_ref_index = cp->invoke_dynamic_name_and_type_ref_index_at(index);
-          check_property((bootstrap_method_ref_index == 0 && AllowTransitionalJSR292)
-                         ||
-                         (valid_cp_range(bootstrap_method_ref_index, length) &&
-                          (cp->tag_at(bootstrap_method_ref_index).is_method_handle())),
-                         "Invalid constant pool index %u in class file %s",
-                         bootstrap_method_ref_index,
-                         CHECK_(nullHandle));
           check_property(valid_cp_range(name_and_type_ref_index, length) &&
                          cp->tag_at(name_and_type_ref_index).is_name_and_type(),
                          "Invalid constant pool index %u in class file %s",
                          name_and_type_ref_index,
                          CHECK_(nullHandle));
-          int argc = cp->invoke_dynamic_argument_count_at(index);
-          for (int arg_i = 0; arg_i < argc; arg_i++) {
-            int arg = cp->invoke_dynamic_argument_index_at(index, arg_i);
-            check_property(valid_cp_range(arg, length) &&
-                           cp->tag_at(arg).is_loadable_constant() ||
-                           // temporary early forms of string and class:
-                           cp->tag_at(arg).is_klass_index() ||
-                           cp->tag_at(arg).is_string_index(),
+          if (tag == JVM_CONSTANT_InvokeDynamicTrans) {
+            int bootstrap_method_ref_index = cp->invoke_dynamic_bootstrap_method_ref_index_at(index);
+            check_property(valid_cp_range(bootstrap_method_ref_index, length) &&
+                           cp->tag_at(bootstrap_method_ref_index).is_method_handle(),
                            "Invalid constant pool index %u in class file %s",
-                           arg,
+                           bootstrap_method_ref_index,
                            CHECK_(nullHandle));
           }
+          // bootstrap specifier index must be checked later, when BootstrapMethods attr is available
           break;
         }
       default:
@@ -2429,6 +2344,76 @@
   k->set_generic_signature(cp->symbol_at(signature_index));
 }
 
+void ClassFileParser::parse_classfile_bootstrap_methods_attribute(constantPoolHandle cp, instanceKlassHandle k,
+                                                                  u4 attribute_byte_length, TRAPS) {
+  ClassFileStream* cfs = stream();
+  u1* current_start = cfs->current();
+
+  cfs->guarantee_more(2, CHECK);  // length
+  int attribute_array_length = cfs->get_u2_fast();
+
+  guarantee_property(_max_bootstrap_specifier_index < attribute_array_length,
+                     "Short length on BootstrapMethods in class file %s",
+                     CHECK);
+
+  // The attribute contains a counted array of counted tuples of shorts,
+  // represending bootstrap specifiers:
+  //    length*{bootstrap_method_index, argument_count*{argument_index}}
+  int operand_count = (attribute_byte_length - sizeof(u2)) / sizeof(u2);
+  // operand_count = number of shorts in attr, except for leading length
+
+  // The attribute is copied into a short[] array.
+  // The array begins with a series of short[2] pairs, one for each tuple.
+  int index_size = (attribute_array_length * 2);
+
+  typeArrayOop operands_oop = oopFactory::new_permanent_intArray(index_size + operand_count, CHECK);
+  typeArrayHandle operands(THREAD, operands_oop);
+  operands_oop = NULL; // tidy
+
+  int operand_fill_index = index_size;
+  int cp_size = cp->length();
+
+  for (int n = 0; n < attribute_array_length; n++) {
+    // Store a 32-bit offset into the header of the operand array.
+    assert(constantPoolOopDesc::operand_offset_at(operands(), n) == 0, "");
+    constantPoolOopDesc::operand_offset_at_put(operands(), n, operand_fill_index);
+
+    // Read a bootstrap specifier.
+    cfs->guarantee_more(sizeof(u2) * 2, CHECK);  // bsm, argc
+    u2 bootstrap_method_index = cfs->get_u2_fast();
+    u2 argument_count = cfs->get_u2_fast();
+    check_property(
+      valid_cp_range(bootstrap_method_index, cp_size) &&
+      cp->tag_at(bootstrap_method_index).is_method_handle(),
+      "bootstrap_method_index %u has bad constant type in class file %s",
+      CHECK);
+    operands->short_at_put(operand_fill_index++, bootstrap_method_index);
+    operands->short_at_put(operand_fill_index++, argument_count);
+
+    cfs->guarantee_more(sizeof(u2) * argument_count, CHECK);  // argv[argc]
+    for (int j = 0; j < argument_count; j++) {
+      u2 arg_index = cfs->get_u2_fast();
+      check_property(
+        valid_cp_range(arg_index, cp_size) &&
+        cp->tag_at(arg_index).is_loadable_constant(),
+        "argument_index %u has bad constant type in class file %s",
+        CHECK);
+      operands->short_at_put(operand_fill_index++, arg_index);
+    }
+  }
+
+  assert(operand_fill_index == operands()->length(), "exact fill");
+  assert(constantPoolOopDesc::operand_array_length(operands()) == attribute_array_length, "correct decode");
+
+  u1* current_end = cfs->current();
+  guarantee_property(current_end == current_start + attribute_byte_length,
+                     "Bad length on BootstrapMethods in class file %s",
+                     CHECK);
+
+  cp->set_operands(operands());
+}
+
+
 void ClassFileParser::parse_classfile_attributes(constantPoolHandle cp, instanceKlassHandle k, TRAPS) {
   ClassFileStream* cfs = stream();
   // Set inner classes attribute to default sentinel
@@ -2438,6 +2423,7 @@
   bool parsed_sourcefile_attribute = false;
   bool parsed_innerclasses_attribute = false;
   bool parsed_enclosingmethod_attribute = false;
+  bool parsed_bootstrap_methods_attribute = false;
   u1* runtime_visible_annotations = NULL;
   int runtime_visible_annotations_length = 0;
   u1* runtime_invisible_annotations = NULL;
@@ -2536,6 +2522,12 @@
           classfile_parse_error("Invalid or out-of-bounds method index in EnclosingMethod attribute in class file %s", CHECK);
         }
         k->set_enclosing_method_indices(class_index, method_index);
+      } else if (tag == vmSymbols::tag_bootstrap_methods() &&
+                 _major_version >= Verifier::INVOKEDYNAMIC_MAJOR_VERSION) {
+        if (parsed_bootstrap_methods_attribute)
+          classfile_parse_error("Multiple BootstrapMethods attributes in class file %s", CHECK);
+        parsed_bootstrap_methods_attribute = true;
+        parse_classfile_bootstrap_methods_attribute(cp, k, attribute_length, CHECK);
       } else {
         // Unknown attribute
         cfs->skip_u1(attribute_length, CHECK);
@@ -2551,6 +2543,11 @@
                                                      runtime_invisible_annotations_length,
                                                      CHECK);
   k->set_class_annotations(annotations());
+
+  if (_max_bootstrap_specifier_index >= 0) {
+    guarantee_property(parsed_bootstrap_methods_attribute,
+                       "Missing BootstrapMethods attribute in class file %s", CHECK);
+  }
 }
 
 
@@ -2868,6 +2865,7 @@
                             PerfClassTraceTime::PARSE_CLASS);
 
   _has_finalizer = _has_empty_finalizer = _has_vanilla_constructor = false;
+  _max_bootstrap_specifier_index = -1;
 
   if (JvmtiExport::should_post_class_file_load_hook()) {
     unsigned char* ptr = cfs->buffer();
--- a/src/share/vm/classfile/classFileParser.hpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/classfile/classFileParser.hpp	Thu Dec 16 20:48:11 2010 -0800
@@ -50,6 +50,8 @@
   bool _has_empty_finalizer;
   bool _has_vanilla_constructor;
 
+  int _max_bootstrap_specifier_index;
+
   enum { fixed_buffer_size = 128 };
   u_char linenumbertable_buffer[fixed_buffer_size];
 
@@ -66,9 +68,6 @@
 
   constantPoolHandle parse_constant_pool(TRAPS);
 
-  static int start_operand_group(GrowableArray<int>* &operands, int op_count, TRAPS);
-  static void store_operand_array(GrowableArray<int>* operands, constantPoolHandle cp, TRAPS);
-
   // Interface parsing
   objArrayHandle parse_interfaces(constantPoolHandle cp,
                                   int length,
@@ -130,6 +129,7 @@
   void parse_classfile_attributes(constantPoolHandle cp, instanceKlassHandle k, TRAPS);
   void parse_classfile_synthetic_attribute(constantPoolHandle cp, instanceKlassHandle k, TRAPS);
   void parse_classfile_signature_attribute(constantPoolHandle cp, instanceKlassHandle k, TRAPS);
+  void parse_classfile_bootstrap_methods_attribute(constantPoolHandle cp, instanceKlassHandle k, u4 attribute_length, TRAPS);
 
   // Annotations handling
   typeArrayHandle assemble_annotations(u1* runtime_visible_annotations,
--- a/src/share/vm/classfile/systemDictionary.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/classfile/systemDictionary.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -2010,7 +2010,7 @@
     scan = WKID(meth_group_end+1);
   }
   WKID indy_group_start = WK_KLASS_ENUM_NAME(Linkage_klass);
-  WKID indy_group_end   = WK_KLASS_ENUM_NAME(InvokeDynamic_klass);
+  WKID indy_group_end   = WK_KLASS_ENUM_NAME(CallSite_klass);
   initialize_wk_klasses_until(indy_group_start, scan, CHECK);
   if (EnableInvokeDynamic) {
     initialize_wk_klasses_through(indy_group_end, scan, CHECK);
--- a/src/share/vm/classfile/systemDictionary.hpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/classfile/systemDictionary.hpp	Thu Dec 16 20:48:11 2010 -0800
@@ -156,8 +156,7 @@
   template(WrongMethodTypeException_klass, java_dyn_WrongMethodTypeException, Opt) \
   template(Linkage_klass,                java_dyn_Linkage,               Opt) \
   template(CallSite_klass,               java_dyn_CallSite,              Opt) \
-  template(InvokeDynamic_klass,          java_dyn_InvokeDynamic,         Opt) \
-  /* Note: MethodHandle must be first, and InvokeDynamic last in group */     \
+  /* Note: MethodHandle must be first, and CallSite last in group */          \
                                                                               \
   template(StringBuffer_klass,           java_lang_StringBuffer,         Pre) \
   template(StringBuilder_klass,          java_lang_StringBuilder,        Pre) \
--- a/src/share/vm/classfile/vmSymbols.hpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/classfile/vmSymbols.hpp	Thu Dec 16 20:48:11 2010 -0800
@@ -132,6 +132,7 @@
   template(tag_runtime_invisible_parameter_annotations,"RuntimeInvisibleParameterAnnotations")    \
   template(tag_annotation_default,                    "AnnotationDefault")                        \
   template(tag_enclosing_method,                      "EnclosingMethod")                          \
+  template(tag_bootstrap_methods,                     "BootstrapMethods")                         \
                                                                                                   \
   /* exception klasses: at least all exceptions thrown by the VM have entries here */             \
   template(java_lang_ArithmeticException,             "java/lang/ArithmeticException")            \
--- a/src/share/vm/code/compressedStream.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/code/compressedStream.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -197,6 +197,7 @@
 // compiler stack overflow is fixed.
 #if _MSC_VER >=1400 && !defined(_WIN64)
 #pragma optimize("", off)
+#pragma warning(disable: 4748)
 #endif
 
 // generator for an "interesting" set of critical values
@@ -276,6 +277,7 @@
 }
 
 #if _MSC_VER >=1400 && !defined(_WIN64)
+#pragma warning(default: 4748)
 #pragma optimize("", on)
 #endif
 
--- a/src/share/vm/code/nmethod.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/code/nmethod.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -619,8 +619,8 @@
   OopMapSet* oop_maps )
   : CodeBlob("native nmethod", code_buffer, sizeof(nmethod),
              nmethod_size, offsets->value(CodeOffsets::Frame_Complete), frame_size, oop_maps),
-  _compiled_synchronized_native_basic_lock_owner_sp_offset(basic_lock_owner_sp_offset),
-  _compiled_synchronized_native_basic_lock_sp_offset(basic_lock_sp_offset)
+  _native_receiver_sp_offset(basic_lock_owner_sp_offset),
+  _native_basic_lock_sp_offset(basic_lock_sp_offset)
 {
   {
     debug_only(No_Safepoint_Verifier nsv;)
@@ -696,8 +696,8 @@
   int frame_size)
   : CodeBlob("dtrace nmethod", code_buffer, sizeof(nmethod),
              nmethod_size, offsets->value(CodeOffsets::Frame_Complete), frame_size, NULL),
-  _compiled_synchronized_native_basic_lock_owner_sp_offset(in_ByteSize(-1)),
-  _compiled_synchronized_native_basic_lock_sp_offset(in_ByteSize(-1))
+  _native_receiver_sp_offset(in_ByteSize(-1)),
+  _native_basic_lock_sp_offset(in_ByteSize(-1))
 {
   {
     debug_only(No_Safepoint_Verifier nsv;)
@@ -790,8 +790,8 @@
   )
   : CodeBlob("nmethod", code_buffer, sizeof(nmethod),
              nmethod_size, offsets->value(CodeOffsets::Frame_Complete), frame_size, oop_maps),
-  _compiled_synchronized_native_basic_lock_owner_sp_offset(in_ByteSize(-1)),
-  _compiled_synchronized_native_basic_lock_sp_offset(in_ByteSize(-1))
+  _native_receiver_sp_offset(in_ByteSize(-1)),
+  _native_basic_lock_sp_offset(in_ByteSize(-1))
 {
   assert(debug_info->oop_recorder() == code_buffer->oop_recorder(), "shared OR");
   {
--- a/src/share/vm/code/nmethod.hpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/code/nmethod.hpp	Thu Dec 16 20:48:11 2010 -0800
@@ -210,7 +210,7 @@
   ExceptionCache *_exception_cache;
   PcDescCache     _pc_desc_cache;
 
-  // These are only used for compiled synchronized native methods to
+  // These are used for compiled synchronized native methods to
   // locate the owner and stack slot for the BasicLock so that we can
   // properly revoke the bias of the owner if necessary. They are
   // needed because there is no debug information for compiled native
@@ -220,8 +220,10 @@
   // sharing between platforms. Note that currently biased locking
   // will never cause Class instances to be biased but this code
   // handles the static synchronized case as well.
-  ByteSize _compiled_synchronized_native_basic_lock_owner_sp_offset;
-  ByteSize _compiled_synchronized_native_basic_lock_sp_offset;
+  // JVMTI's GetLocalInstance() also uses these offsets to find the receiver
+  // for non-static native wrapper frames.
+  ByteSize _native_receiver_sp_offset;
+  ByteSize _native_basic_lock_sp_offset;
 
   friend class nmethodLocker;
 
@@ -676,11 +678,11 @@
   bool is_patchable_at(address instr_address);
 
   // UseBiasedLocking support
-  ByteSize compiled_synchronized_native_basic_lock_owner_sp_offset() {
-    return _compiled_synchronized_native_basic_lock_owner_sp_offset;
+  ByteSize native_receiver_sp_offset() {
+    return _native_receiver_sp_offset;
   }
-  ByteSize compiled_synchronized_native_basic_lock_sp_offset() {
-    return _compiled_synchronized_native_basic_lock_sp_offset;
+  ByteSize native_basic_lock_sp_offset() {
+    return _native_basic_lock_sp_offset;
   }
 
   // support for code generation
--- a/src/share/vm/code/relocInfo.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/code/relocInfo.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -1093,8 +1093,8 @@
     tty->print_cr("(no relocs)");
     return;
   }
-  tty->print("relocInfo@" INTPTR_FORMAT " [type=%d(%s) addr=" INTPTR_FORMAT,
-             _current, type(), reloc_type_string((relocInfo::relocType) type()), _addr);
+  tty->print("relocInfo@" INTPTR_FORMAT " [type=%d(%s) addr=" INTPTR_FORMAT " offset=%d",
+             _current, type(), reloc_type_string((relocInfo::relocType) type()), _addr, _current->addr_offset());
   if (current()->format() != 0)
     tty->print(" format=%d", current()->format());
   if (datalen() == 1) {
--- a/src/share/vm/compiler/disassembler.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/compiler/disassembler.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -466,5 +466,18 @@
     env.set_total_ticks(total_bucket_count);
   }
 
+  // Print constant table.
+  if (nm->consts_size() > 0) {
+    nm->print_nmethod_labels(env.output(), nm->consts_begin());
+    int offset = 0;
+    for (address p = nm->consts_begin(); p < nm->consts_end(); p += 4, offset += 4) {
+      if ((offset % 8) == 0) {
+        env.output()->print_cr("  " INTPTR_FORMAT " (offset: %4d): " PTR32_FORMAT "   " PTR64_FORMAT, (intptr_t) p, offset, *((int32_t*) p), *((int64_t*) p));
+      } else {
+        env.output()->print_cr("  " INTPTR_FORMAT " (offset: %4d): " PTR32_FORMAT,                    (intptr_t) p, offset, *((int32_t*) p));
+      }
+    }
+  }
+
   env.decode_instructions(p, end);
 }
--- a/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -277,7 +277,9 @@
     // completed. This will also notify the FullGCCount_lock in case a
     // Java thread is waiting for a full GC to happen (e.g., it
     // called System.gc() with +ExplicitGCInvokesConcurrent).
-    g1->increment_full_collections_completed(true /* outer */);
+    _sts.join();
+    g1->increment_full_collections_completed(true /* concurrent */);
+    _sts.leave();
   }
   assert(_should_terminate, "just checking");
 
--- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -1389,7 +1389,7 @@
   }
 
   // Update the number of full collections that have been completed.
-  increment_full_collections_completed(false /* outer */);
+  increment_full_collections_completed(false /* concurrent */);
 
   if (PrintHeapAtGC) {
     Universe::print_heap_after_gc();
@@ -2176,9 +2176,14 @@
      (cause == GCCause::_java_lang_system_gc && ExplicitGCInvokesConcurrent));
 }
 
-void G1CollectedHeap::increment_full_collections_completed(bool outer) {
+void G1CollectedHeap::increment_full_collections_completed(bool concurrent) {
   MonitorLockerEx x(FullGCCount_lock, Mutex::_no_safepoint_check_flag);
 
+  // We assume that if concurrent == true, then the caller is a
+  // concurrent thread that was joined the Suspendible Thread
+  // Set. If there's ever a cheap way to check this, we should add an
+  // assert here.
+
   // We have already incremented _total_full_collections at the start
   // of the GC, so total_full_collections() represents how many full
   // collections have been started.
@@ -2192,17 +2197,18 @@
   // behind the number of full collections started.
 
   // This is the case for the inner caller, i.e. a Full GC.
-  assert(outer ||
+  assert(concurrent ||
          (full_collections_started == _full_collections_completed + 1) ||
          (full_collections_started == _full_collections_completed + 2),
-         err_msg("for inner caller: full_collections_started = %u "
+         err_msg("for inner caller (Full GC): full_collections_started = %u "
                  "is inconsistent with _full_collections_completed = %u",
                  full_collections_started, _full_collections_completed));
 
   // This is the case for the outer caller, i.e. the concurrent cycle.
-  assert(!outer ||
+  assert(!concurrent ||
          (full_collections_started == _full_collections_completed + 1),
-         err_msg("for outer caller: full_collections_started = %u "
+         err_msg("for outer caller (concurrent cycle): "
+                 "full_collections_started = %u "
                  "is inconsistent with _full_collections_completed = %u",
                  full_collections_started, _full_collections_completed));
 
@@ -2212,7 +2218,7 @@
   // we wake up any waiters (especially when ExplicitInvokesConcurrent
   // is set) so that if a waiter requests another System.gc() it doesn't
   // incorrectly see that a marking cyle is still in progress.
-  if (outer) {
+  if (concurrent) {
     _cmThread->clear_in_progress();
   }
 
--- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Thu Dec 16 20:48:11 2010 -0800
@@ -643,16 +643,16 @@
   // can happen in a nested fashion, i.e., we start a concurrent
   // cycle, a Full GC happens half-way through it which ends first,
   // and then the cycle notices that a Full GC happened and ends
-  // too. The outer parameter is a boolean to help us do a bit tighter
-  // consistency checking in the method. If outer is false, the caller
-  // is the inner caller in the nesting (i.e., the Full GC). If outer
-  // is true, the caller is the outer caller in this nesting (i.e.,
-  // the concurrent cycle). Further nesting is not currently
-  // supported. The end of the this call also notifies the
-  // FullGCCount_lock in case a Java thread is waiting for a full GC
-  // to happen (e.g., it called System.gc() with
+  // too. The concurrent parameter is a boolean to help us do a bit
+  // tighter consistency checking in the method. If concurrent is
+  // false, the caller is the inner caller in the nesting (i.e., the
+  // Full GC). If concurrent is true, the caller is the outer caller
+  // in this nesting (i.e., the concurrent cycle). Further nesting is
+  // not currently supported. The end of the this call also notifies
+  // the FullGCCount_lock in case a Java thread is waiting for a full
+  // GC to happen (e.g., it called System.gc() with
   // +ExplicitGCInvokesConcurrent).
-  void increment_full_collections_completed(bool outer);
+  void increment_full_collections_completed(bool concurrent);
 
   unsigned int full_collections_completed() {
     return _full_collections_completed;
--- a/src/share/vm/interpreter/bytecodeTracer.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/interpreter/bytecodeTracer.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -346,6 +346,7 @@
     break;
   case JVM_CONSTANT_NameAndType:
   case JVM_CONSTANT_InvokeDynamic:
+  case JVM_CONSTANT_InvokeDynamicTrans:
     has_klass = false;
     break;
   default:
--- a/src/share/vm/interpreter/rewriter.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/interpreter/rewriter.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -52,6 +52,7 @@
       case JVM_CONSTANT_MethodHandle      : // fall through
       case JVM_CONSTANT_MethodType        : // fall through
       case JVM_CONSTANT_InvokeDynamic     : // fall through
+      case JVM_CONSTANT_InvokeDynamicTrans: // fall through
         add_cp_cache_entry(i);
         break;
     }
@@ -61,6 +62,7 @@
             "all cp cache indexes fit in a u2");
 
   _have_invoke_dynamic = ((tag_mask & (1 << JVM_CONSTANT_InvokeDynamic)) != 0);
+  _have_invoke_dynamic |= ((tag_mask & (1 << JVM_CONSTANT_InvokeDynamicTrans)) != 0);
 }
 
 
@@ -74,7 +76,7 @@
       oopFactory::new_constantPoolCache(length, methodOopDesc::IsUnsafeConc, CHECK);
   cache->initialize(_cp_cache_map);
 
-  // Don't bother to the next pass if there is no JVM_CONSTANT_InvokeDynamic.
+  // Don't bother with the next pass if there is no JVM_CONSTANT_InvokeDynamic.
   if (_have_invoke_dynamic) {
     for (int i = 0; i < length; i++) {
       int pool_index = cp_cache_entry_pool_index(i);
--- a/src/share/vm/memory/allocation.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/memory/allocation.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -73,7 +73,7 @@
 void ResourceObj::operator delete(void* p) {
   assert(((ResourceObj *)p)->allocated_on_C_heap(),
          "delete only allowed for C_HEAP objects");
-  DEBUG_ONLY(((ResourceObj *)p)->_allocation = (uintptr_t)badHeapOopVal;)
+  DEBUG_ONLY(((ResourceObj *)p)->_allocation_t[0] = (uintptr_t)badHeapOopVal;)
   FreeHeap(p);
 }
 
@@ -83,43 +83,73 @@
     uintptr_t allocation = (uintptr_t)res;
     assert((allocation & allocation_mask) == 0, "address should be aligned to 4 bytes at least");
     assert(type <= allocation_mask, "incorrect allocation type");
-    ((ResourceObj *)res)->_allocation = ~(allocation + type);
+    ResourceObj* resobj = (ResourceObj *)res;
+    resobj->_allocation_t[0] = ~(allocation + type);
+    if (type != STACK_OR_EMBEDDED) {
+      // Called from operator new() and CollectionSetChooser(),
+      // set verification value.
+      resobj->_allocation_t[1] = (uintptr_t)&(resobj->_allocation_t[1]) + type;
+    }
 }
 
 ResourceObj::allocation_type ResourceObj::get_allocation_type() const {
-    assert(~(_allocation | allocation_mask) == (uintptr_t)this, "lost resource object");
-    return (allocation_type)((~_allocation) & allocation_mask);
+    assert(~(_allocation_t[0] | allocation_mask) == (uintptr_t)this, "lost resource object");
+    return (allocation_type)((~_allocation_t[0]) & allocation_mask);
+}
+
+bool ResourceObj::is_type_set() const {
+    allocation_type type = (allocation_type)(_allocation_t[1] & allocation_mask);
+    return get_allocation_type()  == type &&
+           (_allocation_t[1] - type) == (uintptr_t)(&_allocation_t[1]);
 }
 
 ResourceObj::ResourceObj() { // default constructor
-    if (~(_allocation | allocation_mask) != (uintptr_t)this) {
+    if (~(_allocation_t[0] | allocation_mask) != (uintptr_t)this) {
+      // Operator new() is not called for allocations
+      // on stack and for embedded objects.
       set_allocation_type((address)this, STACK_OR_EMBEDDED);
-    } else if (allocated_on_stack()) {
-      // For some reason we got a value which looks like an allocation on stack.
-      // Pass if it is really allocated on stack.
-      assert(Thread::current()->on_local_stack((address)this),"should be on stack");
+    } else if (allocated_on_stack()) { // STACK_OR_EMBEDDED
+      // For some reason we got a value which resembles
+      // an embedded or stack object (operator new() does not
+      // set such type). Keep it since it is valid value
+      // (even if it was garbage).
+      // Ignore garbage in other fields.
+    } else if (is_type_set()) {
+      // Operator new() was called and type was set.
+      assert(!allocated_on_stack(),
+             err_msg("not embedded or stack, this(" PTR_FORMAT ") type %d a[0]=(" PTR_FORMAT ") a[1]=(" PTR_FORMAT ")",
+                     this, get_allocation_type(), _allocation_t[0], _allocation_t[1]));
     } else {
-      assert(allocated_on_res_area() || allocated_on_C_heap() || allocated_on_arena(),
-             "allocation_type should be set by operator new()");
+      // Operator new() was not called.
+      // Assume that it is embedded or stack object.
+      set_allocation_type((address)this, STACK_OR_EMBEDDED);
     }
+    _allocation_t[1] = 0; // Zap verification value
 }
 
 ResourceObj::ResourceObj(const ResourceObj& r) { // default copy constructor
     // Used in ClassFileParser::parse_constant_pool_entries() for ClassFileStream.
+    // Note: garbage may resembles valid value.
+    assert(~(_allocation_t[0] | allocation_mask) != (uintptr_t)this || !is_type_set(),
+           err_msg("embedded or stack only, this(" PTR_FORMAT ") type %d a[0]=(" PTR_FORMAT ") a[1]=(" PTR_FORMAT ")",
+                   this, get_allocation_type(), _allocation_t[0], _allocation_t[1]));
     set_allocation_type((address)this, STACK_OR_EMBEDDED);
+    _allocation_t[1] = 0; // Zap verification value
 }
 
 ResourceObj& ResourceObj::operator=(const ResourceObj& r) { // default copy assignment
     // Used in InlineTree::ok_to_inline() for WarmCallInfo.
-    assert(allocated_on_stack(), "copy only into local");
-    // Keep current _allocation value;
+    assert(allocated_on_stack(),
+           err_msg("copy only into local, this(" PTR_FORMAT ") type %d a[0]=(" PTR_FORMAT ") a[1]=(" PTR_FORMAT ")",
+                   this, get_allocation_type(), _allocation_t[0], _allocation_t[1]));
+    // Keep current _allocation_t value;
     return *this;
 }
 
 ResourceObj::~ResourceObj() {
     // allocated_on_C_heap() also checks that encoded (in _allocation) address == this.
-    if (!allocated_on_C_heap()) {  // ResourceObj::delete() zaps _allocation for C_heap.
-      _allocation = (uintptr_t)badHeapOopVal; // zap type
+    if (!allocated_on_C_heap()) { // ResourceObj::delete() will zap _allocation for C_heap.
+      _allocation_t[0] = (uintptr_t)badHeapOopVal; // zap type
     }
 }
 #endif // ASSERT
--- a/src/share/vm/memory/allocation.hpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/memory/allocation.hpp	Thu Dec 16 20:48:11 2010 -0800
@@ -337,7 +337,9 @@
   // When this object is allocated on stack the new() operator is not
   // called but garbage on stack may look like a valid allocation_type.
   // Store negated 'this' pointer when new() is called to distinguish cases.
-  uintptr_t _allocation;
+  // Use second array's element for verification value to distinguish garbage.
+  uintptr_t _allocation_t[2];
+  bool is_type_set() const;
  public:
   allocation_type get_allocation_type() const;
   bool allocated_on_stack()    const { return get_allocation_type() == STACK_OR_EMBEDDED; }
--- a/src/share/vm/oops/constantPoolKlass.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/oops/constantPoolKlass.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -399,6 +399,7 @@
       case JVM_CONSTANT_MethodType :
         st->print("signature_index=%d", cp->method_type_index_at(index));
         break;
+      case JVM_CONSTANT_InvokeDynamicTrans :
       case JVM_CONSTANT_InvokeDynamic :
         {
           st->print("bootstrap_method_index=%d", cp->invoke_dynamic_bootstrap_method_ref_index_at(index));
--- a/src/share/vm/oops/constantPoolOop.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/oops/constantPoolOop.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -915,7 +915,8 @@
   {
     int k1 = method_type_index_at(index1);
     int k2 = cp2->method_type_index_at(index2);
-    if (k1 == k2) {
+    bool match = compare_entry_to(k1, cp2, k2, CHECK_false);
+    if (match) {
       return true;
     }
   } break;
@@ -927,28 +928,33 @@
     if (k1 == k2) {
       int i1 = method_handle_index_at(index1);
       int i2 = cp2->method_handle_index_at(index2);
-      if (i1 == i2) {
+      bool match = compare_entry_to(i1, cp2, i2, CHECK_false);
+      if (match) {
         return true;
       }
     }
   } break;
 
   case JVM_CONSTANT_InvokeDynamic:
+  case JVM_CONSTANT_InvokeDynamicTrans:
   {
-    int op_count = multi_operand_count_at(index1);
-    if (op_count == cp2->multi_operand_count_at(index2)) {
-      bool all_equal = true;
-      for (int op_i = 0; op_i < op_count; op_i++) {
-        int k1 = multi_operand_ref_at(index1, op_i);
-        int k2 = cp2->multi_operand_ref_at(index2, op_i);
-        if (k1 != k2) {
-          all_equal = false;
-          break;
-        }
+    int k1 = invoke_dynamic_bootstrap_method_ref_index_at(index1);
+    int k2 = cp2->invoke_dynamic_bootstrap_method_ref_index_at(index2);
+    bool match = compare_entry_to(k1, cp2, k2, CHECK_false);
+    if (!match)  return false;
+    k1 = invoke_dynamic_name_and_type_ref_index_at(index1);
+    k2 = cp2->invoke_dynamic_name_and_type_ref_index_at(index2);
+    match = compare_entry_to(k1, cp2, k2, CHECK_false);
+    if (!match)  return false;
+    int argc = invoke_dynamic_argument_count_at(index1);
+    if (argc == cp2->invoke_dynamic_argument_count_at(index2)) {
+      for (int j = 0; j < argc; j++) {
+        k1 = invoke_dynamic_argument_index_at(index1, j);
+        k2 = cp2->invoke_dynamic_argument_index_at(index2, j);
+        match = compare_entry_to(k1, cp2, k2, CHECK_false);
+        if (!match)  return false;
       }
-      if (all_equal) {
-        return true;           // got through loop; all elements equal
-      }
+      return true;           // got through loop; all elements equal
     }
   } break;
 
@@ -984,44 +990,18 @@
 } // end compare_entry_to()
 
 
-// Grow this->operands() to the indicated length, unless it is already at least that long.
-void constantPoolOopDesc::multi_operand_buffer_grow(int min_length, TRAPS) {
-  int old_length = multi_operand_buffer_fill_pointer();
-  if (old_length >= min_length)  return;
-  int new_length = min_length;
-  assert(new_length > _multi_operand_buffer_fill_pointer_offset, "");
-  typeArrayHandle new_operands = oopFactory::new_permanent_intArray(new_length, CHECK);
-  if (operands() == NULL) {
-    new_operands->int_at_put(_multi_operand_buffer_fill_pointer_offset, old_length);
-  } else {
-    // copy fill pointer and everything else
-    for (int i = 0; i < old_length; i++) {
-      new_operands->int_at_put(i, operands()->int_at(i));
-    }
-  }
-  set_operands(new_operands());
-}
-
-
 // Copy this constant pool's entries at start_i to end_i (inclusive)
 // to the constant pool to_cp's entries starting at to_i. A total of
 // (end_i - start_i) + 1 entries are copied.
-void constantPoolOopDesc::copy_cp_to(int start_i, int end_i,
+void constantPoolOopDesc::copy_cp_to_impl(constantPoolHandle from_cp, int start_i, int end_i,
        constantPoolHandle to_cp, int to_i, TRAPS) {
 
   int dest_i = to_i;  // leave original alone for debug purposes
 
-  if (operands() != NULL) {
-    // pre-grow the target CP's operand buffer
-    int nops = this->multi_operand_buffer_fill_pointer();
-    nops   += to_cp->multi_operand_buffer_fill_pointer();
-    to_cp->multi_operand_buffer_grow(nops, CHECK);
-  }
+  for (int src_i = start_i; src_i <= end_i; /* see loop bottom */ ) {
+    copy_entry_to(from_cp, src_i, to_cp, dest_i, CHECK);
 
-  for (int src_i = start_i; src_i <= end_i; /* see loop bottom */ ) {
-    copy_entry_to(src_i, to_cp, dest_i, CHECK);
-
-    switch (tag_at(src_i).value()) {
+    switch (from_cp->tag_at(src_i).value()) {
     case JVM_CONSTANT_Double:
     case JVM_CONSTANT_Long:
       // double and long take two constant pool entries
@@ -1036,30 +1016,81 @@
       break;
     }
   }
+
+  int from_oplen = operand_array_length(from_cp->operands());
+  int old_oplen  = operand_array_length(to_cp->operands());
+  if (from_oplen != 0) {
+    // append my operands to the target's operands array
+    if (old_oplen == 0) {
+      to_cp->set_operands(from_cp->operands());  // reuse; do not merge
+    } else {
+      int old_len  = to_cp->operands()->length();
+      int from_len = from_cp->operands()->length();
+      int old_off  = old_oplen * sizeof(u2);
+      int from_off = from_oplen * sizeof(u2);
+      typeArrayHandle new_operands = oopFactory::new_permanent_shortArray(old_len + from_len, CHECK);
+      int fillp = 0, len = 0;
+      // first part of dest
+      Copy::conjoint_memory_atomic(to_cp->operands()->short_at_addr(0),
+                                   new_operands->short_at_addr(fillp),
+                                   (len = old_off) * sizeof(u2));
+      fillp += len;
+      // first part of src
+      Copy::conjoint_memory_atomic(to_cp->operands()->short_at_addr(0),
+                                   new_operands->short_at_addr(fillp),
+                                   (len = from_off) * sizeof(u2));
+      fillp += len;
+      // second part of dest
+      Copy::conjoint_memory_atomic(to_cp->operands()->short_at_addr(old_off),
+                                   new_operands->short_at_addr(fillp),
+                                   (len = old_len - old_off) * sizeof(u2));
+      fillp += len;
+      // second part of src
+      Copy::conjoint_memory_atomic(to_cp->operands()->short_at_addr(from_off),
+                                   new_operands->short_at_addr(fillp),
+                                   (len = from_len - from_off) * sizeof(u2));
+      fillp += len;
+      assert(fillp == new_operands->length(), "");
+
+      // Adjust indexes in the first part of the copied operands array.
+      for (int j = 0; j < from_oplen; j++) {
+        int offset = operand_offset_at(new_operands(), old_oplen + j);
+        assert(offset == operand_offset_at(from_cp->operands(), j), "correct copy");
+        offset += old_len;  // every new tuple is preceded by old_len extra u2's
+        operand_offset_at_put(new_operands(), old_oplen + j, offset);
+      }
+
+      // replace target operands array with combined array
+      to_cp->set_operands(new_operands());
+    }
+  }
+
 } // end copy_cp_to()
 
 
 // Copy this constant pool's entry at from_i to the constant pool
 // to_cp's entry at to_i.
-void constantPoolOopDesc::copy_entry_to(int from_i, constantPoolHandle to_cp,
-       int to_i, TRAPS) {
+void constantPoolOopDesc::copy_entry_to(constantPoolHandle from_cp, int from_i,
+                                        constantPoolHandle to_cp, int to_i,
+                                        TRAPS) {
 
-  switch (tag_at(from_i).value()) {
+  int tag = from_cp->tag_at(from_i).value();
+  switch (tag) {
   case JVM_CONSTANT_Class:
   {
-    klassOop k = klass_at(from_i, CHECK);
+    klassOop k = from_cp->klass_at(from_i, CHECK);
     to_cp->klass_at_put(to_i, k);
   } break;
 
   case JVM_CONSTANT_ClassIndex:
   {
-    jint ki = klass_index_at(from_i);
+    jint ki = from_cp->klass_index_at(from_i);
     to_cp->klass_index_at_put(to_i, ki);
   } break;
 
   case JVM_CONSTANT_Double:
   {
-    jdouble d = double_at(from_i);
+    jdouble d = from_cp->double_at(from_i);
     to_cp->double_at_put(to_i, d);
     // double takes two constant pool entries so init second entry's tag
     to_cp->tag_at_put(to_i + 1, JVM_CONSTANT_Invalid);
@@ -1067,33 +1098,33 @@
 
   case JVM_CONSTANT_Fieldref:
   {
-    int class_index = uncached_klass_ref_index_at(from_i);
-    int name_and_type_index = uncached_name_and_type_ref_index_at(from_i);
+    int class_index = from_cp->uncached_klass_ref_index_at(from_i);
+    int name_and_type_index = from_cp->uncached_name_and_type_ref_index_at(from_i);
     to_cp->field_at_put(to_i, class_index, name_and_type_index);
   } break;
 
   case JVM_CONSTANT_Float:
   {
-    jfloat f = float_at(from_i);
+    jfloat f = from_cp->float_at(from_i);
     to_cp->float_at_put(to_i, f);
   } break;
 
   case JVM_CONSTANT_Integer:
   {
-    jint i = int_at(from_i);
+    jint i = from_cp->int_at(from_i);
     to_cp->int_at_put(to_i, i);
   } break;
 
   case JVM_CONSTANT_InterfaceMethodref:
   {
-    int class_index = uncached_klass_ref_index_at(from_i);
-    int name_and_type_index = uncached_name_and_type_ref_index_at(from_i);
+    int class_index = from_cp->uncached_klass_ref_index_at(from_i);
+    int name_and_type_index = from_cp->uncached_name_and_type_ref_index_at(from_i);
     to_cp->interface_method_at_put(to_i, class_index, name_and_type_index);
   } break;
 
   case JVM_CONSTANT_Long:
   {
-    jlong l = long_at(from_i);
+    jlong l = from_cp->long_at(from_i);
     to_cp->long_at_put(to_i, l);
     // long takes two constant pool entries so init second entry's tag
     to_cp->tag_at_put(to_i + 1, JVM_CONSTANT_Invalid);
@@ -1101,39 +1132,39 @@
 
   case JVM_CONSTANT_Methodref:
   {
-    int class_index = uncached_klass_ref_index_at(from_i);
-    int name_and_type_index = uncached_name_and_type_ref_index_at(from_i);
+    int class_index = from_cp->uncached_klass_ref_index_at(from_i);
+    int name_and_type_index = from_cp->uncached_name_and_type_ref_index_at(from_i);
     to_cp->method_at_put(to_i, class_index, name_and_type_index);
   } break;
 
   case JVM_CONSTANT_NameAndType:
   {
-    int name_ref_index = name_ref_index_at(from_i);
-    int signature_ref_index = signature_ref_index_at(from_i);
+    int name_ref_index = from_cp->name_ref_index_at(from_i);
+    int signature_ref_index = from_cp->signature_ref_index_at(from_i);
     to_cp->name_and_type_at_put(to_i, name_ref_index, signature_ref_index);
   } break;
 
   case JVM_CONSTANT_String:
   {
-    oop s = string_at(from_i, CHECK);
+    oop s = from_cp->string_at(from_i, CHECK);
     to_cp->string_at_put(to_i, s);
   } break;
 
   case JVM_CONSTANT_StringIndex:
   {
-    jint si = string_index_at(from_i);
+    jint si = from_cp->string_index_at(from_i);
     to_cp->string_index_at_put(to_i, si);
   } break;
 
   case JVM_CONSTANT_UnresolvedClass:
   {
-    symbolOop k = unresolved_klass_at(from_i);
+    symbolOop k = from_cp->unresolved_klass_at(from_i);
     to_cp->unresolved_klass_at_put(to_i, k);
   } break;
 
   case JVM_CONSTANT_UnresolvedClassInError:
   {
-    symbolOop k = unresolved_klass_at(from_i);
+    symbolOop k = from_cp->unresolved_klass_at(from_i);
     to_cp->unresolved_klass_at_put(to_i, k);
     to_cp->tag_at_put(to_i, JVM_CONSTANT_UnresolvedClassInError);
   } break;
@@ -1141,51 +1172,42 @@
 
   case JVM_CONSTANT_UnresolvedString:
   {
-    symbolOop s = unresolved_string_at(from_i);
+    symbolOop s = from_cp->unresolved_string_at(from_i);
     to_cp->unresolved_string_at_put(to_i, s);
   } break;
 
   case JVM_CONSTANT_Utf8:
   {
-    symbolOop s = symbol_at(from_i);
+    symbolOop s = from_cp->symbol_at(from_i);
     to_cp->symbol_at_put(to_i, s);
   } break;
 
   case JVM_CONSTANT_MethodType:
   {
-    jint k = method_type_index_at(from_i);
+    jint k = from_cp->method_type_index_at(from_i);
     to_cp->method_type_index_at_put(to_i, k);
   } break;
 
   case JVM_CONSTANT_MethodHandle:
   {
-    int k1 = method_handle_ref_kind_at(from_i);
-    int k2 = method_handle_index_at(from_i);
+    int k1 = from_cp->method_handle_ref_kind_at(from_i);
+    int k2 = from_cp->method_handle_index_at(from_i);
     to_cp->method_handle_index_at_put(to_i, k1, k2);
   } break;
 
+  case JVM_CONSTANT_InvokeDynamicTrans:
+  {
+    int k1 = from_cp->invoke_dynamic_bootstrap_method_ref_index_at(from_i);
+    int k2 = from_cp->invoke_dynamic_name_and_type_ref_index_at(from_i);
+    to_cp->invoke_dynamic_trans_at_put(to_i, k1, k2);
+  } break;
+
   case JVM_CONSTANT_InvokeDynamic:
   {
-    int op_count = multi_operand_count_at(from_i);
-    int fillp = to_cp->multi_operand_buffer_fill_pointer();
-    int to_op_base = fillp - _multi_operand_count_offset;  // fillp is count offset; get to base
-    to_cp->multi_operand_buffer_grow(to_op_base + op_count, CHECK);
-    to_cp->operands()->int_at_put(fillp++, op_count);
-    assert(fillp == to_op_base + _multi_operand_base_offset, "just wrote count, will now write args");
-    for (int op_i = 0; op_i < op_count; op_i++) {
-      int op = multi_operand_ref_at(from_i, op_i);
-      to_cp->operands()->int_at_put(fillp++, op);
-    }
-    assert(fillp <= to_cp->operands()->length(), "oob");
-    to_cp->set_multi_operand_buffer_fill_pointer(fillp);
-    to_cp->invoke_dynamic_at_put(to_i, to_op_base, op_count);
-#ifdef ASSERT
-    int k1 = invoke_dynamic_bootstrap_method_ref_index_at(from_i);
-    int k2 = invoke_dynamic_name_and_type_ref_index_at(from_i);
-    int k3 = invoke_dynamic_argument_count_at(from_i);
-    assert(to_cp->check_invoke_dynamic_at(to_i, k1, k2, k3),
-           "indy structure is OK");
-#endif //ASSERT
+    int k1 = from_cp->invoke_dynamic_bootstrap_specifier_index(from_i);
+    int k2 = from_cp->invoke_dynamic_name_and_type_ref_index_at(from_i);
+    k1 += operand_array_length(to_cp->operands());  // to_cp might already have operands
+    to_cp->invoke_dynamic_at_put(to_i, k1, k2);
   } break;
 
   // Invalid is used as the tag for the second constant pool entry
@@ -1195,7 +1217,6 @@
 
   default:
   {
-    jbyte bad_value = tag_at(from_i).value(); // leave a breadcrumb
     ShouldNotReachHere();
   } break;
   }
@@ -1406,8 +1427,9 @@
       return 5;
 
     case JVM_CONSTANT_InvokeDynamic:
-      // u1 tag, u2 bsm, u2 nt, u2 argc, u2 argv[argc]
-      return 7 + 2 * invoke_dynamic_argument_count_at(idx);
+    case JVM_CONSTANT_InvokeDynamicTrans:
+      // u1 tag, u2 bsm, u2 nt
+      return 5;
 
     case JVM_CONSTANT_Long:
     case JVM_CONSTANT_Double:
@@ -1620,19 +1642,15 @@
         DBG(printf("JVM_CONSTANT_MethodType: %hd", idx1));
         break;
       }
+      case JVM_CONSTANT_InvokeDynamicTrans:
       case JVM_CONSTANT_InvokeDynamic: {
-        *bytes = JVM_CONSTANT_InvokeDynamic;
-        idx1 = invoke_dynamic_bootstrap_method_ref_index_at(idx);
-        idx2 = invoke_dynamic_name_and_type_ref_index_at(idx);
-        int argc = invoke_dynamic_argument_count_at(idx);
+        *bytes = tag;
+        idx1 = extract_low_short_from_int(*int_at_addr(idx));
+        idx2 = extract_high_short_from_int(*int_at_addr(idx));
+        assert(idx2 == invoke_dynamic_name_and_type_ref_index_at(idx), "correct half of u4");
         Bytes::put_Java_u2((address) (bytes+1), idx1);
         Bytes::put_Java_u2((address) (bytes+3), idx2);
-        Bytes::put_Java_u2((address) (bytes+5), argc);
-        for (int arg_i = 0; arg_i < argc; arg_i++) {
-          int arg = invoke_dynamic_argument_index_at(idx, arg_i);
-          Bytes::put_Java_u2((address) (bytes+7+2*arg_i), arg);
-        }
-        DBG(printf("JVM_CONSTANT_InvokeDynamic: %hd %hd [%d]", idx1, idx2, argc));
+        DBG(printf("JVM_CONSTANT_InvokeDynamic: %hd %hd", idx1, idx2));
         break;
       }
     }
--- a/src/share/vm/oops/constantPoolOop.hpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/oops/constantPoolOop.hpp	Thu Dec 16 20:48:11 2010 -0800
@@ -179,28 +179,16 @@
     *int_at_addr(which) = ref_index;
   }
 
-  void invoke_dynamic_at_put(int which, int operand_base, int operand_count) {
+  void invoke_dynamic_at_put(int which, int bootstrap_specifier_index, int name_and_type_index) {
     tag_at_put(which, JVM_CONSTANT_InvokeDynamic);
-    *int_at_addr(which) = operand_base;  // this is the real information
+    *int_at_addr(which) = ((jint) name_and_type_index<<16) | bootstrap_specifier_index;
   }
-#ifdef ASSERT
-  bool check_invoke_dynamic_at(int which,
-                               int bootstrap_method_index,
-                               int name_and_type_index,
-                               int argument_count) {
-    assert(invoke_dynamic_bootstrap_method_ref_index_at(which) == bootstrap_method_index,
-           "already stored by caller");
-    assert(invoke_dynamic_name_and_type_ref_index_at(which) == name_and_type_index,
-           "already stored by caller");
-    assert(invoke_dynamic_argument_count_at(which) == argument_count,
-           "consistent argument count");
-    if (argument_count != 0) {
-      invoke_dynamic_argument_index_at(which, 0);
-      invoke_dynamic_argument_index_at(which, argument_count - 1);
-    }
-    return true;
+
+  void invoke_dynamic_trans_at_put(int which, int bootstrap_method_index, int name_and_type_index) {
+    tag_at_put(which, JVM_CONSTANT_InvokeDynamicTrans);
+    *int_at_addr(which) = ((jint) name_and_type_index<<16) | bootstrap_method_index;
+    assert(AllowTransitionalJSR292, "");
   }
-#endif //ASSERT
 
   // Temporary until actual use
   void unresolved_string_at_put(int which, symbolOop s) {
@@ -443,75 +431,90 @@
     return symbol_at(sym);
   }
 
- private:
-  // some nodes (InvokeDynamic) have a variable number of operands, each a u2 value
-  enum { _multi_operand_count_offset = -1,
-         _multi_operand_base_offset  = 0,
-         _multi_operand_buffer_fill_pointer_offset = 0  // shared at front of operands array
-  };
-  int multi_operand_buffer_length() {
-    return operands() == NULL ? 0 : operands()->length();
-  }
-  int multi_operand_buffer_fill_pointer() {
-    return operands() == NULL
-      ? _multi_operand_buffer_fill_pointer_offset + 1
-      : operands()->int_at(_multi_operand_buffer_fill_pointer_offset);
-  }
-  void multi_operand_buffer_grow(int min_length, TRAPS);
-  void set_multi_operand_buffer_fill_pointer(int fillp) {
-    assert(operands() != NULL, "");
-    operands()->int_at_put(_multi_operand_buffer_fill_pointer_offset, fillp);
-  }
-  int multi_operand_base_at(int which) {
+  int invoke_dynamic_name_and_type_ref_index_at(int which) {
     assert(tag_at(which).is_invoke_dynamic(), "Corrupted constant pool");
-    int op_base = *int_at_addr(which);
-    assert(op_base > _multi_operand_buffer_fill_pointer_offset, "Corrupted operand base");
-    return op_base;
+    return extract_high_short_from_int(*int_at_addr(which));
   }
-  int multi_operand_count_at(int which) {
-    int op_base = multi_operand_base_at(which);
-    assert((uint)(op_base + _multi_operand_count_offset) < (uint)operands()->length(), "oob");
-    int count = operands()->int_at(op_base + _multi_operand_count_offset);
-    return count;
+  int invoke_dynamic_bootstrap_specifier_index(int which) {
+    assert(tag_at(which).value() == JVM_CONSTANT_InvokeDynamic, "Corrupted constant pool");
+    return extract_low_short_from_int(*int_at_addr(which));
+  }
+  int invoke_dynamic_operand_base(int which) {
+    int bootstrap_specifier_index = invoke_dynamic_bootstrap_specifier_index(which);
+    return operand_offset_at(operands(), bootstrap_specifier_index);
   }
-  int multi_operand_ref_at(int which, int i) {
-    int op_base = multi_operand_base_at(which);
-    assert((uint)i < (uint)multi_operand_count_at(which), "oob");
-    assert((uint)(op_base + _multi_operand_base_offset + i) < (uint)operands()->length(), "oob");
-    return operands()->int_at(op_base + _multi_operand_base_offset + i);
+  // The first part of the operands array consists of an index into the second part.
+  // Extract a 32-bit index value from the first part.
+  static int operand_offset_at(typeArrayOop operands, int bootstrap_specifier_index) {
+    int n = (bootstrap_specifier_index * 2);
+    assert(n >= 0 && n+2 <= operands->length(), "oob");
+    // The first 32-bit index points to the beginning of the second part
+    // of the operands array.  Make sure this index is in the first part.
+    DEBUG_ONLY(int second_part = build_int_from_shorts(operands->short_at(0),
+                                                       operands->short_at(1)));
+    assert(second_part == 0 || n+2 <= second_part, "oob (2)");
+    int offset = build_int_from_shorts(operands->short_at(n+0),
+                                       operands->short_at(n+1));
+    // The offset itself must point into the second part of the array.
+    assert(offset == 0 || offset >= second_part && offset <= operands->length(), "oob (3)");
+    return offset;
   }
-  void set_multi_operand_ref_at(int which, int i, int ref) {
-    DEBUG_ONLY(multi_operand_ref_at(which, i));  // trigger asserts
-    int op_base = multi_operand_base_at(which);
-    operands()->int_at_put(op_base + _multi_operand_base_offset + i, ref);
+  static void operand_offset_at_put(typeArrayOop operands, int bootstrap_specifier_index, int offset) {
+    int n = bootstrap_specifier_index * 2;
+    assert(n >= 0 && n+2 <= operands->length(), "oob");
+    operands->short_at_put(n+0, extract_low_short_from_int(offset));
+    operands->short_at_put(n+1, extract_high_short_from_int(offset));
+  }
+  static int operand_array_length(typeArrayOop operands) {
+    if (operands == NULL || operands->length() == 0)  return 0;
+    int second_part = operand_offset_at(operands, 0);
+    return (second_part / 2);
   }
 
- public:
-  // layout of InvokeDynamic:
+#ifdef ASSERT
+  // operand tuples fit together exactly, end to end
+  static int operand_limit_at(typeArrayOop operands, int bootstrap_specifier_index) {
+    int nextidx = bootstrap_specifier_index + 1;
+    if (nextidx == operand_array_length(operands))
+      return operands->length();
+    else
+      return operand_offset_at(operands, nextidx);
+  }
+  int invoke_dynamic_operand_limit(int which) {
+    int bootstrap_specifier_index = invoke_dynamic_bootstrap_specifier_index(which);
+    return operand_limit_at(operands(), bootstrap_specifier_index);
+  }
+#endif //ASSERT
+
+  // layout of InvokeDynamic bootstrap method specifier (in second part of operands array):
   enum {
          _indy_bsm_offset  = 0,  // CONSTANT_MethodHandle bsm
-         _indy_nt_offset   = 1,  // CONSTANT_NameAndType descr
-         _indy_argc_offset = 2,  // u2 argc
-         _indy_argv_offset = 3   // u2 argv[argc]
+         _indy_argc_offset = 1,  // u2 argc
+         _indy_argv_offset = 2   // u2 argv[argc]
   };
   int invoke_dynamic_bootstrap_method_ref_index_at(int which) {
     assert(tag_at(which).is_invoke_dynamic(), "Corrupted constant pool");
-    return multi_operand_ref_at(which, _indy_bsm_offset);
-  }
-  int invoke_dynamic_name_and_type_ref_index_at(int which) {
-    assert(tag_at(which).is_invoke_dynamic(), "Corrupted constant pool");
-    return multi_operand_ref_at(which, _indy_nt_offset);
+    if (tag_at(which).value() == JVM_CONSTANT_InvokeDynamicTrans)
+      return extract_low_short_from_int(*int_at_addr(which));
+    int op_base = invoke_dynamic_operand_base(which);
+    return operands()->short_at(op_base + _indy_bsm_offset);
   }
   int invoke_dynamic_argument_count_at(int which) {
     assert(tag_at(which).is_invoke_dynamic(), "Corrupted constant pool");
-    int argc = multi_operand_ref_at(which, _indy_argc_offset);
-    DEBUG_ONLY(int op_count = multi_operand_count_at(which));
-    assert(_indy_argv_offset + argc == op_count, "consistent inner and outer counts");
+    if (tag_at(which).value() == JVM_CONSTANT_InvokeDynamicTrans)
+      return 0;
+    int op_base = invoke_dynamic_operand_base(which);
+    int argc = operands()->short_at(op_base + _indy_argc_offset);
+    DEBUG_ONLY(int end_offset = op_base + _indy_argv_offset + argc;
+               int next_offset = invoke_dynamic_operand_limit(which));
+    assert(end_offset == next_offset, "matched ending");
     return argc;
   }
   int invoke_dynamic_argument_index_at(int which, int j) {
-    assert((uint)j < (uint)invoke_dynamic_argument_count_at(which), "oob");
-    return multi_operand_ref_at(which, _indy_argv_offset + j);
+    int op_base = invoke_dynamic_operand_base(which);
+    DEBUG_ONLY(int argc = operands()->short_at(op_base + _indy_argc_offset));
+    assert((uint)j < (uint)argc, "oob");
+    return operands()->short_at(op_base + _indy_argv_offset + j);
   }
 
   // The following methods (name/signature/klass_ref_at, klass_ref_at_noresolve,
@@ -659,9 +662,12 @@
  public:
   // Merging constantPoolOop support:
   bool compare_entry_to(int index1, constantPoolHandle cp2, int index2, TRAPS);
-  void copy_cp_to(int start_i, int end_i, constantPoolHandle to_cp, int to_i,
-    TRAPS);
-  void copy_entry_to(int from_i, constantPoolHandle to_cp, int to_i, TRAPS);
+  void copy_cp_to(int start_i, int end_i, constantPoolHandle to_cp, int to_i, TRAPS) {
+    constantPoolHandle h_this(THREAD, this);
+    copy_cp_to_impl(h_this, start_i, end_i, to_cp, to_i, THREAD);
+  }
+  static void copy_cp_to_impl(constantPoolHandle from_cp, int start_i, int end_i, constantPoolHandle to_cp, int to_i, TRAPS);
+  static void copy_entry_to(constantPoolHandle from_cp, int from_i, constantPoolHandle to_cp, int to_i, TRAPS);
   int  find_matching_entry(int pattern_i, constantPoolHandle search_cp, TRAPS);
   int  orig_length() const                { return _orig_length; }
   void set_orig_length(int orig_length)   { _orig_length = orig_length; }
--- a/src/share/vm/oops/instanceRefKlass.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/oops/instanceRefKlass.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -457,6 +457,12 @@
   }
 }
 
+bool instanceRefKlass::owns_pending_list_lock(JavaThread* thread) {
+  if (java_lang_ref_Reference::pending_list_lock() == NULL) return false;
+  Handle h_lock(thread, java_lang_ref_Reference::pending_list_lock());
+  return ObjectSynchronizer::current_thread_holds_lock(thread, h_lock);
+}
+
 void instanceRefKlass::acquire_pending_list_lock(BasicLock *pending_list_basic_lock) {
   // we may enter this with pending exception set
   PRESERVE_EXCEPTION_MARK;  // exceptions are never thrown, needed for TRAPS argument
--- a/src/share/vm/oops/instanceRefKlass.hpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/oops/instanceRefKlass.hpp	Thu Dec 16 20:48:11 2010 -0800
@@ -89,6 +89,7 @@
 
   static void release_and_notify_pending_list_lock(BasicLock *pending_list_basic_lock);
   static void acquire_pending_list_lock(BasicLock *pending_list_basic_lock);
+  static bool owns_pending_list_lock(JavaThread* thread);
 
   // Update non-static oop maps so 'referent', 'nextPending' and
   // 'discovered' will look like non-oops
--- a/src/share/vm/oops/klassVtable.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/oops/klassVtable.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -518,18 +518,21 @@
 bool klassVtable::is_miranda(methodOop m, objArrayOop class_methods, klassOop super) {
   symbolOop name = m->name();
   symbolOop signature = m->signature();
+
   if (instanceKlass::find_method(class_methods, name, signature) == NULL) {
-     // did not find it in the method table of the current class
+    // did not find it in the method table of the current class
     if (super == NULL) {
       // super doesn't exist
       return true;
-    } else {
-      if (instanceKlass::cast(super)->lookup_method(name, signature) == NULL) {
-        // super class hierarchy does not implement it
-        return true;
-      }
+    }
+
+    methodOop mo = instanceKlass::cast(super)->lookup_method(name, signature);
+    if (mo == NULL || mo->access_flags().is_private() ) {
+      // super class hierarchy does not implement it or protection is different
+      return true;
     }
   }
+
   return false;
 }
 
--- a/src/share/vm/oops/methodOop.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/oops/methodOop.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -309,6 +309,12 @@
 // Build a methodDataOop object to hold information about this method
 // collected in the interpreter.
 void methodOopDesc::build_interpreter_method_data(methodHandle method, TRAPS) {
+  // Do not profile method if current thread holds the pending list lock,
+  // which avoids deadlock for acquiring the MethodData_lock.
+  if (instanceRefKlass::owns_pending_list_lock((JavaThread*)THREAD)) {
+    return;
+  }
+
   // Grab a lock here to prevent multiple
   // methodDataOops from being created.
   MutexLocker ml(MethodData_lock, THREAD);
--- a/src/share/vm/opto/c2_globals.hpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/opto/c2_globals.hpp	Thu Dec 16 20:48:11 2010 -0800
@@ -284,6 +284,9 @@
   develop(bool, SparcV9RegsHiBitsZero, true,                                \
           "Assume Sparc V9 I&L registers on V8+ systems are zero-extended") \
                                                                             \
+  product(bool, UseRDPCForConstantTableBase, false,                         \
+          "Use Sparc RDPC instruction for the constant table base.")        \
+                                                                            \
   develop(intx, PrintIdealGraphLevel, 0,                                    \
           "Print ideal graph to XML file / network interface. "             \
           "By default attempts to connect to the visualizer on a socket.")  \
--- a/src/share/vm/opto/chaitin.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/opto/chaitin.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -1782,7 +1782,7 @@
   for(uint i2 = 1; i2 < _maxlrg; i2++ ) {
     tty->print("L%d: ",i2);
     if( i2 < _ifg->_maxlrg ) lrgs(i2).dump( );
-    else tty->print("new LRG");
+    else tty->print_cr("new LRG");
   }
   tty->print_cr("");
 
@@ -1993,7 +1993,7 @@
 }
 
 //------------------------------dump_lrg---------------------------------------
-void PhaseChaitin::dump_lrg( uint lidx ) const {
+void PhaseChaitin::dump_lrg( uint lidx, bool defs_only ) const {
   tty->print_cr("---dump of L%d---",lidx);
 
   if( _ifg ) {
@@ -2002,9 +2002,11 @@
       return;
     }
     tty->print("L%d: ",lidx);
-    lrgs(lidx).dump( );
+    if( lidx < _ifg->_maxlrg ) lrgs(lidx).dump( );
+    else tty->print_cr("new LRG");
   }
-  if( _ifg ) {    tty->print("Neighbors: %d - ", _ifg->neighbor_cnt(lidx));
+  if( _ifg && lidx < _ifg->_maxlrg) {
+    tty->print("Neighbors: %d - ", _ifg->neighbor_cnt(lidx));
     _ifg->neighbors(lidx)->dump();
     tty->cr();
   }
@@ -2024,16 +2026,18 @@
         dump(n);
         continue;
       }
-      uint cnt = n->req();
-      for( uint k = 1; k < cnt; k++ ) {
-        Node *m = n->in(k);
-        if (!m)  continue;  // be robust in the dumper
-        if( Find_const(m) == lidx ) {
-          if( !dump_once++ ) {
-            tty->cr();
-            b->dump_head( &_cfg._bbs );
+      if (!defs_only) {
+        uint cnt = n->req();
+        for( uint k = 1; k < cnt; k++ ) {
+          Node *m = n->in(k);
+          if (!m)  continue;  // be robust in the dumper
+          if( Find_const(m) == lidx ) {
+            if( !dump_once++ ) {
+              tty->cr();
+              b->dump_head( &_cfg._bbs );
+            }
+            dump(n);
           }
-          dump(n);
         }
       }
     }
--- a/src/share/vm/opto/chaitin.hpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/opto/chaitin.hpp	Thu Dec 16 20:48:11 2010 -0800
@@ -512,7 +512,11 @@
   void dump( const Block * b ) const;
   void dump_degree_lists() const;
   void dump_simplified() const;
-  void dump_lrg( uint lidx ) const;
+  void dump_lrg( uint lidx, bool defs_only) const;
+  void dump_lrg( uint lidx) const {
+    // dump defs and uses by default
+    dump_lrg(lidx, false);
+  }
   void dump_bb( uint pre_order ) const;
 
   // Verify that base pointers and derived pointers are still sane
--- a/src/share/vm/opto/compile.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/opto/compile.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -75,6 +75,18 @@
 # include "adfiles/ad_zero.hpp"
 #endif
 
+
+// -------------------- Compile::mach_constant_base_node -----------------------
+// Constant table base node singleton.
+MachConstantBaseNode* Compile::mach_constant_base_node() {
+  if (_mach_constant_base_node == NULL) {
+    _mach_constant_base_node = new (C) MachConstantBaseNode();
+    _mach_constant_base_node->add_req(C->root());
+  }
+  return _mach_constant_base_node;
+}
+
+
 /// Support for intrinsics.
 
 // Return the index at which m must be inserted (or already exists).
@@ -432,13 +444,14 @@
 }
 
 
-void Compile::init_scratch_buffer_blob() {
-  if( scratch_buffer_blob() != NULL )  return;
+void Compile::init_scratch_buffer_blob(int const_size) {
+  if (scratch_buffer_blob() != NULL)  return;
 
   // Construct a temporary CodeBuffer to have it construct a BufferBlob
   // Cache this BufferBlob for this compile.
   ResourceMark rm;
-  int size = (MAX_inst_size + MAX_stubs_size + MAX_const_size);
+  _scratch_const_size = const_size;
+  int size = (MAX_inst_size + MAX_stubs_size + _scratch_const_size);
   BufferBlob* blob = BufferBlob::create("Compile::scratch_buffer", size);
   // Record the buffer blob for next time.
   set_scratch_buffer_blob(blob);
@@ -455,9 +468,19 @@
 }
 
 
+void Compile::clear_scratch_buffer_blob() {
+  assert(scratch_buffer_blob(), "no BufferBlob set");
+  set_scratch_buffer_blob(NULL);
+  set_scratch_locs_memory(NULL);
+}
+
+
 //-----------------------scratch_emit_size-------------------------------------
 // Helper function that computes size by emitting code
 uint Compile::scratch_emit_size(const Node* n) {
+  // Start scratch_emit_size section.
+  set_in_scratch_emit_size(true);
+
   // Emit into a trash buffer and count bytes emitted.
   // This is a pretty expensive way to compute a size,
   // but it works well enough if seldom used.
@@ -476,13 +499,20 @@
   address blob_end   = (address)locs_buf;
   assert(blob->content_contains(blob_end), "sanity");
   CodeBuffer buf(blob_begin, blob_end - blob_begin);
-  buf.initialize_consts_size(MAX_const_size);
+  buf.initialize_consts_size(_scratch_const_size);
   buf.initialize_stubs_size(MAX_stubs_size);
   assert(locs_buf != NULL, "sanity");
-  int lsize = MAX_locs_size / 2;
-  buf.insts()->initialize_shared_locs(&locs_buf[0],     lsize);
-  buf.stubs()->initialize_shared_locs(&locs_buf[lsize], lsize);
+  int lsize = MAX_locs_size / 3;
+  buf.consts()->initialize_shared_locs(&locs_buf[lsize * 0], lsize);
+  buf.insts()->initialize_shared_locs( &locs_buf[lsize * 1], lsize);
+  buf.stubs()->initialize_shared_locs( &locs_buf[lsize * 2], lsize);
+
+  // Do the emission.
   n->emit(buf, this->regalloc());
+
+  // End scratch_emit_size section.
+  set_in_scratch_emit_size(false);
+
   return buf.insts_size();
 }
 
@@ -516,10 +546,13 @@
                   _orig_pc_slot(0),
                   _orig_pc_slot_offset_in_bytes(0),
                   _has_method_handle_invokes(false),
+                  _mach_constant_base_node(NULL),
                   _node_bundling_limit(0),
                   _node_bundling_base(NULL),
                   _java_calls(0),
                   _inner_loops(0),
+                  _scratch_const_size(-1),
+                  _in_scratch_emit_size(false),
 #ifndef PRODUCT
                   _trace_opto_output(TraceOptoOutput || method()->has_option("TraceOptoOutput")),
                   _printer(IdealGraphPrinter::printer()),
@@ -553,7 +586,7 @@
   if (ProfileTraps) {
     // Make sure the method being compiled gets its own MDO,
     // so we can at least track the decompile_count().
-    method()->build_method_data();
+    method()->ensure_method_data();
   }
 
   Init(::AliasLevel);
@@ -783,6 +816,7 @@
     _failure_reason(NULL),
     _code_buffer("Compile::Fill_buffer"),
     _has_method_handle_invokes(false),
+    _mach_constant_base_node(NULL),
     _node_bundling_limit(0),
     _node_bundling_base(NULL),
     _java_calls(0),
@@ -2862,3 +2896,207 @@
     _log->done("phase nodes='%d'", C->unique());
   }
 }
+
+//=============================================================================
+// Two Constant's are equal when the type and the value are equal.
+bool Compile::Constant::operator==(const Constant& other) {
+  if (type()          != other.type()         )  return false;
+  if (can_be_reused() != other.can_be_reused())  return false;
+  // For floating point values we compare the bit pattern.
+  switch (type()) {
+  case T_FLOAT:   return (_value.i == other._value.i);
+  case T_LONG:
+  case T_DOUBLE:  return (_value.j == other._value.j);
+  case T_OBJECT:
+  case T_ADDRESS: return (_value.l == other._value.l);
+  case T_VOID:    return (_value.l == other._value.l);  // jump-table entries
+  default: ShouldNotReachHere();
+  }
+  return false;
+}
+
+// Emit constants grouped in the following order:
+static BasicType type_order[] = {
+  T_FLOAT,    // 32-bit
+  T_OBJECT,   // 32 or 64-bit
+  T_ADDRESS,  // 32 or 64-bit
+  T_DOUBLE,   // 64-bit
+  T_LONG,     // 64-bit
+  T_VOID,     // 32 or 64-bit (jump-tables are at the end of the constant table for code emission reasons)
+  T_ILLEGAL
+};
+
+static int type_to_size_in_bytes(BasicType t) {
+  switch (t) {
+  case T_LONG:    return sizeof(jlong  );
+  case T_FLOAT:   return sizeof(jfloat );
+  case T_DOUBLE:  return sizeof(jdouble);
+    // We use T_VOID as marker for jump-table entries (labels) which
+    // need an interal word relocation.
+  case T_VOID:
+  case T_ADDRESS:
+  case T_OBJECT:  return sizeof(jobject);
+  }
+
+  ShouldNotReachHere();
+  return -1;
+}
+
+void Compile::ConstantTable::calculate_offsets_and_size() {
+  int size = 0;
+  for (int t = 0; type_order[t] != T_ILLEGAL; t++) {
+    BasicType type = type_order[t];
+
+    for (int i = 0; i < _constants.length(); i++) {
+      Constant con = _constants.at(i);
+      if (con.type() != type)  continue;  // Skip other types.
+
+      // Align size for type.
+      int typesize = type_to_size_in_bytes(con.type());
+      size = align_size_up(size, typesize);
+
+      // Set offset.
+      con.set_offset(size);
+      _constants.at_put(i, con);
+
+      // Add type size.
+      size = size + typesize;
+    }
+  }
+
+  // Align size up to the next section start (which is insts; see
+  // CodeBuffer::align_at_start).
+  assert(_size == -1, "already set?");
+  _size = align_size_up(size, CodeEntryAlignment);
+
+  if (Matcher::constant_table_absolute_addressing) {
+    set_table_base_offset(0);  // No table base offset required
+  } else {
+    if (UseRDPCForConstantTableBase) {
+      // table base offset is set in MachConstantBaseNode::emit
+    } else {
+      // When RDPC is not used, the table base is set into the middle of
+      // the constant table.
+      int half_size = _size / 2;
+      assert(half_size * 2 == _size, "sanity");
+      set_table_base_offset(-half_size);
+    }
+  }
+}
+
+void Compile::ConstantTable::emit(CodeBuffer& cb) {
+  MacroAssembler _masm(&cb);
+  for (int t = 0; type_order[t] != T_ILLEGAL; t++) {
+    BasicType type = type_order[t];
+
+    for (int i = 0; i < _constants.length(); i++) {
+      Constant con = _constants.at(i);
+      if (con.type() != type)  continue;  // Skip other types.
+
+      address constant_addr;
+      switch (con.type()) {
+      case T_LONG:   constant_addr = _masm.long_constant(  con.get_jlong()  ); break;
+      case T_FLOAT:  constant_addr = _masm.float_constant( con.get_jfloat() ); break;
+      case T_DOUBLE: constant_addr = _masm.double_constant(con.get_jdouble()); break;
+      case T_OBJECT: {
+        jobject obj = con.get_jobject();
+        int oop_index = _masm.oop_recorder()->find_index(obj);
+        constant_addr = _masm.address_constant((address) obj, oop_Relocation::spec(oop_index));
+        break;
+      }
+      case T_ADDRESS: {
+        address addr = (address) con.get_jobject();
+        constant_addr = _masm.address_constant(addr);
+        break;
+      }
+      // We use T_VOID as marker for jump-table entries (labels) which
+      // need an interal word relocation.
+      case T_VOID: {
+        // Write a dummy word.  The real value is filled in later
+        // in fill_jump_table_in_constant_table.
+        address addr = (address) con.get_jobject();
+        constant_addr = _masm.address_constant(addr);
+        break;
+      }
+      default: ShouldNotReachHere();
+      }
+      assert(constant_addr != NULL, "consts section too small");
+      assert((constant_addr - _masm.code()->consts()->start()) == con.offset(), err_msg("must be: %d == %d", constant_addr - _masm.code()->consts()->start(), con.offset()));
+    }
+  }
+}
+
+int Compile::ConstantTable::find_offset(Constant& con) const {
+  int idx = _constants.find(con);
+  assert(idx != -1, "constant must be in constant table");
+  int offset = _constants.at(idx).offset();
+  assert(offset != -1, "constant table not emitted yet?");
+  return offset;
+}
+
+void Compile::ConstantTable::add(Constant& con) {
+  if (con.can_be_reused()) {
+    int idx = _constants.find(con);
+    if (idx != -1 && _constants.at(idx).can_be_reused()) {
+      return;
+    }
+  }
+  (void) _constants.append(con);
+}
+
+Compile::Constant Compile::ConstantTable::add(BasicType type, jvalue value) {
+  Constant con(type, value);
+  add(con);
+  return con;
+}
+
+Compile::Constant Compile::ConstantTable::add(MachOper* oper) {
+  jvalue value;
+  BasicType type = oper->type()->basic_type();
+  switch (type) {
+  case T_LONG:    value.j = oper->constantL(); break;
+  case T_FLOAT:   value.f = oper->constantF(); break;
+  case T_DOUBLE:  value.d = oper->constantD(); break;
+  case T_OBJECT:
+  case T_ADDRESS: value.l = (jobject) oper->constant(); break;
+  default: ShouldNotReachHere();
+  }
+  return add(type, value);
+}
+
+Compile::Constant Compile::ConstantTable::allocate_jump_table(MachConstantNode* n) {
+  jvalue value;
+  // We can use the node pointer here to identify the right jump-table
+  // as this method is called from Compile::Fill_buffer right before
+  // the MachNodes are emitted and the jump-table is filled (means the
+  // MachNode pointers do not change anymore).
+  value.l = (jobject) n;
+  Constant con(T_VOID, value, false);  // Labels of a jump-table cannot be reused.
+  for (uint i = 0; i < n->outcnt(); i++) {
+    add(con);
+  }
+  return con;
+}
+
+void Compile::ConstantTable::fill_jump_table(CodeBuffer& cb, MachConstantNode* n, GrowableArray<Label*> labels) const {
+  // If called from Compile::scratch_emit_size do nothing.
+  if (Compile::current()->in_scratch_emit_size())  return;
+
+  assert(labels.is_nonempty(), "must be");
+  assert((uint) labels.length() == n->outcnt(), err_msg("must be equal: %d == %d", labels.length(), n->outcnt()));
+
+  // Since MachConstantNode::constant_offset() also contains
+  // table_base_offset() we need to subtract the table_base_offset()
+  // to get the plain offset into the constant table.
+  int offset = n->constant_offset() - table_base_offset();
+
+  MacroAssembler _masm(&cb);
+  address* jump_table_base = (address*) (_masm.code()->consts()->start() + offset);
+
+  for (int i = 0; i < labels.length(); i++) {
+    address* constant_addr = &jump_table_base[i];
+    assert(*constant_addr == (address) n, "all jump-table entries must contain node pointer");
+    *constant_addr = cb.consts()->target(*labels.at(i), (address) constant_addr);
+    cb.consts()->relocate((address) constant_addr, relocInfo::internal_word_type);
+  }
+}
--- a/src/share/vm/opto/compile.hpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/opto/compile.hpp	Thu Dec 16 20:48:11 2010 -0800
@@ -48,7 +48,10 @@
 class InlineTree;
 class Int_Array;
 class Matcher;
+class MachConstantNode;
+class MachConstantBaseNode;
 class MachNode;
+class MachOper;
 class MachSafePointNode;
 class Node;
 class Node_Array;
@@ -139,6 +142,81 @@
     trapHistLength = methodDataOopDesc::_trap_hist_limit
   };
 
+  // Constant entry of the constant table.
+  class Constant {
+  private:
+    BasicType _type;
+    jvalue    _value;
+    int       _offset;         // offset of this constant (in bytes) relative to the constant table base.
+    bool      _can_be_reused;  // true (default) if the value can be shared with other users.
+
+  public:
+    Constant() : _type(T_ILLEGAL), _offset(-1), _can_be_reused(true) { _value.l = 0; }
+    Constant(BasicType type, jvalue value, bool can_be_reused = true) :
+      _type(type),
+      _value(value),
+      _offset(-1),
+      _can_be_reused(can_be_reused)
+    {}
+
+    bool operator==(const Constant& other);
+
+    BasicType type()      const    { return _type; }
+
+    jlong   get_jlong()   const    { return _value.j; }
+    jfloat  get_jfloat()  const    { return _value.f; }
+    jdouble get_jdouble() const    { return _value.d; }
+    jobject get_jobject() const    { return _value.l; }
+
+    int         offset()  const    { return _offset; }
+    void    set_offset(int offset) {        _offset = offset; }
+
+    bool    can_be_reused() const  { return _can_be_reused; }
+  };
+
+  // Constant table.
+  class ConstantTable {
+  private:
+    GrowableArray<Constant> _constants;          // Constants of this table.
+    int                     _size;               // Size in bytes the emitted constant table takes (including padding).
+    int                     _table_base_offset;  // Offset of the table base that gets added to the constant offsets.
+
+  public:
+    ConstantTable() :
+      _size(-1),
+      _table_base_offset(-1)  // We can use -1 here since the constant table is always bigger than 2 bytes (-(size / 2), see MachConstantBaseNode::emit).
+    {}
+
+    int size() const { assert(_size != -1, "size not yet calculated"); return _size; }
+
+    void set_table_base_offset(int x)  { assert(_table_base_offset == -1, "set only once");                        _table_base_offset = x; }
+    int      table_base_offset() const { assert(_table_base_offset != -1, "table base offset not yet set"); return _table_base_offset; }
+
+    void emit(CodeBuffer& cb);
+
+    // Returns the offset of the last entry (the top) of the constant table.
+    int  top_offset() const { assert(_constants.top().offset() != -1, "constant not yet bound"); return _constants.top().offset(); }
+
+    void calculate_offsets_and_size();
+    int  find_offset(Constant& con) const;
+
+    void     add(Constant& con);
+    Constant add(BasicType type, jvalue value);
+    Constant add(MachOper* oper);
+    Constant add(jfloat f) {
+      jvalue value; value.f = f;
+      return add(T_FLOAT, value);
+    }
+    Constant add(jdouble d) {
+      jvalue value; value.d = d;
+      return add(T_DOUBLE, value);
+    }
+
+    // Jump table
+    Constant allocate_jump_table(MachConstantNode* n);
+    void         fill_jump_table(CodeBuffer& cb, MachConstantNode* n, GrowableArray<Label*> labels) const;
+  };
+
  private:
   // Fixed parameters to this compilation.
   const int             _compile_id;
@@ -212,6 +290,11 @@
   Node*                 _recent_alloc_obj;
   Node*                 _recent_alloc_ctl;
 
+  // Constant table
+  ConstantTable         _constant_table;        // The constant table for this compile.
+  MachConstantBaseNode* _mach_constant_base_node;  // Constant table base node singleton.
+
+
   // Blocked array of debugging and profiling information,
   // tracked per node.
   enum { _log2_node_notes_block_size = 8,
@@ -272,6 +355,8 @@
   static int            _CompiledZap_count;     // counter compared against CompileZap[First/Last]
   BufferBlob*           _scratch_buffer_blob;   // For temporary code buffers.
   relocInfo*            _scratch_locs_memory;   // For temporary code buffers.
+  int                   _scratch_const_size;    // For temporary code buffers.
+  bool                  _in_scratch_emit_size;  // true when in scratch_emit_size.
 
  public:
   // Accessors
@@ -454,6 +539,12 @@
                                                   _recent_alloc_obj = obj;
                                                 }
 
+  // Constant table
+  ConstantTable&   constant_table() { return _constant_table; }
+
+  MachConstantBaseNode*     mach_constant_base_node();
+  bool                  has_mach_constant_base_node() const { return _mach_constant_base_node != NULL; }
+
   // Handy undefined Node
   Node*             top() const                 { return _top; }
 
@@ -605,13 +696,16 @@
   Dependencies*     dependencies()              { return env()->dependencies(); }
   static int        CompiledZap_count()         { return _CompiledZap_count; }
   BufferBlob*       scratch_buffer_blob()       { return _scratch_buffer_blob; }
-  void         init_scratch_buffer_blob();
+  void         init_scratch_buffer_blob(int const_size);
+  void        clear_scratch_buffer_blob();
   void          set_scratch_buffer_blob(BufferBlob* b) { _scratch_buffer_blob = b; }
   relocInfo*        scratch_locs_memory()       { return _scratch_locs_memory; }
   void          set_scratch_locs_memory(relocInfo* b)  { _scratch_locs_memory = b; }
 
   // emit to scratch blob, report resulting size
   uint              scratch_emit_size(const Node* n);
+  void       set_in_scratch_emit_size(bool x)   {        _in_scratch_emit_size = x; }
+  bool           in_scratch_emit_size() const   { return _in_scratch_emit_size;     }
 
   enum ScratchBufferBlob {
     MAX_inst_size       = 1024,
@@ -692,7 +786,7 @@
   void Fill_buffer();
 
   // Determine which variable sized branches can be shortened
-  void Shorten_branches(Label *labels, int& code_size, int& reloc_size, int& stub_size, int& const_size);
+  void Shorten_branches(Label *labels, int& code_size, int& reloc_size, int& stub_size);
 
   // Compute the size of first NumberOfLoopInstrToAlign instructions
   // at the head of a loop.
--- a/src/share/vm/opto/gcm.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/opto/gcm.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -89,7 +89,7 @@
   assert(in0 != NULL, "Only control-dependent");
   const Node *p = in0->is_block_proj();
   if (p != NULL && p != n) {    // Control from a block projection?
-    assert(!n->pinned() || n->is_SafePointScalarObject(), "only SafePointScalarObject pinned node is expected here");
+    assert(!n->pinned() || n->is_MachConstantBase() || n->is_SafePointScalarObject(), "only pinned MachConstantBase or SafePointScalarObject node is expected here");
     // Find trailing Region
     Block *pb = _bbs[in0->_idx]; // Block-projection already has basic block
     uint j = 0;
--- a/src/share/vm/opto/graphKit.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/opto/graphKit.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -1841,7 +1841,7 @@
 
   // Note:  If ProfileTraps is true, and if a deopt. actually
   // occurs here, the runtime will make sure an MDO exists.  There is
-  // no need to call method()->build_method_data() at this point.
+  // no need to call method()->ensure_method_data() at this point.
 
 #ifdef ASSERT
   if (!must_throw) {
--- a/src/share/vm/opto/machnode.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/opto/machnode.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -489,6 +489,20 @@
 }
 #endif
 
+
+//=============================================================================
+int MachConstantNode::constant_offset() {
+  int offset = _constant.offset();
+  // Bind the offset lazily.
+  if (offset == -1) {
+    Compile::ConstantTable& constant_table = Compile::current()->constant_table();
+    offset = constant_table.table_base_offset() + constant_table.find_offset(_constant);
+    _constant.set_offset(offset);
+  }
+  return offset;
+}
+
+
 //=============================================================================
 #ifndef PRODUCT
 void MachNullCheckNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
--- a/src/share/vm/opto/machnode.hpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/opto/machnode.hpp	Thu Dec 16 20:48:11 2010 -0800
@@ -231,9 +231,6 @@
   // Return number of relocatable values contained in this instruction
   virtual int   reloc() const { return 0; }
 
-  // Return number of words used for double constants in this instruction
-  virtual int   const_size() const { return 0; }
-
   // Hash and compare over operands.  Used to do GVN on machine Nodes.
   virtual uint  hash() const;
   virtual uint  cmp( const Node &n ) const;
@@ -348,6 +345,65 @@
 #endif
 };
 
+//------------------------------MachConstantBaseNode--------------------------
+// Machine node that represents the base address of the constant table.
+class MachConstantBaseNode : public MachIdealNode {
+public:
+  static const RegMask& _out_RegMask;  // We need the out_RegMask statically in MachConstantNode::in_RegMask().
+
+public:
+  MachConstantBaseNode() : MachIdealNode() {
+    init_class_id(Class_MachConstantBase);
+  }
+  virtual const class Type* bottom_type() const { return TypeRawPtr::NOTNULL; }
+  virtual uint ideal_reg() const { return Op_RegP; }
+  virtual uint oper_input_base() const { return 1; }
+
+  virtual void emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const;
+  virtual uint size(PhaseRegAlloc* ra_) const;
+  virtual bool pinned() const { return UseRDPCForConstantTableBase; }
+
+  static const RegMask& static_out_RegMask() { return _out_RegMask; }
+  virtual const RegMask& out_RegMask() const { return static_out_RegMask(); }
+
+#ifndef PRODUCT
+  virtual const char* Name() const { return "MachConstantBaseNode"; }
+  virtual void format(PhaseRegAlloc*, outputStream* st) const;
+#endif
+};
+
+//------------------------------MachConstantNode-------------------------------
+// Machine node that holds a constant which is stored in the constant table.
+class MachConstantNode : public MachNode {
+protected:
+  Compile::Constant _constant;  // This node's constant.
+
+public:
+  MachConstantNode() : MachNode() {
+    init_class_id(Class_MachConstant);
+  }
+
+  virtual void eval_constant(Compile* C) {
+#ifdef ASSERT
+    tty->print("missing MachConstantNode eval_constant function: ");
+    dump();
+#endif
+    ShouldNotCallThis();
+  }
+
+  virtual const RegMask &in_RegMask(uint idx) const {
+    if (idx == mach_constant_base_node_input())
+      return MachConstantBaseNode::static_out_RegMask();
+    return MachNode::in_RegMask(idx);
+  }
+
+  // Input edge of MachConstantBaseNode.
+  uint mach_constant_base_node_input() const { return req() - 1; }
+
+  int  constant_offset();
+  int  constant_offset() const { return ((MachConstantNode*) this)->constant_offset(); }
+};
+
 //------------------------------MachUEPNode-----------------------------------
 // Machine Unvalidated Entry Point Node
 class MachUEPNode : public MachIdealNode {
--- a/src/share/vm/opto/matcher.hpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/opto/matcher.hpp	Thu Dec 16 20:48:11 2010 -0800
@@ -365,6 +365,10 @@
   // registers?  True for Intel but false for most RISCs
   static const bool clone_shift_expressions;
 
+  // Should constant table entries be accessed with loads using
+  // absolute addressing?  True for x86 but false for most RISCs.
+  static const bool constant_table_absolute_addressing;
+
   static bool narrow_oop_use_complex_address();
 
   // Generate implicit null check for narrow oops if it can fold
--- a/src/share/vm/opto/memnode.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/opto/memnode.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -3599,10 +3599,12 @@
     intptr_t size_limit = phase->find_intptr_t_con(size_in_bytes, max_jint);
     if (zeroes_done + BytesPerLong >= size_limit) {
       assert(allocation() != NULL, "");
-      Node* klass_node = allocation()->in(AllocateNode::KlassNode);
-      ciKlass* k = phase->type(klass_node)->is_klassptr()->klass();
-      if (zeroes_done == k->layout_helper())
-        zeroes_done = size_limit;
+      if (allocation()->Opcode() == Op_Allocate) {
+        Node* klass_node = allocation()->in(AllocateNode::KlassNode);
+        ciKlass* k = phase->type(klass_node)->is_klassptr()->klass();
+        if (zeroes_done == k->layout_helper())
+          zeroes_done = size_limit;
+      }
     }
     if (zeroes_done < size_limit) {
       rawmem = ClearArrayNode::clear_memory(rawctl, rawmem, rawptr,
--- a/src/share/vm/opto/node.hpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/opto/node.hpp	Thu Dec 16 20:48:11 2010 -0800
@@ -81,6 +81,8 @@
 class MachCallNode;
 class MachCallRuntimeNode;
 class MachCallStaticJavaNode;
+class MachConstantBaseNode;
+class MachConstantNode;
 class MachIfNode;
 class MachNode;
 class MachNullCheckNode;
@@ -566,10 +568,12 @@
               DEFINE_CLASS_ID(MachCallDynamicJava,  MachCallJava, 1)
             DEFINE_CLASS_ID(MachCallRuntime,      MachCall, 1)
               DEFINE_CLASS_ID(MachCallLeaf,         MachCallRuntime, 0)
-      DEFINE_CLASS_ID(MachSpillCopy, Mach, 1)
-      DEFINE_CLASS_ID(MachNullCheck, Mach, 2)
-      DEFINE_CLASS_ID(MachIf,        Mach, 3)
-      DEFINE_CLASS_ID(MachTemp,      Mach, 4)
+      DEFINE_CLASS_ID(MachSpillCopy,    Mach, 1)
+      DEFINE_CLASS_ID(MachNullCheck,    Mach, 2)
+      DEFINE_CLASS_ID(MachIf,           Mach, 3)
+      DEFINE_CLASS_ID(MachTemp,         Mach, 4)
+      DEFINE_CLASS_ID(MachConstantBase, Mach, 5)
+      DEFINE_CLASS_ID(MachConstant,     Mach, 6)
 
     DEFINE_CLASS_ID(Proj,  Node, 2)
       DEFINE_CLASS_ID(CatchProj, Proj, 0)
@@ -734,6 +738,8 @@
   DEFINE_CLASS_QUERY(MachCallLeaf)
   DEFINE_CLASS_QUERY(MachCallRuntime)
   DEFINE_CLASS_QUERY(MachCallStaticJava)
+  DEFINE_CLASS_QUERY(MachConstantBase)
+  DEFINE_CLASS_QUERY(MachConstant)
   DEFINE_CLASS_QUERY(MachIf)
   DEFINE_CLASS_QUERY(MachNullCheck)
   DEFINE_CLASS_QUERY(MachReturn)
--- a/src/share/vm/opto/output.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/opto/output.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -61,11 +61,6 @@
   // RootNode goes
   assert( _cfg->_broot->_nodes.size() == 0, "" );
 
-  // Initialize the space for the BufferBlob used to find and verify
-  // instruction size in MachNode::emit_size()
-  init_scratch_buffer_blob();
-  if (failing())  return; // Out of memory
-
   // The number of new nodes (mostly MachNop) is proportional to
   // the number of java calls and inner loops which are aligned.
   if ( C->check_node_count((NodeLimitFudgeFactor + C->java_calls()*3 +
@@ -333,7 +328,7 @@
 //----------------------Shorten_branches---------------------------------------
 // The architecture description provides short branch variants for some long
 // branch instructions. Replace eligible long branches with short branches.
-void Compile::Shorten_branches(Label *labels, int& code_size, int& reloc_size, int& stub_size, int& const_size) {
+void Compile::Shorten_branches(Label *labels, int& code_size, int& reloc_size, int& stub_size) {
 
   // fill in the nop array for bundling computations
   MachNode *_nop_list[Bundle::_nop_count];
@@ -353,12 +348,11 @@
   // Size in bytes of all relocation entries, including those in local stubs.
   // Start with 2-bytes of reloc info for the unvalidated entry point
   reloc_size = 1;          // Number of relocation entries
-  const_size = 0;          // size of fp constants in words
 
   // Make three passes.  The first computes pessimistic blk_starts,
-  // relative jmp_end, reloc_size and const_size information.
-  // The second performs short branch substitution using the pessimistic
-  // sizing. The third inserts nops where needed.
+  // relative jmp_end and reloc_size information.  The second performs
+  // short branch substitution using the pessimistic sizing.  The
+  // third inserts nops where needed.
 
   Node *nj; // tmp
 
@@ -381,7 +375,6 @@
         MachNode *mach = nj->as_Mach();
         blk_size += (mach->alignment_required() - 1) * relocInfo::addr_unit(); // assume worst case padding
         reloc_size += mach->reloc();
-        const_size += mach->const_size();
         if( mach->is_MachCall() ) {
           MachCallNode *mcall = mach->as_MachCall();
           // This destination address is NOT PC-relative
@@ -398,10 +391,6 @@
           if (min_offset_from_last_call == 0) {
             blk_size += nop_size;
           }
-        } else if (mach->ideal_Opcode() == Op_Jump) {
-          const_size += b->_num_succs; // Address table size
-          // The size is valid even for 64 bit since it is
-          // multiplied by 2*jintSize on this method exit.
         }
       }
       min_offset_from_last_call += inst_size;
@@ -562,10 +551,6 @@
   // a relocation index.
   // The CodeBuffer will expand the locs array if this estimate is too low.
   reloc_size   *= 10 / sizeof(relocInfo);
-
-  // Adjust const_size to number of bytes
-  const_size   *= 2*jintSize; // both float and double take two words per entry
-
 }
 
 //------------------------------FillLocArray-----------------------------------
@@ -1102,10 +1087,39 @@
     blk_labels[i].init();
   }
 
+  if (has_mach_constant_base_node()) {
+    // Fill the constant table.
+    // Note:  This must happen before Shorten_branches.
+    for (i = 0; i < _cfg->_num_blocks; i++) {
+      Block* b = _cfg->_blocks[i];
+
+      for (uint j = 0; j < b->_nodes.size(); j++) {
+        Node* n = b->_nodes[j];
+
+        // If the node is a MachConstantNode evaluate the constant
+        // value section.
+        if (n->is_MachConstant()) {
+          MachConstantNode* machcon = n->as_MachConstant();
+          machcon->eval_constant(C);
+        }
+      }
+    }
+
+    // Calculate the offsets of the constants and the size of the
+    // constant table (including the padding to the next section).
+    constant_table().calculate_offsets_and_size();
+    const_req = constant_table().size();
+  }
+
+  // Initialize the space for the BufferBlob used to find and verify
+  // instruction size in MachNode::emit_size()
+  init_scratch_buffer_blob(const_req);
+  if (failing())  return; // Out of memory
+
   // If this machine supports different size branch offsets, then pre-compute
   // the length of the blocks
   if( _matcher->is_short_branch_offset(-1, 0) ) {
-    Shorten_branches(blk_labels, code_req, locs_req, stub_req, const_req);
+    Shorten_branches(blk_labels, code_req, locs_req, stub_req);
     labels_not_set = false;
   }
 
@@ -1121,12 +1135,12 @@
     code_req = const_req = stub_req = exception_handler_req = deopt_handler_req = 0x10;  // force expansion
 
   int total_req =
+    const_req +
     code_req +
     pad_req +
     stub_req +
     exception_handler_req +
-    deopt_handler_req +              // deopt handler
-    const_req;
+    deopt_handler_req;               // deopt handler
 
   if (has_method_handle_invokes())
     total_req += deopt_handler_req;  // deopt MH handler
@@ -1180,6 +1194,11 @@
 
   NonSafepointEmitter non_safepoints(this);  // emit non-safepoints lazily
 
+  // Emit the constant table.
+  if (has_mach_constant_base_node()) {
+    constant_table().emit(*cb);
+  }
+
   // ------------------
   // Now fill in the code buffer
   Node *delay_slot = NULL;
@@ -1196,12 +1215,13 @@
       cb->flush_bundle(true);
 
     // Define the label at the beginning of the basic block
-    if( labels_not_set )
-      MacroAssembler(cb).bind( blk_labels[b->_pre_order] );
-
-    else
-      assert( blk_labels[b->_pre_order].loc_pos() == cb->insts_size(),
-              "label position does not match code offset" );
+    if (labels_not_set) {
+      MacroAssembler(cb).bind(blk_labels[b->_pre_order]);
+    } else {
+      assert(blk_labels[b->_pre_order].loc_pos() == cb->insts_size(),
+             err_msg("label position does not match code offset: %d != %d",
+                     blk_labels[b->_pre_order].loc_pos(), cb->insts_size()));
+    }
 
     uint last_inst = b->_nodes.size();
 
@@ -1718,9 +1738,17 @@
   // Create a data structure for all the scheduling information
   Scheduling scheduling(Thread::current()->resource_area(), *this);
 
+  // Initialize the space for the BufferBlob used to find and verify
+  // instruction size in MachNode::emit_size()
+  init_scratch_buffer_blob(MAX_const_size);
+  if (failing())  return;  // Out of memory
+
   // Walk backwards over each basic block, computing the needed alignment
   // Walk over all the basic blocks
   scheduling.DoScheduling();
+
+  // Clear the BufferBlob used for scheduling.
+  clear_scratch_buffer_blob();
 }
 
 //------------------------------ComputeLocalLatenciesForward-------------------
--- a/src/share/vm/opto/postaloc.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/opto/postaloc.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -200,6 +200,19 @@
   // then reloaded BUT survives in a register the whole way.
   Node *val = skip_copies(n->in(k));
 
+  if (val == x && nk_idx != 0 &&
+      regnd[nk_reg] != NULL && regnd[nk_reg] != x &&
+      n2lidx(x) == n2lidx(regnd[nk_reg])) {
+    // When rematerialzing nodes and stretching lifetimes, the
+    // allocator will reuse the original def for multidef LRG instead
+    // of the current reaching def because it can't know it's safe to
+    // do so.  After allocation completes if they are in the same LRG
+    // then it should use the current reaching def instead.
+    n->set_req(k, regnd[nk_reg]);
+    blk_adjust += yank_if_dead(val, current_block, &value, &regnd);
+    val = skip_copies(n->in(k));
+  }
+
   if( val == x ) return blk_adjust; // No progress?
 
   bool single = is_single_register(val->ideal_reg());
--- a/src/share/vm/opto/reg_split.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/opto/reg_split.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -1239,6 +1239,7 @@
   // Cycle through this block's predecessors, collecting Reaches
   // info for each spilled LRG and update edges.
   // Walk the phis list to patch inputs, split phis, and name phis
+  uint lrgs_before_phi_split = maxlrg;
   for( insidx = 0; insidx < phis->size(); insidx++ ) {
     Node *phi = phis->at(insidx);
     assert(phi->is_Phi(),"This list must only contain Phi Nodes");
@@ -1273,7 +1274,16 @@
       assert( def, "must have reaching def" );
       // If input up/down sense and reg-pressure DISagree
       if( def->rematerialize() ) {
-        def = split_Rematerialize( def, pred, pred->end_idx(), maxlrg, splits, slidx, lrg2reach, Reachblock, false );
+        // Place the rematerialized node above any MSCs created during
+        // phi node splitting.  end_idx points at the insertion point
+        // so look at the node before it.
+        int insert = pred->end_idx();
+        while (insert >= 1 &&
+               pred->_nodes[insert - 1]->is_SpillCopy() &&
+               Find(pred->_nodes[insert - 1]) >= lrgs_before_phi_split) {
+          insert--;
+        }
+        def = split_Rematerialize( def, pred, insert, maxlrg, splits, slidx, lrg2reach, Reachblock, false );
         if( !def ) return 0;    // Bail out
       }
       // Update the Phi's input edge array
--- a/src/share/vm/prims/jvm.h	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/prims/jvm.h	Thu Dec 16 20:48:11 2010 -0800
@@ -1063,7 +1063,8 @@
     JVM_CONSTANT_MethodHandle           = 15,  // JSR 292
     JVM_CONSTANT_MethodType             = 16,  // JSR 292
     JVM_CONSTANT_InvokeDynamicTrans     = 17,  // JSR 292, only occurs in old class files
-    JVM_CONSTANT_InvokeDynamic          = 18   // JSR 292
+    JVM_CONSTANT_InvokeDynamic          = 18,  // JSR 292
+    JVM_CONSTANT_ExternalMax            = 18   // Last tag found in classfiles
 };
 
 /* JVM_CONSTANT_MethodHandle subtypes */
--- a/src/share/vm/prims/jvmti.xml	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/prims/jvmti.xml	Thu Dec 16 20:48:11 2010 -0800
@@ -5649,6 +5649,45 @@
       </errors>
     </function>
 
+    <function id="GetLocalInstance" num="155" since="1.2">
+      <synopsis>Get Local Instance</synopsis>
+      <description>
+        This function can be used to retrieve the value of the local object
+        variable at slot 0 (the "<code>this</code>" object) from non-static
+        frames.  This function can retrieve the "<code>this</code>" object from
+        native method frames, whereas <code>GetLocalObject()</code> would 
+        return <code>JVMTI_ERROR_OPAQUE_FRAME</code> in those cases.
+      </description>
+      <origin>new</origin>
+      <capabilities>
+	<required id="can_access_local_variables"></required>
+      </capabilities>
+      <parameters>
+ 	<param id="thread">
+	  <jthread null="current" frame="frame"/>
+	  <description>
+	    The thread of the frame containing the variable's value.
+	  </description>
+	</param>
+	<param id="depth">
+	  <jframeID thread="thread"/>
+	  <description>
+	    The depth of the frame containing the variable's value.
+	  </description>
+	</param>
+	<param id="value_ptr">
+	  <outptr><jobject/></outptr>
+	    <description>
+	      On return, points to the variable's value. 
+	    </description>
+	</param>
+      </parameters>
+      <errors>
+	<error id="JVMTI_ERROR_INVALID_SLOT">
+	  If the specified frame is a static method frame.
+	</error>
+      </errors>
+    </function>
     <function id="GetLocalInt" num="22">
       <synopsis>Get Local Variable - Int</synopsis>
       <description>
--- a/src/share/vm/prims/jvmtiEnv.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/prims/jvmtiEnv.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -1796,6 +1796,29 @@
   }
 } /* end GetLocalObject */
 
+// Threads_lock NOT held, java_thread not protected by lock
+// java_thread - pre-checked
+// java_thread - unchecked
+// depth - pre-checked as non-negative
+// value - pre-checked for NULL
+jvmtiError
+JvmtiEnv::GetLocalInstance(JavaThread* java_thread, jint depth, jobject* value){
+  JavaThread* current_thread = JavaThread::current();
+  // rm object is created to clean up the javaVFrame created in
+  // doit_prologue(), but after doit() is finished with it.
+  ResourceMark rm(current_thread);
+
+  VM_GetReceiver op(java_thread, current_thread, depth);
+  VMThread::execute(&op);
+  jvmtiError err = op.result();
+  if (err != JVMTI_ERROR_NONE) {
+    return err;
+  } else {
+    *value = op.value().l;
+    return JVMTI_ERROR_NONE;
+  }
+} /* end GetLocalInstance */
+
 
 // Threads_lock NOT held, java_thread not protected by lock
 // java_thread - pre-checked
--- a/src/share/vm/prims/jvmtiImpl.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/prims/jvmtiImpl.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -586,7 +586,6 @@
 {
 }
 
-
 vframe *VM_GetOrSetLocal::get_vframe() {
   if (!_thread->has_last_Java_frame()) {
     return NULL;
@@ -609,7 +608,7 @@
   }
   javaVFrame *jvf = (javaVFrame*)vf;
 
-  if (!vf->is_java_frame() || jvf->method()->is_native()) {
+  if (!vf->is_java_frame()) {
     _result = JVMTI_ERROR_OPAQUE_FRAME;
     return NULL;
   }
@@ -740,6 +739,15 @@
   _jvf = get_java_vframe();
   NULL_CHECK(_jvf, false);
 
+  if (_jvf->method()->is_native()) {
+    if (getting_receiver() && !_jvf->method()->is_static()) {
+      return true;
+    } else {
+      _result = JVMTI_ERROR_OPAQUE_FRAME;
+      return false;
+    }
+  }
+
   if (!check_slot_type(_jvf)) {
     return false;
   }
@@ -781,40 +789,46 @@
     HandleMark hm;
 
     switch (_type) {
-    case T_INT:    locals->set_int_at   (_index, _value.i); break;
-    case T_LONG:   locals->set_long_at  (_index, _value.j); break;
-    case T_FLOAT:  locals->set_float_at (_index, _value.f); break;
-    case T_DOUBLE: locals->set_double_at(_index, _value.d); break;
-    case T_OBJECT: {
-      Handle ob_h(JNIHandles::resolve_external_guard(_value.l));
-      locals->set_obj_at (_index, ob_h);
-      break;
-    }
-    default: ShouldNotReachHere();
+      case T_INT:    locals->set_int_at   (_index, _value.i); break;
+      case T_LONG:   locals->set_long_at  (_index, _value.j); break;
+      case T_FLOAT:  locals->set_float_at (_index, _value.f); break;
+      case T_DOUBLE: locals->set_double_at(_index, _value.d); break;
+      case T_OBJECT: {
+        Handle ob_h(JNIHandles::resolve_external_guard(_value.l));
+        locals->set_obj_at (_index, ob_h);
+        break;
+      }
+      default: ShouldNotReachHere();
     }
     _jvf->set_locals(locals);
   } else {
-    StackValueCollection *locals = _jvf->locals();
+    if (_jvf->method()->is_native() && _jvf->is_compiled_frame()) {
+      assert(getting_receiver(), "Can only get here when getting receiver");
+      oop receiver = _jvf->fr().get_native_receiver();
+      _value.l = JNIHandles::make_local(_calling_thread, receiver);
+    } else {
+      StackValueCollection *locals = _jvf->locals();
 
-    if (locals->at(_index)->type() == T_CONFLICT) {
-      memset(&_value, 0, sizeof(_value));
-      _value.l = NULL;
-      return;
-    }
+      if (locals->at(_index)->type() == T_CONFLICT) {
+        memset(&_value, 0, sizeof(_value));
+        _value.l = NULL;
+        return;
+      }
 
-    switch (_type) {
-    case T_INT:    _value.i = locals->int_at   (_index);   break;
-    case T_LONG:   _value.j = locals->long_at  (_index);   break;
-    case T_FLOAT:  _value.f = locals->float_at (_index);   break;
-    case T_DOUBLE: _value.d = locals->double_at(_index);   break;
-    case T_OBJECT: {
-      // Wrap the oop to be returned in a local JNI handle since
-      // oops_do() no longer applies after doit() is finished.
-      oop obj = locals->obj_at(_index)();
-      _value.l = JNIHandles::make_local(_calling_thread, obj);
-      break;
-    }
-    default: ShouldNotReachHere();
+      switch (_type) {
+        case T_INT:    _value.i = locals->int_at   (_index);   break;
+        case T_LONG:   _value.j = locals->long_at  (_index);   break;
+        case T_FLOAT:  _value.f = locals->float_at (_index);   break;
+        case T_DOUBLE: _value.d = locals->double_at(_index);   break;
+        case T_OBJECT: {
+          // Wrap the oop to be returned in a local JNI handle since
+          // oops_do() no longer applies after doit() is finished.
+          oop obj = locals->obj_at(_index)();
+          _value.l = JNIHandles::make_local(_calling_thread, obj);
+          break;
+        }
+        default: ShouldNotReachHere();
+      }
     }
   }
 }
@@ -825,6 +839,10 @@
 }
 
 
+VM_GetReceiver::VM_GetReceiver(
+    JavaThread* thread, JavaThread* caller_thread, jint depth)
+    : VM_GetOrSetLocal(thread, caller_thread, depth, 0) {}
+
 /////////////////////////////////////////////////////////////////////////////////////////
 
 //
--- a/src/share/vm/prims/jvmtiImpl.hpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/prims/jvmtiImpl.hpp	Thu Dec 16 20:48:11 2010 -0800
@@ -355,7 +355,7 @@
 // to the thread simultaneously.
 //
 class VM_GetOrSetLocal : public VM_Operation {
-private:
+ protected:
   JavaThread* _thread;
   JavaThread* _calling_thread;
   jint        _depth;
@@ -365,6 +365,10 @@
   javaVFrame* _jvf;
   bool        _set;
 
+  // It is possible to get the receiver out of a non-static native wrapper
+  // frame.  Use VM_GetReceiver to do this.
+  virtual bool getting_receiver() const { return false; }
+
   jvmtiError  _result;
 
   vframe* get_vframe();
@@ -395,6 +399,15 @@
   static bool is_assignable(const char* ty_sign, Klass* klass, Thread* thread);
 };
 
+class VM_GetReceiver : public VM_GetOrSetLocal {
+ protected:
+  virtual bool getting_receiver() const { return true; }
+
+ public:
+  VM_GetReceiver(JavaThread* thread, JavaThread* calling_thread, jint depth);
+  const char* name() const                       { return "get receiver"; }
+};
+
 
 ///////////////////////////////////////////////////////////////
 //
--- a/src/share/vm/prims/jvmtiRedefineClasses.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/prims/jvmtiRedefineClasses.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -214,7 +214,7 @@
     case JVM_CONSTANT_Double:  // fall through
     case JVM_CONSTANT_Long:
     {
-      scratch_cp->copy_entry_to(scratch_i, *merge_cp_p, *merge_cp_length_p,
+      constantPoolOopDesc::copy_entry_to(scratch_cp, scratch_i, *merge_cp_p, *merge_cp_length_p,
         THREAD);
 
       if (scratch_i != *merge_cp_length_p) {
@@ -239,7 +239,7 @@
     case JVM_CONSTANT_UnresolvedClass:  // fall through
     case JVM_CONSTANT_UnresolvedString:
     {
-      scratch_cp->copy_entry_to(scratch_i, *merge_cp_p, *merge_cp_length_p,
+      constantPoolOopDesc::copy_entry_to(scratch_cp, scratch_i, *merge_cp_p, *merge_cp_length_p,
         THREAD);
 
       if (scratch_i != *merge_cp_length_p) {
@@ -1093,13 +1093,13 @@
       case JVM_CONSTANT_Long:
         // just copy the entry to *merge_cp_p, but double and long take
         // two constant pool entries
-        old_cp->copy_entry_to(old_i, *merge_cp_p, old_i, CHECK_0);
+        constantPoolOopDesc::copy_entry_to(old_cp, old_i, *merge_cp_p, old_i, CHECK_0);
         old_i++;
         break;
 
       default:
         // just copy the entry to *merge_cp_p
-        old_cp->copy_entry_to(old_i, *merge_cp_p, old_i, CHECK_0);
+        constantPoolOopDesc::copy_entry_to(old_cp, old_i, *merge_cp_p, old_i, CHECK_0);
         break;
       }
     } // end for each old_cp entry
--- a/src/share/vm/prims/methodHandleWalk.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/prims/methodHandleWalk.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -968,16 +968,11 @@
 
   if (tailcall) {
     // Actually, in order to make these methods more recognizable,
-    // let's put them in holder classes MethodHandle and InvokeDynamic.
-    // That way stack walkers and compiler heuristics can recognize them.
-    _target_klass = (for_invokedynamic()
-                     ? SystemDictionary::InvokeDynamic_klass()
-                     : SystemDictionary::MethodHandle_klass());
+    // let's put them in holder class MethodHandle.  That way stack
+    // walkers and compiler heuristics can recognize them.
+    _target_klass = SystemDictionary::MethodHandle_klass();
   }
 
-  // instanceKlass* ik = instanceKlass::cast(klass);
-  // tty->print_cr("MethodHandleCompiler::make_invoke: %s %s.%s%s", Bytecodes::name(op), ik->external_name(), name->as_C_string(), signature->as_C_string());
-
   // Inline the method.
   InvocationCounter* ic = m->invocation_counter();
   ic->set_carry_flag();
--- a/src/share/vm/prims/methodHandleWalk.hpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/prims/methodHandleWalk.hpp	Thu Dec 16 20:48:11 2010 -0800
@@ -412,8 +412,7 @@
 
   // Tests if the given class is a MH adapter holder.
   static bool klass_is_method_handle_adapter_holder(klassOop klass) {
-    return (klass == SystemDictionary::MethodHandle_klass() ||
-            klass == SystemDictionary::InvokeDynamic_klass());
+    return (klass == SystemDictionary::MethodHandle_klass());
   }
 };
 
--- a/src/share/vm/prims/methodHandles.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/prims/methodHandles.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -485,9 +485,8 @@
   Handle polymorphic_method_type;
   bool polymorphic_signature = false;
   if ((flags & ALL_KINDS) == IS_METHOD &&
-      (defc() == SystemDictionary::InvokeDynamic_klass() ||
-       (defc() == SystemDictionary::MethodHandle_klass() &&
-        methodOopDesc::is_method_handle_invoke_name(name()))))
+      (defc() == SystemDictionary::MethodHandle_klass() &&
+       methodOopDesc::is_method_handle_invoke_name(name())))
     polymorphic_signature = true;
 
   // convert the external string or reflective type to an internal signature
--- a/src/share/vm/runtime/arguments.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/runtime/arguments.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -1007,24 +1007,9 @@
 void Arguments::check_compressed_oops_compat() {
 #ifdef _LP64
   assert(UseCompressedOops, "Precondition");
-#  if defined(COMPILER1) && !defined(TIERED)
-  // Until c1 supports compressed oops turn them off.
-  FLAG_SET_DEFAULT(UseCompressedOops, false);
-#  else
   // Is it on by default or set on ergonomically
   bool is_on_by_default = FLAG_IS_DEFAULT(UseCompressedOops) || FLAG_IS_ERGO(UseCompressedOops);
 
-  // Tiered currently doesn't work with compressed oops
-  if (TieredCompilation) {
-    if (is_on_by_default) {
-      FLAG_SET_DEFAULT(UseCompressedOops, false);
-      return;
-    } else {
-      vm_exit_during_initialization(
-        "Tiered compilation is not supported with compressed oops yet", NULL);
-    }
-  }
-
   // If dumping an archive or forcing its use, disable compressed oops if possible
   if (DumpSharedSpaces || RequireSharedSpaces) {
     if (is_on_by_default) {
@@ -1038,9 +1023,7 @@
     // UseSharedSpaces is on by default. With compressed oops, we turn it off.
     FLAG_SET_DEFAULT(UseSharedSpaces, false);
   }
-
-#  endif // defined(COMPILER1) && !defined(TIERED)
-#endif // _LP64
+#endif
 }
 
 void Arguments::set_tiered_flags() {
@@ -3075,11 +3058,9 @@
   // Set flags based on ergonomics.
   set_ergonomics_flags();
 
-#ifdef _LP64
   if (UseCompressedOops) {
     check_compressed_oops_compat();
   }
-#endif
 
   // Check the GC selections again.
   if (!check_gc_consistency()) {
--- a/src/share/vm/runtime/frame.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/runtime/frame.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -41,6 +41,8 @@
 #include "runtime/signature.hpp"
 #include "runtime/stubCodeGenerator.hpp"
 #include "runtime/stubRoutines.hpp"
+#include "utilities/decoder.hpp"
+
 #ifdef TARGET_ARCH_x86
 # include "nativeInst_x86.hpp"
 #endif
@@ -652,7 +654,7 @@
   // names if pc is within jvm.dll or libjvm.so, because JVM only has
   // JVM_xxxx and a few other symbols in the dynamic symbol table. Do this
   // only for native libraries.
-  if (!in_vm) {
+  if (!in_vm || Decoder::can_decode_C_frame_in_vm()) {
     found = os::dll_address_to_function_name(pc, buf, buflen, &offset);
 
     if (found) {
@@ -1071,28 +1073,20 @@
   }
 }
 
-BasicLock* frame::compiled_synchronized_native_monitor(nmethod* nm) {
-  if (nm == NULL) {
-    assert(_cb != NULL && _cb->is_nmethod() &&
-           nm->method()->is_native() &&
-           nm->method()->is_synchronized(),
-           "should not call this otherwise");
-    nm = (nmethod*) _cb;
-  }
-  int byte_offset = in_bytes(nm->compiled_synchronized_native_basic_lock_sp_offset());
+BasicLock* frame::get_native_monitor() {
+  nmethod* nm = (nmethod*)_cb;
+  assert(_cb != NULL && _cb->is_nmethod() && nm->method()->is_native(),
+         "Should not call this unless it's a native nmethod");
+  int byte_offset = in_bytes(nm->native_basic_lock_sp_offset());
   assert(byte_offset >= 0, "should not see invalid offset");
   return (BasicLock*) &sp()[byte_offset / wordSize];
 }
 
-oop frame::compiled_synchronized_native_monitor_owner(nmethod* nm) {
-  if (nm == NULL) {
-    assert(_cb != NULL && _cb->is_nmethod() &&
-           nm->method()->is_native() &&
-           nm->method()->is_synchronized(),
-           "should not call this otherwise");
-    nm = (nmethod*) _cb;
-  }
-  int byte_offset = in_bytes(nm->compiled_synchronized_native_basic_lock_owner_sp_offset());
+oop frame::get_native_receiver() {
+  nmethod* nm = (nmethod*)_cb;
+  assert(_cb != NULL && _cb->is_nmethod() && nm->method()->is_native(),
+         "Should not call this unless it's a native nmethod");
+  int byte_offset = in_bytes(nm->native_receiver_sp_offset());
   assert(byte_offset >= 0, "should not see invalid offset");
   oop owner = ((oop*) sp())[byte_offset / wordSize];
   assert( Universe::heap()->is_in(owner), "bad receiver" );
--- a/src/share/vm/runtime/frame.hpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/runtime/frame.hpp	Thu Dec 16 20:48:11 2010 -0800
@@ -254,10 +254,10 @@
 
   // Return the monitor owner and BasicLock for compiled synchronized
   // native methods so that biased locking can revoke the receiver's
-  // bias if necessary. Takes optional nmethod for this frame as
-  // argument to avoid performing repeated lookups in code cache.
-  BasicLock* compiled_synchronized_native_monitor      (nmethod* nm = NULL);
-  oop        compiled_synchronized_native_monitor_owner(nmethod* nm = NULL);
+  // bias if necessary.  This is also used by JVMTI's GetLocalInstance method
+  // (via VM_GetReceiver) to retrieve the receiver from a native wrapper frame.
+  BasicLock* get_native_monitor();
+  oop        get_native_receiver();
 
   // Find receiver for an invoke when arguments are just pushed on stack (i.e., callee stack-frame is
   // not setup)
--- a/src/share/vm/runtime/thread.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/runtime/thread.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -3231,12 +3231,6 @@
       warning("java.lang.ArithmeticException has not been initialized");
       warning("java.lang.StackOverflowError has not been initialized");
     }
-
-    if (EnableInvokeDynamic) {
-      // JSR 292: An intialized java.dyn.InvokeDynamic is required in
-      // the compiler.
-      initialize_class(vmSymbolHandles::java_dyn_InvokeDynamic(), CHECK_0);
-    }
   }
 
   // See        : bugid 4211085.
--- a/src/share/vm/runtime/vframe_hp.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/runtime/vframe_hp.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -207,8 +207,8 @@
     GrowableArray<MonitorInfo*> *monitors = new GrowableArray<MonitorInfo*>(1);
     // Casting away const
     frame& fr = (frame&) _fr;
-    MonitorInfo* info = new MonitorInfo(fr.compiled_synchronized_native_monitor_owner(nm),
-                                        fr.compiled_synchronized_native_monitor(nm), false, false);
+    MonitorInfo* info = new MonitorInfo(
+        fr.get_native_receiver(), fr.get_native_monitor(), false, false);
     monitors->push(info);
     return monitors;
   }
--- a/src/share/vm/runtime/vmStructs.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/runtime/vmStructs.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -1676,10 +1676,7 @@
   /* constantPoolOop layout enum for InvokeDynamic */                     \
   /*************************************************/                     \
                                                                           \
-  declare_constant(constantPoolOopDesc::_multi_operand_count_offset)      \
-  declare_constant(constantPoolOopDesc::_multi_operand_base_offset)       \
   declare_constant(constantPoolOopDesc::_indy_bsm_offset)                 \
-  declare_constant(constantPoolOopDesc::_indy_nt_offset)                  \
   declare_constant(constantPoolOopDesc::_indy_argc_offset)                \
   declare_constant(constantPoolOopDesc::_indy_argv_offset)                \
                                                                           \
--- a/src/share/vm/utilities/constantTag.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/utilities/constantTag.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -93,6 +93,8 @@
       return "MethodType";
     case JVM_CONSTANT_InvokeDynamic :
       return "InvokeDynamic";
+    case JVM_CONSTANT_InvokeDynamicTrans :
+      return "InvokeDynamic/transitional";
     case JVM_CONSTANT_Object :
       return "Object";
     case JVM_CONSTANT_Utf8 :
--- a/src/share/vm/utilities/constantTag.hpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/utilities/constantTag.hpp	Thu Dec 16 20:48:11 2010 -0800
@@ -86,7 +86,8 @@
 
   bool is_method_type() const              { return _tag == JVM_CONSTANT_MethodType; }
   bool is_method_handle() const            { return _tag == JVM_CONSTANT_MethodHandle; }
-  bool is_invoke_dynamic() const           { return _tag == JVM_CONSTANT_InvokeDynamic; }
+  bool is_invoke_dynamic() const           { return (_tag == JVM_CONSTANT_InvokeDynamic ||
+                                                     _tag == JVM_CONSTANT_InvokeDynamicTrans); }
 
   bool is_loadable_constant() const {
     return ((_tag >= JVM_CONSTANT_Integer && _tag <= JVM_CONSTANT_String) ||
--- a/src/share/vm/utilities/debug.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/utilities/debug.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -399,8 +399,14 @@
 extern "C" void disnm(intptr_t p) {
   Command c("disnm");
   CodeBlob* cb = CodeCache::find_blob((address) p);
-  cb->print();
-  Disassembler::decode(cb);
+  nmethod* nm = cb->as_nmethod_or_null();
+  if (nm) {
+    nm->print();
+    Disassembler::decode(nm);
+  } else {
+    cb->print();
+    Disassembler::decode(cb);
+  }
 }
 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/utilities/decoder.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "prims/jvm.h"
+#include "utilities/decoder.hpp"
+
+Decoder::decoder_status  Decoder::_decoder_status = Decoder::no_error;
+bool                     Decoder::_initialized = false;
+
+#ifndef _WINDOWS
+
+// Implementation of common functionalities among Solaris and Linux
+#include "utilities/elfFile.hpp"
+
+ElfFile* Decoder::_opened_elf_files = NULL;
+
+bool Decoder::can_decode_C_frame_in_vm() {
+  return true;
+}
+
+void Decoder::initialize() {
+  _initialized = true;
+}
+
+void Decoder::uninitialize() {
+  if (_opened_elf_files != NULL) {
+    delete _opened_elf_files;
+    _opened_elf_files = NULL;
+  }
+  _initialized = false;
+}
+
+Decoder::decoder_status Decoder::decode(address addr, const char* filepath, char *buf, int buflen, int *offset) {
+  if (_decoder_status != no_error) {
+    return _decoder_status;
+  }
+
+  ElfFile* file = get_elf_file(filepath);
+  if (_decoder_status != no_error) {
+    return _decoder_status;
+  }
+
+  const char* symbol = file->decode(addr, offset);
+  if (file->get_status() == out_of_memory) {
+    _decoder_status = out_of_memory;
+    return _decoder_status;
+  } else if (symbol != NULL) {
+    if (!demangle(symbol, buf, buflen)) {
+      jio_snprintf(buf, buflen, "%s", symbol);
+    }
+    return no_error;
+  } else {
+    return symbol_not_found;
+  }
+}
+
+ElfFile* Decoder::get_elf_file(const char* filepath) {
+  if (_decoder_status != no_error) {
+    return NULL;
+  }
+  ElfFile* file = _opened_elf_files;
+  while (file != NULL) {
+    if (file->same_elf_file(filepath)) {
+      return file;
+    }
+    file = file->m_next;
+  }
+
+  file = new ElfFile(filepath);
+  if (file == NULL) {
+    _decoder_status = out_of_memory;
+  }
+  if (_opened_elf_files != NULL) {
+    file->m_next = _opened_elf_files;
+  }
+
+  _opened_elf_files = file;
+  return file;
+}
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/utilities/decoder.hpp	Thu Dec 16 20:48:11 2010 -0800
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+
+#ifndef __DECODER_HPP
+#define __DECODER_HPP
+
+#include "memory/allocation.hpp"
+
+#ifdef _WINDOWS
+#include <windows.h>
+#include <imagehlp.h>
+
+// functions needed for decoding symbols
+typedef DWORD (WINAPI *pfn_SymSetOptions)(DWORD);
+typedef BOOL  (WINAPI *pfn_SymInitialize)(HANDLE, PCTSTR, BOOL);
+typedef BOOL  (WINAPI *pfn_SymGetSymFromAddr64)(HANDLE, DWORD64, PDWORD64, PIMAGEHLP_SYMBOL64);
+typedef DWORD (WINAPI *pfn_UndecorateSymbolName)(const char*, char*, DWORD, DWORD);
+
+#else
+
+class ElfFile;
+
+#endif // _WINDOWS
+
+
+class Decoder: public StackObj {
+
+ public:
+  // status code for decoding native C frame
+  enum decoder_status {
+         no_error,             // successfully decoded frames
+         out_of_memory,        // out of memory
+         file_invalid,         // invalid elf file
+         file_not_found,       // could not found symbol file (on windows), such as jvm.pdb or jvm.map
+         helper_not_found,     // could not load dbghelp.dll (Windows only)
+         helper_func_error,    // decoding functions not found (Windows only)
+         helper_init_error,    // SymInitialize failed (Windows only)
+         symbol_not_found      // could not find the symbol
+  };
+
+ public:
+  Decoder() { initialize(); };
+  ~Decoder() { uninitialize(); };
+
+  static bool can_decode_C_frame_in_vm();
+
+  static void initialize();
+  static void uninitialize();
+
+#ifdef _WINDOWS
+  static decoder_status    decode(address addr, char *buf, int buflen, int *offset);
+#else
+  static decoder_status    decode(address addr, const char* filepath, char *buf, int buflen, int *offset);
+#endif
+
+  static bool              demangle(const char* symbol, char *buf, int buflen);
+
+  static decoder_status    get_status() { return _decoder_status; };
+
+#ifndef _WINDOWS
+ private:
+  static ElfFile*         get_elf_file(const char* filepath);
+#endif // _WINDOWS
+
+
+ private:
+  static decoder_status     _decoder_status;
+  static bool               _initialized;
+
+#ifdef _WINDOWS
+  static HMODULE                   _dbghelp_handle;
+  static bool                      _can_decode_in_vm;
+  static pfn_SymGetSymFromAddr64   _pfnSymGetSymFromAddr64;
+  static pfn_UndecorateSymbolName  _pfnUndecorateSymbolName;
+#else
+  static ElfFile*                  _opened_elf_files;
+#endif // _WINDOWS
+};
+
+#endif // __DECODER_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/utilities/elfFile.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+
+#ifndef _WINDOWS
+
+#include <string.h>
+#include <stdio.h>
+#include <limits.h>
+
+#include "memory/allocation.inline.hpp"
+#include "utilities/decoder.hpp"
+#include "utilities/elfFile.hpp"
+#include "utilities/elfStringTable.hpp"
+#include "utilities/elfSymbolTable.hpp"
+
+
+ElfFile::ElfFile(const char* filepath) {
+  assert(filepath, "null file path");
+  memset(&m_elfHdr, 0, sizeof(m_elfHdr));
+  m_string_tables = NULL;
+  m_symbol_tables = NULL;
+  m_next = NULL;
+  m_status = Decoder::no_error;
+
+  int len = strlen(filepath) + 1;
+  m_filepath = NEW_C_HEAP_ARRAY(char, len);
+  if (m_filepath != NULL) {
+    strcpy((char*)m_filepath, filepath);
+    m_file = fopen(filepath, "r");
+    if (m_file != NULL) {
+      load_tables();
+    } else {
+      m_status = Decoder::file_not_found;
+    }
+  } else {
+    m_status = Decoder::out_of_memory;
+  }
+}
+
+ElfFile::~ElfFile() {
+  if (m_string_tables != NULL) {
+    delete m_string_tables;
+  }
+
+  if (m_symbol_tables != NULL) {
+    delete m_symbol_tables;
+  }
+
+  if (m_file != NULL) {
+    fclose(m_file);
+  }
+
+  if (m_filepath != NULL) {
+    FREE_C_HEAP_ARRAY(char, m_filepath);
+  }
+
+  if (m_next != NULL) {
+    delete m_next;
+  }
+};
+
+
+//Check elf header to ensure the file is valid.
+bool ElfFile::is_elf_file(Elf_Ehdr& hdr) {
+  return (ELFMAG0 == hdr.e_ident[EI_MAG0] &&
+      ELFMAG1 == hdr.e_ident[EI_MAG1] &&
+      ELFMAG2 == hdr.e_ident[EI_MAG2] &&
+      ELFMAG3 == hdr.e_ident[EI_MAG3] &&
+      ELFCLASSNONE != hdr.e_ident[EI_CLASS] &&
+      ELFDATANONE != hdr.e_ident[EI_DATA]);
+}
+
+bool ElfFile::load_tables() {
+  assert(m_file, "file not open");
+  assert(m_status == Decoder::no_error, "already in error");
+
+  // read elf file header
+  if (fread(&m_elfHdr, sizeof(m_elfHdr), 1, m_file) != 1) {
+    m_status = Decoder::file_invalid;
+    return false;
+  }
+
+  if (!is_elf_file(m_elfHdr)) {
+    m_status = Decoder::file_invalid;
+    return false;
+  }
+
+  // walk elf file's section headers, and load string tables
+  Elf_Shdr shdr;
+  if (!fseek(m_file, m_elfHdr.e_shoff, SEEK_SET)) {
+    if (m_status != Decoder::no_error) return false;
+
+    for (int index = 0; index < m_elfHdr.e_shnum; index ++) {
+      if (fread((void*)&shdr, sizeof(Elf_Shdr), 1, m_file) != 1) {
+        m_status = Decoder::file_invalid;
+        return false;
+      }
+      // string table
+      if (shdr.sh_type == SHT_STRTAB) {
+        ElfStringTable* table = new ElfStringTable(m_file, shdr, index);
+        if (table == NULL) {
+          m_status = Decoder::out_of_memory;
+          return false;
+        }
+        add_string_table(table);
+      } else if (shdr.sh_type == SHT_SYMTAB || shdr.sh_type == SHT_DYNSYM) {
+        ElfSymbolTable* table = new ElfSymbolTable(m_file, shdr);
+        if (table == NULL) {
+          m_status = Decoder::out_of_memory;
+          return false;
+        }
+        add_symbol_table(table);
+      }
+    }
+  }
+  return true;
+}
+
+const char* ElfFile::decode(address addr, int* offset) {
+  // something already went wrong, just give up
+  if (m_status != Decoder::no_error) {
+    return NULL;
+  }
+
+  ElfSymbolTable* symbol_table = m_symbol_tables;
+  int string_table_index;
+  int pos_in_string_table;
+  int off = INT_MAX;
+  bool found_symbol = false;
+  while (symbol_table != NULL) {
+    if (Decoder::no_error == symbol_table->lookup(addr, &string_table_index, &pos_in_string_table, &off)) {
+      found_symbol = true;
+    }
+    symbol_table = symbol_table->m_next;
+  }
+  if (!found_symbol) return NULL;
+
+  ElfStringTable* string_table = get_string_table(string_table_index);
+  if (string_table == NULL) {
+    m_status = Decoder::file_invalid;
+    return NULL;
+  }
+  if (offset) *offset = off;
+  return string_table->string_at(pos_in_string_table);
+}
+
+
+void ElfFile::add_symbol_table(ElfSymbolTable* table) {
+  if (m_symbol_tables == NULL) {
+    m_symbol_tables = table;
+  } else {
+    table->m_next = m_symbol_tables;
+    m_symbol_tables = table;
+  }
+}
+
+void ElfFile::add_string_table(ElfStringTable* table) {
+  if (m_string_tables == NULL) {
+    m_string_tables = table;
+  } else {
+    table->m_next = m_string_tables;
+    m_string_tables = table;
+  }
+}
+
+ElfStringTable* ElfFile::get_string_table(int index) {
+  ElfStringTable* p = m_string_tables;
+  while (p != NULL) {
+    if (p->index() == index) return p;
+    p = p->m_next;
+  }
+  return NULL;
+}
+
+#endif // _WINDOWS
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/utilities/elfFile.hpp	Thu Dec 16 20:48:11 2010 -0800
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef __ELF_FILE_HPP
+#define __ELF_FILE_HPP
+
+#ifndef _WINDOWS
+
+#include <elf.h>
+#include <stdio.h>
+
+#ifdef _LP64
+
+typedef Elf64_Half      Elf_Half;
+typedef Elf64_Word      Elf_Word;
+typedef Elf64_Off       Elf_Off;
+typedef Elf64_Addr      Elf_Addr;
+
+typedef Elf64_Ehdr      Elf_Ehdr;
+typedef Elf64_Shdr      Elf_Shdr;
+typedef Elf64_Sym       Elf_Sym;
+
+#define ELF_ST_TYPE ELF64_ST_TYPE
+
+#else
+
+typedef Elf32_Half      Elf_Half;
+typedef Elf32_Word      Elf_Word;
+typedef Elf32_Off       Elf_Off;
+typedef Elf32_Addr      Elf_Addr;
+
+
+typedef Elf32_Ehdr      Elf_Ehdr;
+typedef Elf32_Shdr      Elf_Shdr;
+typedef Elf32_Sym       Elf_Sym;
+
+#define ELF_ST_TYPE ELF32_ST_TYPE
+#endif
+
+#include "globalDefinitions.hpp"
+#include "memory/allocation.hpp"
+#include "utilities/decoder.hpp"
+
+
+class ElfStringTable;
+class ElfSymbolTable;
+
+
+// On Solaris/Linux platforms, libjvm.so does contain all private symbols.
+// ElfFile is basically an elf file parser, which can lookup the symbol
+// that is the nearest to the given address.
+// Beware, this code is called from vm error reporting code, when vm is already
+// in "error" state, so there are scenarios, lookup will fail. We want this
+// part of code to be very defensive, and bait out if anything went wrong.
+
+class ElfFile: public CHeapObj {
+  friend class Decoder;
+ public:
+  ElfFile(const char* filepath);
+  ~ElfFile();
+
+  const char* decode(address addr, int* offset);
+  const char* filepath() {
+    return m_filepath;
+  }
+
+  bool same_elf_file(const char* filepath) {
+    assert(filepath, "null file path");
+    assert(m_filepath, "already out of memory");
+    return (m_filepath && !strcmp(filepath, m_filepath));
+  }
+
+  Decoder::decoder_status get_status() {
+    return m_status;
+  }
+
+ private:
+  // sanity check, if the file is a real elf file
+  bool is_elf_file(Elf_Ehdr&);
+
+  // load string tables from the elf file
+  bool load_tables();
+
+  // string tables are stored in a linked list
+  void add_string_table(ElfStringTable* table);
+
+  // symbol tables are stored in a linked list
+  void add_symbol_table(ElfSymbolTable* table);
+
+  // return a string table at specified section index
+  ElfStringTable* get_string_table(int index);
+
+  // look up an address and return the nearest symbol
+  const char* look_up(Elf_Shdr shdr, address addr, int* offset);
+
+ protected:
+    ElfFile*         m_next;
+
+ private:
+  // file
+  const char* m_filepath;
+  FILE* m_file;
+
+  // Elf header
+  Elf_Ehdr            m_elfHdr;
+
+  // symbol tables
+  ElfSymbolTable*     m_symbol_tables;
+
+  // string tables
+  ElfStringTable*     m_string_tables;
+
+  Decoder::decoder_status  m_status;
+};
+
+#endif // _WINDOWS
+
+#endif // __ELF_FILE_HPP
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/utilities/elfStringTable.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+
+#ifndef _WINDOWS
+
+#include "memory/allocation.inline.hpp"
+#include "utilities/elfStringTable.hpp"
+
+// We will try to load whole string table into memory if we can.
+// Otherwise, fallback to more expensive file operation.
+ElfStringTable::ElfStringTable(FILE* file, Elf_Shdr shdr, int index) {
+  assert(file, "null file handle");
+  m_table = NULL;
+  m_index = index;
+  m_next = NULL;
+  m_file = file;
+  m_status = Decoder::no_error;
+
+  // try to load the string table
+  long cur_offset = ftell(file);
+  m_table = (char*)NEW_C_HEAP_ARRAY(char, shdr.sh_size);
+  if (m_table != NULL) {
+    // if there is an error, mark the error
+    if (fseek(file, shdr.sh_offset, SEEK_SET) ||
+      fread((void*)m_table, shdr.sh_size, 1, file) != 1 ||
+      fseek(file, cur_offset, SEEK_SET)) {
+      m_status = Decoder::file_invalid;
+      FREE_C_HEAP_ARRAY(char, m_table);
+      m_table = NULL;
+    }
+  } else {
+    memcpy(&m_shdr, &shdr, sizeof(Elf_Shdr));
+  }
+}
+
+ElfStringTable::~ElfStringTable() {
+  if (m_table != NULL) {
+    FREE_C_HEAP_ARRAY(char, m_table);
+  }
+
+  if (m_next != NULL) {
+    delete m_next;
+  }
+}
+
+const char* ElfStringTable::string_at(int pos) {
+  if (m_status != Decoder::no_error) {
+    return NULL;
+  }
+  if (m_table != NULL) {
+    return (const char*)(m_table + pos);
+  } else {
+    long cur_pos = ftell(m_file);
+    if (cur_pos == -1 ||
+      fseek(m_file, m_shdr.sh_offset + pos, SEEK_SET) ||
+      fread(m_symbol, 1, MAX_SYMBOL_LEN, m_file) <= 0 ||
+      fseek(m_file, cur_pos, SEEK_SET)) {
+      m_status = Decoder::file_invalid;
+      return NULL;
+    }
+    return (const char*)m_symbol;
+  }
+}
+
+#endif // _WINDOWS
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/utilities/elfStringTable.hpp	Thu Dec 16 20:48:11 2010 -0800
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef __ELF_STRING_TABLE_HPP
+#define __ELF_STRING_TABLE_HPP
+
+#ifndef _WINDOWS
+
+#include "memory/allocation.hpp"
+#include "utilities/decoder.hpp"
+#include "utilities/elfFile.hpp"
+
+
+// The string table represents a string table section in an elf file.
+// Whenever there is enough memory, it will load whole string table as
+// one blob. Otherwise, it will load string from file when requested.
+
+#define MAX_SYMBOL_LEN  256
+
+class ElfStringTable: CHeapObj {
+  friend class ElfFile;
+ public:
+  ElfStringTable(FILE* file, Elf_Shdr shdr, int index);
+  ~ElfStringTable();
+
+  // section index
+  int index() { return m_index; };
+
+  // get string at specified offset
+  const char* string_at(int offset);
+
+  // get status code
+  Decoder::decoder_status get_status() { return m_status; };
+
+ protected:
+  ElfStringTable*        m_next;
+
+  // section index
+  int                      m_index;
+
+  // holds complete string table if can
+  // allocate enough memory
+  const char*              m_table;
+
+  // file contains string table
+  FILE*                    m_file;
+
+  // section header
+  Elf_Shdr                 m_shdr;
+
+  // buffer for reading individual string
+  char                     m_symbol[MAX_SYMBOL_LEN];
+
+  // error code
+  Decoder::decoder_status  m_status;
+};
+
+#endif // _WINDOWS
+
+#endif // __ELF_STRING_TABLE_HPP
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/utilities/elfSymbolTable.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+
+#ifndef _WINDOWS
+
+#include "memory/allocation.inline.hpp"
+#include "utilities/elfSymbolTable.hpp"
+
+ElfSymbolTable::ElfSymbolTable(FILE* file, Elf_Shdr shdr) {
+  assert(file, "null file handle");
+  m_symbols = NULL;
+  m_next = NULL;
+  m_file = file;
+  m_status = Decoder::no_error;
+
+  // try to load the string table
+  long cur_offset = ftell(file);
+  if (cur_offset != -1) {
+    m_symbols = (Elf_Sym*)NEW_C_HEAP_ARRAY(char, shdr.sh_size);
+    if (m_symbols) {
+      if (fseek(file, shdr.sh_offset, SEEK_SET) ||
+        fread((void*)m_symbols, shdr.sh_size, 1, file) != 1 ||
+        fseek(file, cur_offset, SEEK_SET)) {
+        m_status = Decoder::file_invalid;
+        FREE_C_HEAP_ARRAY(char, m_symbols);
+        m_symbols = NULL;
+      }
+    }
+    if (m_status == Decoder::no_error) {
+      memcpy(&m_shdr, &shdr, sizeof(Elf_Shdr));
+    }
+  } else {
+    m_status = Decoder::file_invalid;
+  }
+}
+
+ElfSymbolTable::~ElfSymbolTable() {
+  if (m_symbols != NULL) {
+    FREE_C_HEAP_ARRAY(char, m_symbols);
+  }
+
+  if (m_next != NULL) {
+    delete m_next;
+  }
+}
+
+Decoder::decoder_status ElfSymbolTable::lookup(address addr, int* stringtableIndex, int* posIndex, int* offset) {
+  assert(stringtableIndex, "null string table index pointer");
+  assert(posIndex, "null string table offset pointer");
+  assert(offset, "null offset pointer");
+
+  if (m_status != Decoder::no_error) {
+    return m_status;
+  }
+
+  address pc = 0;
+  size_t  sym_size = sizeof(Elf_Sym);
+  assert((m_shdr.sh_size % sym_size) == 0, "check size");
+  int count = m_shdr.sh_size / sym_size;
+  if (m_symbols != NULL) {
+    for (int index = 0; index < count; index ++) {
+      if (STT_FUNC == ELF_ST_TYPE(m_symbols[index].st_info)) {
+        address sym_addr = (address)m_symbols[index].st_value;
+        if (sym_addr < addr && (addr - sym_addr) < *offset) {
+          pc = (address)m_symbols[index].st_value;
+          *offset = (int)(addr - pc);
+          *posIndex = m_symbols[index].st_name;
+          *stringtableIndex = m_shdr.sh_link;
+        }
+      }
+    }
+  } else {
+    long cur_pos;
+    if ((cur_pos = ftell(m_file)) == -1 ||
+      fseek(m_file, m_shdr.sh_offset, SEEK_SET)) {
+      m_status = Decoder::file_invalid;
+      return m_status;
+    }
+
+    Elf_Sym sym;
+    for (int index = 0; index < count; index ++) {
+      if (fread(&sym, sym_size, 1, m_file) == 1) {
+        if (STT_FUNC == ELF_ST_TYPE(sym.st_info)) {
+          address sym_addr = (address)sym.st_value;
+          if (sym_addr < addr && (addr - sym_addr) < *offset) {
+            pc = (address)sym.st_value;
+            *offset = (int)(addr - pc);
+            *posIndex = sym.st_name;
+            *stringtableIndex = m_shdr.sh_link;
+          }
+        }
+      } else {
+        m_status = Decoder::file_invalid;
+        return m_status;
+      }
+    }
+    fseek(m_file, cur_pos, SEEK_SET);
+  }
+  return m_status;
+}
+
+#endif // _WINDOWS
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/utilities/elfSymbolTable.hpp	Thu Dec 16 20:48:11 2010 -0800
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef __ELF_SYMBOL_TABLE_HPP
+#define __ELF_SYMBOL_TABLE_HPP
+
+#ifndef _WINDOWS
+
+
+#include "memory/allocation.hpp"
+#include "utilities/decoder.hpp"
+#include "utilities/elfFile.hpp"
+
+/*
+ * symbol table object represents a symbol section in an elf file.
+ * Whenever possible, it will load all symbols from the corresponding section
+ * of the elf file into memory. Otherwise, it will walk the section in file
+ * to look up the symbol that nearest the given address.
+ */
+class ElfSymbolTable: public CHeapObj {
+  friend class ElfFile;
+ public:
+  ElfSymbolTable(FILE* file, Elf_Shdr shdr);
+  ~ElfSymbolTable();
+
+  // search the symbol that is nearest to the specified address.
+  Decoder::decoder_status lookup(address addr, int* stringtableIndex, int* posIndex, int* offset);
+
+  Decoder::decoder_status get_status() { return m_status; };
+
+ protected:
+  ElfSymbolTable*  m_next;
+
+  // holds a complete symbol table section if
+  // can allocate enough memory
+  Elf_Sym*            m_symbols;
+
+  // file contains string table
+  FILE*               m_file;
+
+  // section header
+  Elf_Shdr            m_shdr;
+
+  Decoder::decoder_status  m_status;
+};
+
+#endif // _WINDOWS
+
+#endif // __ELF_SYMBOL_TABLE_HPP
+
+
+
--- a/src/share/vm/utilities/vmError.cpp	Thu Dec 16 20:35:33 2010 -0800
+++ b/src/share/vm/utilities/vmError.cpp	Thu Dec 16 20:48:11 2010 -0800
@@ -33,6 +33,7 @@
 #include "runtime/vmThread.hpp"
 #include "runtime/vm_operations.hpp"
 #include "utilities/debug.hpp"
+#include "utilities/decoder.hpp"
 #include "utilities/defaultStream.hpp"
 #include "utilities/top.hpp"
 #include "utilities/vmError.hpp"
@@ -516,8 +517,10 @@
        if (fr.pc()) {
           st->print_cr("Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)");
 
+          // initialize decoder to decode C frames
+          Decoder decoder;
+
           int count = 0;
-
           while (count++ < StackPrintLimit) {
              fr.print_on_error(st, buf, sizeof(buf));
              st->cr();
--- a/test/compiler/6991596/Test6991596.java	Thu Dec 16 20:35:33 2010 -0800
+++ b/test/compiler/6991596/Test6991596.java	Thu Dec 16 20:48:11 2010 -0800
@@ -35,7 +35,7 @@
 public class Test6991596 {
     private static final Class   CLASS = Test6991596.class;
     private static final String  NAME  = "foo";
-    private static final boolean DEBUG = false;
+    private static final boolean DEBUG = System.getProperty("DEBUG", "false").equals("true");
 
     public static void main(String[] args) throws Throwable {
         testboolean();
@@ -47,7 +47,7 @@
     }
 
     // Helpers to get various methods.
-    static MethodHandle getmh1(Class ret, Class arg) {
+    static MethodHandle getmh1(Class ret, Class arg) throws NoAccessException {
         return MethodHandles.lookup().findStatic(CLASS, NAME, MethodType.methodType(ret, arg));
     }
     static MethodHandle getmh2(MethodHandle mh1, Class ret, Class arg) {
@@ -76,38 +76,38 @@
             MethodHandle mh2 = getmh2(mh1, boolean.class, boolean.class);
             // TODO add this for all cases when the bugs are fixed.
             //MethodHandle mh3 = getmh3(mh1, boolean.class, boolean.class);
-            boolean a = mh1.<boolean>invokeExact((boolean) x);
-            boolean b = mh2.<boolean>invokeExact(x);
+            boolean a = (boolean) mh1.invokeExact((boolean) x);
+            boolean b = (boolean) mh2.invokeExact(x);
             //boolean c = mh3.<boolean>invokeExact((boolean) x);
-            assert a == b : a + " != " + b;
-            //assert c == x : c + " != " + x;
+            check(x, a, b);
+            //check(x, c, x);
         }
 
         // byte
         {
             MethodHandle mh1 = getmh1(     byte.class,    byte.class   );
             MethodHandle mh2 = getmh2(mh1, byte.class,    boolean.class);
-            byte    a = mh1.<byte>invokeExact((byte) (x ? 1 : 0));
-            byte    b = mh2.<byte>invokeExact(x);
-            assert a == b : a + " != " + b;
+            byte a = (byte) mh1.invokeExact((byte) (x ? 1 : 0));
+            byte b = (byte) mh2.invokeExact(x);
+            check(x, a, b);
         }
 
         // char
         {
             MethodHandle mh1 = getmh1(     char.class, char.class);
             MethodHandle mh2 = getmh2(mh1, char.class, boolean.class);
-            char a = mh1.<char>invokeExact((char) (x ? 1 : 0));
-            char b = mh2.<char>invokeExact(x);
-            assert a == b : a + " != " + b;
+            char a = (char) mh1.invokeExact((char) (x ? 1 : 0));
+            char b = (char) mh2.invokeExact(x);
+            check(x, a, b);
         }
 
         // short
         {
             MethodHandle mh1 = getmh1(     short.class, short.class);
             MethodHandle mh2 = getmh2(mh1, short.class, boolean.class);
-            short a = mh1.<short>invokeExact((short) (x ? 1 : 0));
-            short b = mh2.<short>invokeExact(x);
-            assert a == b : a + " != " + b;
+            short a = (short) mh1.invokeExact((short) (x ? 1 : 0));
+            short b = (short) mh2.invokeExact(x);
+            check(x, a, b);
         }
     }
 
@@ -134,36 +134,36 @@
         {
             MethodHandle mh1 = getmh1(     boolean.class, boolean.class);
             MethodHandle mh2 = getmh2(mh1, boolean.class, byte.class);
-            boolean a = mh1.<boolean>invokeExact((x & 1) == 1);
-            boolean b = mh2.<boolean>invokeExact(x);
-            assert a == b : a + " != " + b;
+            boolean a = (boolean) mh1.invokeExact((x & 1) == 1);
+            boolean b = (boolean) mh2.invokeExact(x);
+            check(x, a, b);
         }
 
         // byte
         {
             MethodHandle mh1 = getmh1(     byte.class, byte.class);
             MethodHandle mh2 = getmh2(mh1, byte.class, byte.class);
-            byte a = mh1.<byte>invokeExact((byte) x);
-            byte b = mh2.<byte>invokeExact(x);
-            assert a == b : a + " != " + b;
+            byte a = (byte) mh1.invokeExact((byte) x);
+            byte b = (byte) mh2.invokeExact(x);
+            check(x, a, b);
         }
 
         // char
         {
             MethodHandle mh1 = getmh1(     char.class, char.class);
             MethodHandle mh2 = getmh2(mh1, char.class, byte.class);
-            char a = mh1.<char>invokeExact((char) x);
-            char b = mh2.<char>invokeExact(x);
-            assert a == b : a + " != " + b;
+            char a = (char) mh1.invokeExact((char) x);
+            char b = (char) mh2.invokeExact(x);
+            check(x, a, b);
         }
 
         // short
         {
             MethodHandle mh1 = getmh1(     short.class, short.class);
             MethodHandle mh2 = getmh2(mh1, short.class, byte.class);
-            short a = mh1.<short>invokeExact((short) x);
-            short b = mh2.<short>invokeExact(x);
-            assert a == b : a + " != " + b;
+            short a = (short) mh1.invokeExact((short) x);
+            short b = (short) mh2.invokeExact(x);
+            check(x, a, b);
         }
     }
 
@@ -188,36 +188,36 @@
         {
             MethodHandle mh1 = getmh1(     boolean.class, boolean.class);
             MethodHandle mh2 = getmh2(mh1, boolean.class, char.class);
-            boolean a = mh1.<boolean>invokeExact((x & 1) == 1);
-            boolean b = mh2.<boolean>invokeExact(x);
-            assert a == b : a + " != " + b;
+            boolean a = (boolean) mh1.invokeExact((x & 1) == 1);
+            boolean b = (boolean) mh2.invokeExact(x);
+            check(x, a, b);
         }
 
         // byte
         {
             MethodHandle mh1 = getmh1(     byte.class, byte.class);
             MethodHandle mh2 = getmh2(mh1, byte.class, char.class);
-            byte a = mh1.<byte>invokeExact((byte) x);
-            byte b = mh2.<byte>invokeExact(x);
-            assert a == b : a + " != " + b;
+            byte a = (byte) mh1.invokeExact((byte) x);
+            byte b = (byte) mh2.invokeExact(x);
+            check(x, a, b);
         }
 
         // char
         {
             MethodHandle mh1 = getmh1(     char.class, char.class);
             MethodHandle mh2 = getmh2(mh1, char.class, char.class);
-            char a = mh1.<char>invokeExact((char) x);
-            char b = mh2.<char>invokeExact(x);
-            assert a == b : a + " != " + b;
+            char a = (char) mh1.invokeExact((char) x);
+            char b = (char) mh2.invokeExact(x);
+            check(x, a, b);
         }
 
         // short
         {
             MethodHandle mh1 = getmh1(     short.class, short.class);
             MethodHandle mh2 = getmh2(mh1, short.class, char.class);
-            short a = mh1.<short>invokeExact((short) x);
-            short b = mh2.<short>invokeExact(x);
-            assert a == b : a + " != " + b;
+            short a = (short) mh1.invokeExact((short) x);
+            short b = (short) mh2.invokeExact(x);
+            check(x, a, b);
         }
     }
 
@@ -248,36 +248,36 @@
         {
             MethodHandle mh1 = getmh1(     boolean.class, boolean.class);
             MethodHandle mh2 = getmh2(mh1, boolean.class, short.class);
-            boolean a = mh1.<boolean>invokeExact((x & 1) == 1);
-            boolean b = mh2.<boolean>invokeExact(x);
-            assert a == b : a + " != " + b;
+            boolean a = (boolean) mh1.invokeExact((x & 1) == 1);
+            boolean b = (boolean) mh2.invokeExact(x);
+            check(x, a, b);
         }
 
         // byte
         {
             MethodHandle mh1 = getmh1(     byte.class, byte.class);
             MethodHandle mh2 = getmh2(mh1, byte.class, short.class);
-            byte a = mh1.<byte>invokeExact((byte) x);
-            byte b = mh2.<byte>invokeExact(x);
-            assert a == b : a + " != " + b;
+            byte a = (byte) mh1.invokeExact((byte) x);
+            byte b = (byte) mh2.invokeExact(x);
+            check(x, a, b);
         }
 
         // char
         {
             MethodHandle mh1 = getmh1(     char.class, char.class);
             MethodHandle mh2 = getmh2(mh1, char.class, short.class);
-            char a = mh1.<char>invokeExact((char) x);
-            char b = mh2.<char>invokeExact(x);
-            assert a == b : a + " != " + b;
+            char a = (char) mh1.invokeExact((char) x);
+            char b = (char) mh2.invokeExact(x);
+            check(x, a, b);
         }
 
         // short
         {
             MethodHandle mh1 = getmh1(     short.class, short.class);
             MethodHandle mh2 = getmh2(mh1, short.class, short.class);
-            short a = mh1.<short>invokeExact((short) x);
-            short b = mh2.<short>invokeExact(x);
-            assert a == b : a + " != " + b;
+            short a = (short) mh1.invokeExact((short) x);
+            short b = (short) mh2.invokeExact(x);
+            check(x, a, b);
         }
     }
 
@@ -316,45 +316,46 @@
         {
             MethodHandle mh1 = getmh1(     boolean.class, boolean.class);
             MethodHandle mh2 = getmh2(mh1, boolean.class, int.class);
-            boolean a = mh1.<boolean>invokeExact((x & 1) == 1);
-            boolean b = mh2.<boolean>invokeExact(x);
-            assert a == b : a + " != " + b;
+            boolean a = (boolean) mh1.invokeExact((x & 1) == 1);
+            boolean b = (boolean) mh2.invokeExact(x);
+            check(x, a, b);
         }
 
         // byte
         {
             MethodHandle mh1 = getmh1(     byte.class, byte.class);
             MethodHandle mh2 = getmh2(mh1, byte.class, int.class);
-            byte a = mh1.<byte>invokeExact((byte) x);
-            byte b = mh2.<byte>invokeExact(x);
-            assert a == b : a + " != " + b;
+            byte a = (byte) mh1.invokeExact((byte) x);
+            byte b = (byte) mh2.invokeExact(x);
+            check(x, a, b);
         }
 
         // char
         {
             MethodHandle mh1 = getmh1(     char.class, char.class);
             MethodHandle mh2 = getmh2(mh1, char.class, int.class);
-            char a = mh1.<char>invokeExact((char) x);
-            char b = mh2.<char>invokeExact(x);
-            assert a == b : a + " != " + b;
+            char a = (char) mh1.invokeExact((char) x);
+            char b = (char) mh2.invokeExact(x);
+            check(x, a, b);
         }
 
         // short
         {
             MethodHandle mh1 = getmh1(     short.class, short.class);
             MethodHandle mh2 = getmh2(mh1, short.class, int.class);
-            short a = mh1.<short>invokeExact((short) x);
-            short b = mh2.<short>invokeExact(x);
+            short a = (short) mh1.invokeExact((short) x);
+            short b = (short) mh2.invokeExact(x);
             assert a == b : a + " != " + b;
+            check(x, a, b);
         }
 
         // int
         {
             MethodHandle mh1 = getmh1(     int.class, int.class);
             MethodHandle mh2 = getmh2(mh1, int.class, int.class);
-            int a = mh1.<int>invokeExact((int) x);
-            int b = mh2.<int>invokeExact(x);
-            assert a == b : a + " != " + b;
+            int a = (int) mh1.invokeExact((int) x);
+            int b = (int) mh2.invokeExact(x);
+            check(x, a, b);
         }
     }
 
@@ -395,48 +396,65 @@
         {
             MethodHandle mh1 = getmh1(     boolean.class, boolean.class);
             MethodHandle mh2 = getmh2(mh1, boolean.class, long.class);
-            boolean a = mh1.<boolean>invokeExact((x & 1L) == 1L);
-            boolean b = mh2.<boolean>invokeExact(x);
-            assert a == b : a + " != " + b;
+            boolean a = (boolean) mh1.invokeExact((x & 1L) == 1L);
+            boolean b = (boolean) mh2.invokeExact(x);
+            check(x, a, b);
         }
 
         // byte
         {
             MethodHandle mh1 = getmh1(     byte.class, byte.class);
             MethodHandle mh2 = getmh2(mh1, byte.class, long.class);
-            byte a = mh1.<byte>invokeExact((byte) x);
-            byte b = mh2.<byte>invokeExact(x);
-            assert a == b : a + " != " + b;
+            byte a = (byte) mh1.invokeExact((byte) x);
+            byte b = (byte) mh2.invokeExact(x);
+            check(x, a, b);
         }
 
         // char
         {
             MethodHandle mh1 = getmh1(     char.class, char.class);
             MethodHandle mh2 = getmh2(mh1, char.class, long.class);
-            char a = mh1.<char>invokeExact((char) x);
-            char b = mh2.<char>invokeExact(x);
-            assert a == b : a + " != " + b;
+            char a = (char) mh1.invokeExact((char) x);
+            char b = (char) mh2.invokeExact(x);
+            check(x, a, b);
         }
 
         // short
         {
             MethodHandle mh1 = getmh1(     short.class, short.class);
             MethodHandle mh2 = getmh2(mh1, short.class, long.class);
-            short a = mh1.<short>invokeExact((short) x);
-            short b = mh2.<short>invokeExact(x);
-            assert a == b : a + " != " + b;
+            short a = (short) mh1.invokeExact((short) x);
+            short b = (short) mh2.invokeExact(x);
+            check(x, a, b);
         }
 
         // int
         {
             MethodHandle mh1 = getmh1(     int.class, int.class);
             MethodHandle mh2 = getmh2(mh1, int.class, long.class);
-            int a = mh1.<int>invokeExact((int) x);
-            int b = mh2.<int>invokeExact(x);
-            assert a == b : a + " != " + b;
+            int a = (int) mh1.invokeExact((int) x);
+            int b = (int) mh2.invokeExact(x);
+            check(x, a, b);
         }
+    }
 
-    }
+    static void check(boolean x, boolean e, boolean a) { p(z2h(x), z2h(e), z2h(a)); assert e == a : z2h(x) + ": " + z2h(e) + " != " + z2h(a); }
+    static void check(boolean x, byte    e, byte    a) { p(z2h(x), i2h(e), i2h(a)); assert e == a : z2h(x) + ": " + i2h(e) + " != " + i2h(a); }
+    static void check(boolean x, int     e, int     a) { p(z2h(x), i2h(e), i2h(a)); assert e == a : z2h(x) + ": " + i2h(e) + " != " + i2h(a); }
+
+    static void check(int     x, boolean e, boolean a) { p(i2h(x), z2h(e), z2h(a)); assert e == a : i2h(x) + ": " + z2h(e) + " != " + z2h(a); }
+    static void check(int     x, byte    e, byte    a) { p(i2h(x), i2h(e), i2h(a)); assert e == a : i2h(x) + ": " + i2h(e) + " != " + i2h(a); }
+    static void check(int     x, int     e, int     a) { p(i2h(x), i2h(e), i2h(a)); assert e == a : i2h(x) + ": " + i2h(e) + " != " + i2h(a); }
+
+    static void check(long    x, boolean e, boolean a) { p(l2h(x), z2h(e), z2h(a)); assert e == a : l2h(x) + ": " + z2h(e) + " != " + z2h(a); }
+    static void check(long    x, byte    e, byte    a) { p(l2h(x), i2h(e), i2h(a)); assert e == a : l2h(x) + ": " + i2h(e) + " != " + i2h(a); }
+    static void check(long    x, int     e, int     a) { p(l2h(x), i2h(e), i2h(a)); assert e == a : l2h(x) + ": " + i2h(e) + " != " + i2h(a); }
+
+    static void p(String x, String e, String a) { if (DEBUG)  System.out.println(x + ": expected: " + e + ", actual: " + a); }
+
+    static String z2h(boolean x) { return x ? "1" : "0"; }
+    static String i2h(int     x) { return Integer.toHexString(x); }
+    static String l2h(long    x) { return Long.toHexString(x); }
 
     // to int
     public static boolean foo(boolean i) { return i; }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/compiler/7002666/Test7002666.java	Thu Dec 16 20:48:11 2010 -0800
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 7002666
+ * @summary eclipse CDT projects crash with compressed oops
+ *
+ * @run main/othervm -Xbatch -XX:CompileOnly=Test7002666.test,java/lang/reflect/Array Test7002666
+ *
+ * This will only reliably fail with a fastdebug build since it relies
+ * on seeing garbage in the heap to die.  It could be made more
+ * reliable in product mode but that would require greatly increasing
+ * the runtime.
+ */
+
+public class Test7002666 {
+    public static void main(String[] args) {
+        for (int i = 0; i < 25000; i++) {
+            Object[] a = test(Test7002666.class, new Test7002666());
+            if (a[0] != null) {
+                // The element should be null but if it's not then
+                // we've hit the bug.  This will most likely crash but
+                // at least throw an exception.
+                System.err.println(a[0]);
+                throw new InternalError(a[0].toString());
+
+            }
+        }
+    }
+    public static Object[] test(Class c, Object o) {
+        // allocate an array small enough to be trigger the bug
+        Object[] a = (Object[])java.lang.reflect.Array.newInstance(c, 1);
+        return a;
+    }
+}