changeset 2372:753074e52aba

Merge from main OpenJDK repository
author Greg Lewis <glewis@eyesbeyond.com>
date Mon, 04 Apr 2011 19:23:29 -0700
parents 557195360a74 2ffcf94550d5
children ea3fbdac4cdc
files src/cpu/sparc/vm/globals_sparc.hpp src/cpu/x86/vm/c1_LIRAssembler_x86.cpp src/cpu/x86/vm/globals_x86.hpp src/cpu/x86/vm/stubGenerator_x86_32.cpp src/cpu/x86/vm/stubGenerator_x86_64.cpp src/cpu/x86/vm/templateTable_x86_32.cpp src/cpu/x86/vm/vm_version_x86.cpp src/os/linux/vm/os_linux.cpp src/share/vm/classfile/classLoader.cpp src/share/vm/classfile/javaClasses.cpp src/share/vm/compiler/compileBroker.cpp src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp src/share/vm/interpreter/abstractInterpreter.hpp src/share/vm/interpreter/bytecodeInterpreter.cpp src/share/vm/interpreter/linkResolver.cpp src/share/vm/memory/allocation.cpp src/share/vm/memory/collectorPolicy.cpp src/share/vm/memory/universe.cpp src/share/vm/oops/constantPoolKlass.cpp src/share/vm/oops/constantPoolOop.cpp src/share/vm/oops/instanceKlass.cpp src/share/vm/opto/c2_globals.hpp src/share/vm/prims/jni.cpp src/share/vm/prims/jvm.cpp src/share/vm/prims/jvmtiImpl.cpp src/share/vm/prims/nativeLookup.cpp src/share/vm/runtime/arguments.cpp src/share/vm/runtime/globals.hpp src/share/vm/runtime/java.cpp src/share/vm/runtime/os.cpp src/share/vm/runtime/os.hpp src/share/vm/runtime/osThread.hpp src/share/vm/runtime/thread.cpp src/share/vm/runtime/vmStructs.cpp src/share/vm/utilities/globalDefinitions.hpp src/share/vm/utilities/globalDefinitions_gcc.hpp src/share/vm/utilities/macros.hpp src/share/vm/utilities/vmError.cpp src/share/vm/utilities/workgroup.hpp test/compiler/6987555/Test6987555.java test/compiler/6991596/Test6991596.java
diffstat 242 files changed, 6649 insertions(+), 4202 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Thu Mar 03 23:48:25 2011 -0800
+++ b/.hgtags	Mon Apr 04 19:23:29 2011 -0700
@@ -153,3 +153,10 @@
 e9aa2ca89ad6c53420623d579765f9706ec523d7 hs21-b02
 0e531ab5ba04967a0e9aa6aef65e6eb3a0dcf632 jdk7-b132
 a8d643a4db47c7b58e0bcb49c77b5c3610de86a8 hs21-b03
+1b3a350709e4325d759bb453ff3fb6a463270488 jdk7-b133
+447e6faab4a8755d4860c2366630729dbaec111c jdk7-b134
+3c76374706ea8a77e15aec8310e831e5734f8775 hs21-b04
+b898f0fc3cedc972d884d31a751afd75969531cf jdk7-b135
+b898f0fc3cedc972d884d31a751afd75969531cf hs21-b05
+bd586e392d93b7ed7a1636dcc8da2b6a4203a102 jdk7-b136
+bd586e392d93b7ed7a1636dcc8da2b6a4203a102 hs21-b06
--- a/agent/src/share/classes/sun/jvm/hotspot/jdi/FieldImpl.java	Thu Mar 03 23:48:25 2011 -0800
+++ b/agent/src/share/classes/sun/jvm/hotspot/jdi/FieldImpl.java	Mon Apr 04 19:23:29 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -62,7 +62,7 @@
 
     // get the value of static field
     ValueImpl getValue() {
-        return getValue(saField.getFieldHolder());
+        return getValue(saField.getFieldHolder().getJavaMirror());
     }
 
     // get the value of this Field from a specific Oop
--- a/agent/src/share/classes/sun/jvm/hotspot/memory/StringTable.java	Thu Mar 03 23:48:25 2011 -0800
+++ b/agent/src/share/classes/sun/jvm/hotspot/memory/StringTable.java	Mon Apr 04 19:23:29 2011 -0700
@@ -44,12 +44,10 @@
   private static synchronized void initialize(TypeDataBase db) {
     Type type = db.lookupType("StringTable");
     theTableField  = type.getAddressField("_the_table");
-    stringTableSize = db.lookupIntConstant("StringTable::string_table_size").intValue();
   }
 
   // Fields
   private static AddressField theTableField;
-  private static int stringTableSize;
 
   // Accessors
   public static StringTable getTheTable() {
@@ -57,10 +55,6 @@
     return (StringTable) VMObjectFactory.newObject(StringTable.class, tmp);
   }
 
-  public static int getStringTableSize() {
-    return stringTableSize;
-  }
-
   public StringTable(Address addr) {
     super(addr);
   }
--- a/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java	Thu Mar 03 23:48:25 2011 -0800
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java	Mon Apr 04 19:23:29 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -87,7 +87,7 @@
     innerClasses         = new OopField(type.getOopField("_inner_classes"), Oop.getHeaderSize());
     nonstaticFieldSize   = new CIntField(type.getCIntegerField("_nonstatic_field_size"), Oop.getHeaderSize());
     staticFieldSize      = new CIntField(type.getCIntegerField("_static_field_size"), Oop.getHeaderSize());
-    staticOopFieldSize   = new CIntField(type.getCIntegerField("_static_oop_field_size"), Oop.getHeaderSize());
+    staticOopFieldCount   = new CIntField(type.getCIntegerField("_static_oop_field_count"), Oop.getHeaderSize());
     nonstaticOopMapSize  = new CIntField(type.getCIntegerField("_nonstatic_oop_map_size"), Oop.getHeaderSize());
     isMarkedDependent    = new CIntField(type.getCIntegerField("_is_marked_dependent"), Oop.getHeaderSize());
     initState            = new CIntField(type.getCIntegerField("_init_state"), Oop.getHeaderSize());
@@ -140,7 +140,7 @@
   private static OopField  innerClasses;
   private static CIntField nonstaticFieldSize;
   private static CIntField staticFieldSize;
-  private static CIntField staticOopFieldSize;
+  private static CIntField staticOopFieldCount;
   private static CIntField nonstaticOopMapSize;
   private static CIntField isMarkedDependent;
   private static CIntField initState;
@@ -261,8 +261,7 @@
   public Symbol    getSourceDebugExtension(){ return getSymbol(sourceDebugExtension); }
   public TypeArray getInnerClasses()        { return (TypeArray)    innerClasses.getValue(this); }
   public long      getNonstaticFieldSize()  { return                nonstaticFieldSize.getValue(this); }
-  public long      getStaticFieldSize()     { return                staticFieldSize.getValue(this); }
-  public long      getStaticOopFieldSize()  { return                staticOopFieldSize.getValue(this); }
+  public long      getStaticOopFieldCount() { return                staticOopFieldCount.getValue(this); }
   public long      getNonstaticOopMapSize() { return                nonstaticOopMapSize.getValue(this); }
   public boolean   getIsMarkedDependent()   { return                isMarkedDependent.getValue(this) != 0; }
   public long      getVtableLen()           { return                vtableLen.getValue(this); }
@@ -453,7 +452,7 @@
       visitor.doOop(innerClasses, true);
       visitor.doCInt(nonstaticFieldSize, true);
       visitor.doCInt(staticFieldSize, true);
-      visitor.doCInt(staticOopFieldSize, true);
+      visitor.doCInt(staticOopFieldCount, true);
       visitor.doCInt(nonstaticOopMapSize, true);
       visitor.doCInt(isMarkedDependent, true);
       visitor.doCInt(initState, true);
@@ -692,7 +691,7 @@
   public long getObjectSize() {
     long bodySize =    alignObjectOffset(getVtableLen() * getHeap().getOopSize())
                      + alignObjectOffset(getItableLen() * getHeap().getOopSize())
-                     + (getStaticFieldSize() + getNonstaticOopMapSize()) * getHeap().getOopSize();
+                     + (getNonstaticOopMapSize()) * getHeap().getOopSize();
     return alignObjectSize(headerSize + bodySize);
   }
 
--- a/agent/src/share/classes/sun/jvm/hotspot/oops/IntField.java	Thu Mar 03 23:48:25 2011 -0800
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/IntField.java	Mon Apr 04 19:23:29 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2001, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -40,7 +40,12 @@
     super(holder, fieldArrayIndex);
   }
 
-  public int getValue(Oop obj) { return obj.getHandle().getJIntAt(getOffset()); }
+  public int getValue(Oop obj) {
+    if (!isVMField() && !obj.isInstance() && !obj.isArray()) {
+      throw new InternalError(obj.toString());
+    }
+    return obj.getHandle().getJIntAt(getOffset());
+  }
   public void setValue(Oop obj, int value) throws MutationException {
     // Fix this: setJIntAt is missing in Address
   }
--- a/agent/src/share/classes/sun/jvm/hotspot/oops/OopField.java	Thu Mar 03 23:48:25 2011 -0800
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/OopField.java	Mon Apr 04 19:23:29 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2002, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -41,11 +41,17 @@
   }
 
   public Oop getValue(Oop obj) {
+    if (!isVMField() && !obj.isInstance() && !obj.isArray()) {
+      throw new InternalError();
+    }
     return obj.getHeap().newOop(getValueAsOopHandle(obj));
   }
 
   /** Debugging support */
   public OopHandle getValueAsOopHandle(Oop obj) {
+    if (!isVMField() && !obj.isInstance() && !obj.isArray()) {
+      throw new InternalError(obj.toString());
+    }
     return obj.getHandle().getOopHandleAt(getOffset());
   }
 
--- a/agent/src/share/classes/sun/jvm/hotspot/oops/OopUtilities.java	Thu Mar 03 23:48:25 2011 -0800
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/OopUtilities.java	Mon Apr 04 19:23:29 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -274,13 +274,7 @@
        // hc_klass is a HotSpot magic field and hence we can't
        // find it from InstanceKlass for java.lang.Class.
        TypeDataBase db = VM.getVM().getTypeDataBase();
-       int hcKlassOffset = (int) Instance.getHeaderSize();
-       try {
-          hcKlassOffset += (db.lookupIntConstant("java_lang_Class::hc_klass_offset").intValue() *
-                           VM.getVM().getHeapOopSize());
-       } catch (RuntimeException re) {
-          // ignore, currently java_lang_Class::hc_klass_offset is zero
-       }
+       int hcKlassOffset = (int) db.lookupType("java_lang_Class").getCIntegerField("klass_offset").getValue();
        if (VM.getVM().isCompressedOopsEnabled()) {
          hcKlassField = new NarrowOopField(new NamedFieldIdentifier("hc_klass"), hcKlassOffset, true);
        } else {
--- a/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java	Thu Mar 03 23:48:25 2011 -0800
+++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java	Mon Apr 04 19:23:29 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -839,13 +839,13 @@
   }
 
   private void readSystemProperties() {
-     InstanceKlass systemKls = getSystemDictionary().getSystemKlass();
+     final InstanceKlass systemKls = getSystemDictionary().getSystemKlass();
      systemKls.iterate(new DefaultOopVisitor() {
                                ObjectReader objReader = new ObjectReader();
                                public void doOop(sun.jvm.hotspot.oops.OopField field, boolean isVMField) {
                                   if (field.getID().getName().equals("props")) {
                                      try {
-                                        sysProps = (Properties) objReader.readObject(field.getValue(getObj()));
+                                        sysProps = (Properties) objReader.readObject(field.getValue(systemKls.getJavaMirror()));
                                      } catch (Exception e) {
                                         if (Assert.ASSERTS_ENABLED) {
                                            e.printStackTrace();
--- a/agent/src/share/classes/sun/jvm/hotspot/utilities/HeapHprofBinWriter.java	Thu Mar 03 23:48:25 2011 -0800
+++ b/agent/src/share/classes/sun/jvm/hotspot/utilities/HeapHprofBinWriter.java	Mon Apr 04 19:23:29 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -746,7 +746,7 @@
             out.writeByte((byte)kind);
             if (ik != null) {
                 // static field
-                writeField(field, ik);
+                writeField(field, ik.getJavaMirror());
             }
         }
     }
--- a/agent/test/jdi/sasanity.sh	Thu Mar 03 23:48:25 2011 -0800
+++ b/agent/test/jdi/sasanity.sh	Mon Apr 04 19:23:29 2011 -0700
@@ -43,6 +43,7 @@
 fi
 
 jdk=$1
+shift
 OS=`uname`
 
 if [ "$OS" != "Linux" ]; then
@@ -68,7 +69,7 @@
 
 tmp=/tmp/sagsetup
 rm -f $tmp
-$jdk/bin/java sagtarg > $tmp &
+$jdk/bin/java $* sagtarg > $tmp &
 pid=$!
 while [ ! -s $tmp ] ; do
   # Kludge alert!
--- a/make/hotspot_version	Thu Mar 03 23:48:25 2011 -0800
+++ b/make/hotspot_version	Mon Apr 04 19:23:29 2011 -0700
@@ -35,7 +35,7 @@
 
 HS_MAJOR_VER=21
 HS_MINOR_VER=0
-HS_BUILD_NUMBER=03
+HS_BUILD_NUMBER=06
 
 JDK_MAJOR_VER=1
 JDK_MINOR_VER=7
--- a/make/windows/makefiles/compile.make	Thu Mar 03 23:48:25 2011 -0800
+++ b/make/windows/makefiles/compile.make	Mon Apr 04 19:23:29 2011 -0700
@@ -207,6 +207,9 @@
 # Manifest Tool - used in VS2005 and later to adjust manifests stored
 # as resources inside build artifacts.
 MT=mt.exe
+!if "$(BUILDARCH)" == "i486"
+LINK_FLAGS = /SAFESEH $(LINK_FLAGS)
+!endif
 !endif
 
 # Compile for space above time.
--- a/make/windows/makefiles/launcher.make	Thu Mar 03 23:48:25 2011 -0800
+++ b/make/windows/makefiles/launcher.make	Mon Apr 04 19:23:29 2011 -0700
@@ -1,71 +1,73 @@
-#
-# 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.
-#  
-#
-
-
-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)\" \
-	/D GAMMA \
-	/D LAUNCHER_TYPE=\"gamma\" \
-	/D _CRT_SECURE_NO_WARNINGS \
-	/D _CRT_SECURE_NO_DEPRECATE \
-	/D LINK_INTO_LIBJVM \
-	/I $(WorkSpace)\src\os\windows\launcher \
-	/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 
-
-!if "$(COMPILER_NAME)" == "VS2005"
-# This VS2005 compiler has /GS as a default and requires bufferoverflowU.lib
-#    on the link command line, otherwise we get missing __security_check_cookie
-#    externals at link time. Even with /GS-, you need bufferoverflowU.lib.
-BUFFEROVERFLOWLIB = bufferoverflowU.lib
-LINK_FLAGS = $(LINK_FLAGS) $(BUFFEROVERFLOWLIB)
-!endif
-
-LAUNCHERDIR = $(WorkSpace)/src/os/windows/launcher
-LAUNCHERDIR_SHARE = $(WorkSpace)/src/share/tools/launcher
-
-OUTDIR = launcher
-
-{$(LAUNCHERDIR)}.c{$(OUTDIR)}.obj:
-	-mkdir $(OUTDIR) 2>NUL >NUL
-        $(CPP) $(LAUNCHER_FLAGS) /c /Fo$@ $<
-
-{$(LAUNCHERDIR_SHARE)}.c{$(OUTDIR)}.obj:
-	-mkdir $(OUTDIR) 2>NUL >NUL
-        $(CPP) $(LAUNCHER_FLAGS) /c /Fo$@ $<
-
-$(OUTDIR)\*.obj: $(LAUNCHERDIR)\*.c $(LAUNCHERDIR)\*.h $(LAUNCHERDIR_SHARE)\*.c $(LAUNCHERDIR_SHARE)\*.h
-
-launcher: $(OUTDIR)\java.obj $(OUTDIR)\java_md.obj $(OUTDIR)\jli_util.obj
-	echo $(JAVA_HOME) > jdkpath.txt  
-	$(LINK) $(LINK_FLAGS) /out:hotspot.exe $**
-
-
+#
+# 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.
+#  
+#
+
+
+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)\" \
+	/D GAMMA \
+	/D LAUNCHER_TYPE=\"gamma\" \
+	/D _CRT_SECURE_NO_WARNINGS \
+	/D _CRT_SECURE_NO_DEPRECATE \
+	/D LINK_INTO_LIBJVM \
+	/I $(WorkSpace)\src\os\windows\launcher \
+	/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 
+
+!if "$(COMPILER_NAME)" == "VS2005"
+# This VS2005 compiler has /GS as a default and requires bufferoverflowU.lib
+#    on the link command line, otherwise we get missing __security_check_cookie
+#    externals at link time. Even with /GS-, you need bufferoverflowU.lib.
+BUFFEROVERFLOWLIB = bufferoverflowU.lib
+LINK_FLAGS = $(LINK_FLAGS) $(BUFFEROVERFLOWLIB)
+!endif
+
+!if "$(COMPILER_NAME)" == "VS2010" && "$(BUILDARCH)" == "i486"
+LINK_FLAGS = /SAFESEH $(LINK_FLAGS)
+!endif
+
+LAUNCHERDIR = $(WorkSpace)/src/os/windows/launcher
+LAUNCHERDIR_SHARE = $(WorkSpace)/src/share/tools/launcher
+
+OUTDIR = launcher
+
+{$(LAUNCHERDIR)}.c{$(OUTDIR)}.obj:
+	-mkdir $(OUTDIR) 2>NUL >NUL
+        $(CPP) $(LAUNCHER_FLAGS) /c /Fo$@ $<
+
+{$(LAUNCHERDIR_SHARE)}.c{$(OUTDIR)}.obj:
+	-mkdir $(OUTDIR) 2>NUL >NUL
+        $(CPP) $(LAUNCHER_FLAGS) /c /Fo$@ $<
+
+$(OUTDIR)\*.obj: $(LAUNCHERDIR)\*.c $(LAUNCHERDIR)\*.h $(LAUNCHERDIR_SHARE)\*.c $(LAUNCHERDIR_SHARE)\*.h
+
+launcher: $(OUTDIR)\java.obj $(OUTDIR)\java_md.obj $(OUTDIR)\jli_util.obj
+	echo $(JAVA_HOME) > jdkpath.txt  
+	$(LINK) $(LINK_FLAGS) /out:hotspot.exe $**
--- a/src/cpu/sparc/vm/assembler_sparc.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/cpu/sparc/vm/assembler_sparc.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -3179,7 +3179,7 @@
                                               Label& wrong_method_type) {
   assert_different_registers(mtype_reg, mh_reg, temp_reg);
   // compare method type against that of the receiver
-  RegisterOrConstant mhtype_offset = delayed_value(java_dyn_MethodHandle::type_offset_in_bytes, temp_reg);
+  RegisterOrConstant mhtype_offset = delayed_value(java_lang_invoke_MethodHandle::type_offset_in_bytes, temp_reg);
   load_heap_oop(mh_reg, mhtype_offset, temp_reg);
   cmp(temp_reg, mtype_reg);
   br(Assembler::notEqual, false, Assembler::pn, wrong_method_type);
@@ -3195,14 +3195,14 @@
                                                 Register temp_reg) {
   assert_different_registers(vmslots_reg, mh_reg, temp_reg);
   // load mh.type.form.vmslots
-  if (java_dyn_MethodHandle::vmslots_offset_in_bytes() != 0) {
+  if (java_lang_invoke_MethodHandle::vmslots_offset_in_bytes() != 0) {
     // hoist vmslots into every mh to avoid dependent load chain
-    ld(           Address(mh_reg,    delayed_value(java_dyn_MethodHandle::vmslots_offset_in_bytes, temp_reg)),   vmslots_reg);
+    ld(           Address(mh_reg,    delayed_value(java_lang_invoke_MethodHandle::vmslots_offset_in_bytes, temp_reg)),   vmslots_reg);
   } else {
     Register temp2_reg = vmslots_reg;
-    load_heap_oop(Address(mh_reg,    delayed_value(java_dyn_MethodHandle::type_offset_in_bytes, temp_reg)),      temp2_reg);
-    load_heap_oop(Address(temp2_reg, delayed_value(java_dyn_MethodType::form_offset_in_bytes, temp_reg)),        temp2_reg);
-    ld(           Address(temp2_reg, delayed_value(java_dyn_MethodTypeForm::vmslots_offset_in_bytes, temp_reg)), vmslots_reg);
+    load_heap_oop(Address(mh_reg,    delayed_value(java_lang_invoke_MethodHandle::type_offset_in_bytes, temp_reg)),      temp2_reg);
+    load_heap_oop(Address(temp2_reg, delayed_value(java_lang_invoke_MethodType::form_offset_in_bytes, temp_reg)),        temp2_reg);
+    ld(           Address(temp2_reg, delayed_value(java_lang_invoke_MethodTypeForm::vmslots_offset_in_bytes, temp_reg)), vmslots_reg);
   }
 }
 
@@ -3213,7 +3213,7 @@
 
   // pick out the interpreted side of the handler
   // NOTE: vmentry is not an oop!
-  ld_ptr(mh_reg, delayed_value(java_dyn_MethodHandle::vmentry_offset_in_bytes, temp_reg), temp_reg);
+  ld_ptr(mh_reg, delayed_value(java_lang_invoke_MethodHandle::vmentry_offset_in_bytes, temp_reg), temp_reg);
 
   // off we go...
   ld_ptr(temp_reg, MethodHandleEntry::from_interpreted_entry_offset_in_bytes(), temp_reg);
--- a/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -301,7 +301,8 @@
     // thread.
     assert(_obj != noreg, "must be a valid register");
     assert(_oop_index >= 0, "must have oop index");
-    __ ld_ptr(_obj, instanceKlass::init_thread_offset_in_bytes() + sizeof(klassOopDesc), G3);
+    __ load_heap_oop(_obj, java_lang_Class::klass_offset_in_bytes(), G3);
+    __ ld_ptr(G3, instanceKlass::init_thread_offset_in_bytes() + sizeof(klassOopDesc), G3);
     __ cmp(G2_thread, G3);
     __ br(Assembler::notEqual, false, Assembler::pn, call_patch);
     __ delayed()->nop();
--- a/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -395,9 +395,9 @@
 
   int offset = code_offset();
 
-  __ call(Runtime1::entry_for(Runtime1::handle_exception_id), relocInfo::runtime_call_type);
+  __ call(Runtime1::entry_for(Runtime1::handle_exception_from_callee_id), relocInfo::runtime_call_type);
   __ delayed()->nop();
-  debug_only(__ stop("should have gone to the caller");)
+  __ should_not_reach_here();
   assert(code_offset() - offset <= exception_handler_size, "overflow");
   __ end_a_stub();
 
--- a/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -148,7 +148,7 @@
 
 static OopMap* generate_oop_map(StubAssembler* sasm, bool save_fpu_registers) {
   assert(frame_size_in_bytes == __ total_frame_size_in_bytes(reg_save_size_in_words),
-         " mismatch in calculation");
+         "mismatch in calculation");
   sasm->set_frame_size(frame_size_in_bytes / BytesPerWord);
   int frame_size_in_slots = frame_size_in_bytes / sizeof(jint);
   OopMap* oop_map = new OopMap(frame_size_in_slots, 0);
@@ -176,9 +176,8 @@
 
 static OopMap* save_live_registers(StubAssembler* sasm, bool save_fpu_registers = true) {
   assert(frame_size_in_bytes == __ total_frame_size_in_bytes(reg_save_size_in_words),
-         " mismatch in calculation");
+         "mismatch in calculation");
   __ save_frame_c1(frame_size_in_bytes);
-  sasm->set_frame_size(frame_size_in_bytes / BytesPerWord);
 
   // Record volatile registers as callee-save values in an OopMap so their save locations will be
   // propagated to the caller frame's RegisterMap during StackFrameStream construction (needed for
@@ -367,23 +366,7 @@
   switch (id) {
     case forward_exception_id:
       {
-        // we're handling an exception in the context of a compiled
-        // frame.  The registers have been saved in the standard
-        // places.  Perform an exception lookup in the caller and
-        // dispatch to the handler if found.  Otherwise unwind and
-        // dispatch to the callers exception handler.
-
-        oop_maps = new OopMapSet();
-        OopMap* oop_map = generate_oop_map(sasm, true);
-
-        // transfer the pending exception to the exception_oop
-        __ ld_ptr(G2_thread, in_bytes(JavaThread::pending_exception_offset()), Oexception);
-        __ ld_ptr(Oexception, 0, G0);
-        __ st_ptr(G0, G2_thread, in_bytes(JavaThread::pending_exception_offset()));
-        __ add(I7, frame::pc_return_offset, Oissuing_pc);
-
-        generate_handle_exception(sasm, oop_maps, oop_map);
-        __ should_not_reach_here();
+        oop_maps = generate_handle_exception(id, sasm);
       }
       break;
 
@@ -671,15 +654,14 @@
       break;
 
     case handle_exception_id:
-      {
-        __ set_info("handle_exception", dont_gc_arguments);
-        // make a frame and preserve the caller's caller-save registers
+      { __ set_info("handle_exception", dont_gc_arguments);
+        oop_maps = generate_handle_exception(id, sasm);
+      }
+      break;
 
-        oop_maps = new OopMapSet();
-        OopMap* oop_map = save_live_registers(sasm);
-        __ mov(Oexception->after_save(),  Oexception);
-        __ mov(Oissuing_pc->after_save(), Oissuing_pc);
-        generate_handle_exception(sasm, oop_maps, oop_map);
+    case handle_exception_from_callee_id:
+      { __ set_info("handle_exception_from_callee", dont_gc_arguments);
+        oop_maps = generate_handle_exception(id, sasm);
       }
       break;
 
@@ -696,7 +678,7 @@
                         G2_thread, Oissuing_pc->after_save());
         __ verify_not_null_oop(Oexception->after_save());
 
-        // Restore SP from L7 if the exception PC is a MethodHandle call site.
+        // Restore SP from L7 if the exception PC is a method handle call site.
         __ mov(O0, G5);  // Save the target address.
         __ lduw(Address(G2_thread, JavaThread::is_method_handle_return_offset()), L0);
         __ tst(L0);  // Condition codes are preserved over the restore.
@@ -1006,48 +988,89 @@
 }
 
 
-void Runtime1::generate_handle_exception(StubAssembler* sasm, OopMapSet* oop_maps, OopMap* oop_map, bool) {
-  Label no_deopt;
+OopMapSet* Runtime1::generate_handle_exception(StubID id, StubAssembler* sasm) {
+  __ block_comment("generate_handle_exception");
+
+  // Save registers, if required.
+  OopMapSet* oop_maps = new OopMapSet();
+  OopMap* oop_map = NULL;
+  switch (id) {
+  case forward_exception_id:
+    // We're handling an exception in the context of a compiled frame.
+    // The registers have been saved in the standard places.  Perform
+    // an exception lookup in the caller and dispatch to the handler
+    // if found.  Otherwise unwind and dispatch to the callers
+    // exception handler.
+     oop_map = generate_oop_map(sasm, true);
+
+     // transfer the pending exception to the exception_oop
+     __ ld_ptr(G2_thread, in_bytes(JavaThread::pending_exception_offset()), Oexception);
+     __ ld_ptr(Oexception, 0, G0);
+     __ st_ptr(G0, G2_thread, in_bytes(JavaThread::pending_exception_offset()));
+     __ add(I7, frame::pc_return_offset, Oissuing_pc);
+    break;
+  case handle_exception_id:
+    // At this point all registers MAY be live.
+    oop_map = save_live_registers(sasm);
+    __ mov(Oexception->after_save(),  Oexception);
+    __ mov(Oissuing_pc->after_save(), Oissuing_pc);
+    break;
+  case handle_exception_from_callee_id:
+    // At this point all registers except exception oop (Oexception)
+    // and exception pc (Oissuing_pc) are dead.
+    oop_map = new OopMap(frame_size_in_bytes / sizeof(jint), 0);
+    sasm->set_frame_size(frame_size_in_bytes / BytesPerWord);
+    __ save_frame_c1(frame_size_in_bytes);
+    __ mov(Oexception->after_save(),  Oexception);
+    __ mov(Oissuing_pc->after_save(), Oissuing_pc);
+    break;
+  default:  ShouldNotReachHere();
+  }
 
   __ verify_not_null_oop(Oexception);
 
   // save the exception and issuing pc in the thread
-  __ st_ptr(Oexception, G2_thread, in_bytes(JavaThread::exception_oop_offset()));
+  __ st_ptr(Oexception,  G2_thread, in_bytes(JavaThread::exception_oop_offset()));
   __ st_ptr(Oissuing_pc, G2_thread, in_bytes(JavaThread::exception_pc_offset()));
 
-  // save the real return address and use the throwing pc as the return address to lookup (has bci & oop map)
-  __ mov(I7, L0);
+  // use the throwing pc as the return address to lookup (has bci & oop map)
   __ mov(Oissuing_pc, I7);
   __ sub(I7, frame::pc_return_offset, I7);
   int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, exception_handler_for_pc));
+  oop_maps->add_gc_map(call_offset, oop_map);
 
   // Note: if nmethod has been deoptimized then regardless of
   // whether it had a handler or not we will deoptimize
   // by entering the deopt blob with a pending exception.
 
-#ifdef ASSERT
-  Label done;
-  __ tst(O0);
-  __ br(Assembler::notZero, false, Assembler::pn, done);
-  __ delayed()->nop();
-  __ stop("should have found address");
-  __ bind(done);
-#endif
+  // Restore the registers that were saved at the beginning, remove
+  // the frame and jump to the exception handler.
+  switch (id) {
+  case forward_exception_id:
+  case handle_exception_id:
+    restore_live_registers(sasm);
+    __ jmp(O0, 0);
+    __ delayed()->restore();
+    break;
+  case handle_exception_from_callee_id:
+    // Restore SP from L7 if the exception PC is a method handle call site.
+    __ mov(O0, G5);  // Save the target address.
+    __ lduw(Address(G2_thread, JavaThread::is_method_handle_return_offset()), L0);
+    __ tst(L0);  // Condition codes are preserved over the restore.
+    __ restore();
 
-  // restore the registers that were saved at the beginning and jump to the exception handler.
-  restore_live_registers(sasm);
+    __ jmp(G5, 0);  // jump to the exception handler
+    __ delayed()->movcc(Assembler::notZero, false, Assembler::icc, L7_mh_SP_save, SP);  // Restore SP if required.
+    break;
+  default:  ShouldNotReachHere();
+  }
 
-  __ jmp(O0, 0);
-  __ delayed()->restore();
-
-  oop_maps->add_gc_map(call_offset, oop_map);
+  return oop_maps;
 }
 
 
 #undef __
 
-#define __ masm->
-
 const char *Runtime1::pd_name_for_address(address entry) {
   return "<unknown function>";
 }
--- a/src/cpu/sparc/vm/cppInterpreter_sparc.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/cpu/sparc/vm/cppInterpreter_sparc.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -1188,7 +1188,7 @@
   __ st_ptr(O2, XXX_STATE(_stack));                // PREPUSH
 
   __ lduh(max_stack, O3);                      // Full size expression stack
-  guarantee(!EnableMethodHandles, "no support yet for java.dyn.MethodHandle"); //6815692
+  guarantee(!EnableMethodHandles, "no support yet for java.lang.invoke.MethodHandle"); //6815692
   //6815692//if (EnableMethodHandles)
   //6815692//  __ inc(O3, methodOopDesc::extra_stack_entries());
   __ sll(O3, LogBytesPerWord, O3);
--- a/src/cpu/sparc/vm/dump_sparc.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/cpu/sparc/vm/dump_sparc.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -80,13 +80,19 @@
     for (int j = 0; j < num_virtuals; ++j) {
       dummy_vtable[num_virtuals * i + j] = (void*)masm->pc();
       __ save(SP, -256, SP);
+      int offset = (i << 8) + j;
+      Register src = G0;
+      if (!Assembler::is_simm13(offset)) {
+        __ sethi(offset, L0);
+        src = L0;
+        offset = offset & ((1 << 10) - 1);
+      }
       __ brx(Assembler::always, false, Assembler::pt, common_code);
 
       // Load L0 with a value indicating vtable/offset pair.
       // -- bits[ 7..0]  (8 bits) which virtual method in table?
-      // -- bits[12..8]  (5 bits) which virtual method table?
-      // -- must fit in 13-bit instruction immediate field.
-      __ delayed()->set((i << 8) + j, L0);
+      // -- bits[13..8]  (6 bits) which virtual method table?
+      __ delayed()->or3(src, offset, L0);
     }
   }
 
--- a/src/cpu/sparc/vm/globals_sparc.hpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/cpu/sparc/vm/globals_sparc.hpp	Mon Apr 04 19:23:29 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -51,6 +51,7 @@
 define_pd_global(intx, OptoLoopAlignment,     16);  // = 4*wordSize
 define_pd_global(intx, InlineFrequencyCount,  50);  // we can use more inlining on the SPARC
 define_pd_global(intx, InlineSmallCode,       1500);
+
 #ifdef _LP64
 // Stack slots are 2X larger in LP64 than in the 32 bit VM.
 define_pd_global(intx, ThreadStackSize,       1024);
@@ -75,4 +76,6 @@
 define_pd_global(bool, UseMembar,            false);
 #endif
 
+// GC Ergo Flags
+define_pd_global(intx, CMSYoungGenPerWorker, 16*M);  // default max size of CMS young gen, per GC worker thread
 #endif // CPU_SPARC_VM_GLOBALS_SPARC_HPP
--- a/src/cpu/sparc/vm/interpreter_sparc.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/cpu/sparc/vm/interpreter_sparc.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -260,7 +260,7 @@
 
 
 // Method handle invoker
-// Dispatch a method of the form java.dyn.MethodHandles::invoke(...)
+// Dispatch a method of the form java.lang.invoke.MethodHandles::invoke(...)
 address InterpreterGenerator::generate_method_handle_entry(void) {
   if (!EnableMethodHandles) {
     return generate_abstract_entry();
--- a/src/cpu/sparc/vm/methodHandles_sparc.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/cpu/sparc/vm/methodHandles_sparc.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -112,8 +112,8 @@
   }
 
   // given the MethodType, find out where the MH argument is buried
-  __ load_heap_oop(Address(O0_mtype,   __ delayed_value(java_dyn_MethodType::form_offset_in_bytes,        O1_scratch)), O4_argslot);
-  __ ldsw(         Address(O4_argslot, __ delayed_value(java_dyn_MethodTypeForm::vmslots_offset_in_bytes, O1_scratch)), O4_argslot);
+  __ load_heap_oop(Address(O0_mtype,   __ delayed_value(java_lang_invoke_MethodType::form_offset_in_bytes,        O1_scratch)), O4_argslot);
+  __ ldsw(         Address(O4_argslot, __ delayed_value(java_lang_invoke_MethodTypeForm::vmslots_offset_in_bytes, O1_scratch)), O4_argslot);
   __ add(Gargs, __ argument_offset(O4_argslot, 1), O4_argbase);
   // Note: argument_address uses its input as a scratch register!
   __ ld_ptr(Address(O4_argbase, -Interpreter::stackElementSize), G3_method_handle);
@@ -141,10 +141,10 @@
   // load up an adapter from the calling type (Java weaves this)
   Register O2_form    = O2_scratch;
   Register O3_adapter = O3_scratch;
-  __ load_heap_oop(Address(O0_mtype, __ delayed_value(java_dyn_MethodType::form_offset_in_bytes,               O1_scratch)), O2_form);
-  // load_heap_oop(Address(O2_form,  __ delayed_value(java_dyn_MethodTypeForm::genericInvoker_offset_in_bytes, O1_scratch)), O3_adapter);
+  __ load_heap_oop(Address(O0_mtype, __ delayed_value(java_lang_invoke_MethodType::form_offset_in_bytes,               O1_scratch)), O2_form);
+  // load_heap_oop(Address(O2_form,  __ delayed_value(java_lang_invoke_MethodTypeForm::genericInvoker_offset_in_bytes, O1_scratch)), O3_adapter);
   // deal with old JDK versions:
-  __ add(          Address(O2_form,  __ delayed_value(java_dyn_MethodTypeForm::genericInvoker_offset_in_bytes, O1_scratch)), O3_adapter);
+  __ add(          Address(O2_form,  __ delayed_value(java_lang_invoke_MethodTypeForm::genericInvoker_offset_in_bytes, O1_scratch)), O3_adapter);
   __ cmp(O3_adapter, O2_form);
   Label sorry_no_invoke_generic;
   __ brx(Assembler::lessUnsigned, false, Assembler::pn, sorry_no_invoke_generic);
@@ -376,16 +376,16 @@
 
 // which conversion op types are implemented here?
 int MethodHandles::adapter_conversion_ops_supported_mask() {
-  return ((1<<sun_dyn_AdapterMethodHandle::OP_RETYPE_ONLY)
-         |(1<<sun_dyn_AdapterMethodHandle::OP_RETYPE_RAW)
-         |(1<<sun_dyn_AdapterMethodHandle::OP_CHECK_CAST)
-         |(1<<sun_dyn_AdapterMethodHandle::OP_PRIM_TO_PRIM)
-         |(1<<sun_dyn_AdapterMethodHandle::OP_REF_TO_PRIM)
-         |(1<<sun_dyn_AdapterMethodHandle::OP_SWAP_ARGS)
-         |(1<<sun_dyn_AdapterMethodHandle::OP_ROT_ARGS)
-         |(1<<sun_dyn_AdapterMethodHandle::OP_DUP_ARGS)
-         |(1<<sun_dyn_AdapterMethodHandle::OP_DROP_ARGS)
-         //|(1<<sun_dyn_AdapterMethodHandle::OP_SPREAD_ARGS) //BUG!
+  return ((1<<java_lang_invoke_AdapterMethodHandle::OP_RETYPE_ONLY)
+         |(1<<java_lang_invoke_AdapterMethodHandle::OP_RETYPE_RAW)
+         |(1<<java_lang_invoke_AdapterMethodHandle::OP_CHECK_CAST)
+         |(1<<java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_PRIM)
+         |(1<<java_lang_invoke_AdapterMethodHandle::OP_REF_TO_PRIM)
+         |(1<<java_lang_invoke_AdapterMethodHandle::OP_SWAP_ARGS)
+         |(1<<java_lang_invoke_AdapterMethodHandle::OP_ROT_ARGS)
+         |(1<<java_lang_invoke_AdapterMethodHandle::OP_DUP_ARGS)
+         |(1<<java_lang_invoke_AdapterMethodHandle::OP_DROP_ARGS)
+         //|(1<<java_lang_invoke_AdapterMethodHandle::OP_SPREAD_ARGS) //BUG!
          );
   // FIXME: MethodHandlesTest gets a crash if we enable OP_SPREAD_ARGS.
 }
@@ -413,21 +413,22 @@
   const Register O1_actual   = O1;
   const Register O2_required = O2;
 
-  guarantee(java_dyn_MethodHandle::vmentry_offset_in_bytes() != 0, "must have offsets");
+  guarantee(java_lang_invoke_MethodHandle::vmentry_offset_in_bytes() != 0, "must have offsets");
 
   // Some handy addresses:
   Address G5_method_fie(    G5_method,        in_bytes(methodOopDesc::from_interpreted_offset()));
+  Address G5_method_fce(    G5_method,        in_bytes(methodOopDesc::from_compiled_offset()));
 
-  Address G3_mh_vmtarget(   G3_method_handle, java_dyn_MethodHandle::vmtarget_offset_in_bytes());
+  Address G3_mh_vmtarget(   G3_method_handle, java_lang_invoke_MethodHandle::vmtarget_offset_in_bytes());
 
-  Address G3_dmh_vmindex(   G3_method_handle, sun_dyn_DirectMethodHandle::vmindex_offset_in_bytes());
+  Address G3_dmh_vmindex(   G3_method_handle, java_lang_invoke_DirectMethodHandle::vmindex_offset_in_bytes());
 
-  Address G3_bmh_vmargslot( G3_method_handle, sun_dyn_BoundMethodHandle::vmargslot_offset_in_bytes());
-  Address G3_bmh_argument(  G3_method_handle, sun_dyn_BoundMethodHandle::argument_offset_in_bytes());
+  Address G3_bmh_vmargslot( G3_method_handle, java_lang_invoke_BoundMethodHandle::vmargslot_offset_in_bytes());
+  Address G3_bmh_argument(  G3_method_handle, java_lang_invoke_BoundMethodHandle::argument_offset_in_bytes());
 
-  Address G3_amh_vmargslot( G3_method_handle, sun_dyn_AdapterMethodHandle::vmargslot_offset_in_bytes());
-  Address G3_amh_argument ( G3_method_handle, sun_dyn_AdapterMethodHandle::argument_offset_in_bytes());
-  Address G3_amh_conversion(G3_method_handle, sun_dyn_AdapterMethodHandle::conversion_offset_in_bytes());
+  Address G3_amh_vmargslot( G3_method_handle, java_lang_invoke_AdapterMethodHandle::vmargslot_offset_in_bytes());
+  Address G3_amh_argument ( G3_method_handle, java_lang_invoke_AdapterMethodHandle::argument_offset_in_bytes());
+  Address G3_amh_conversion(G3_method_handle, java_lang_invoke_AdapterMethodHandle::conversion_offset_in_bytes());
 
   const int java_mirror_offset = klassOopDesc::klass_part_offset_in_bytes() + Klass::java_mirror_offset_in_bytes();
 
@@ -444,17 +445,15 @@
   case _raise_exception:
     {
       // Not a real MH entry, but rather shared code for raising an
-      // exception.  Since we use a C2I adapter to set up the
-      // interpreter state, arguments are expected in compiler
-      // argument registers.
+      // exception.  Since we use the compiled entry, arguments are
+      // expected in compiler argument registers.
       assert(raise_exception_method(), "must be set");
-      address c2i_entry = raise_exception_method()->get_c2i_entry();
-      assert(c2i_entry, "method must be linked");
+      assert(raise_exception_method()->from_compiled_entry(), "method must be linked");
 
       __ mov(O5_savedSP, SP);  // Cut the stack back to where the caller started.
 
       Label L_no_method;
-      // FIXME: fill in _raise_exception_method with a suitable sun.dyn method
+      // FIXME: fill in _raise_exception_method with a suitable java.lang.invoke method
       __ set(AddressLiteral((address) &_raise_exception_method), G5_method);
       __ ld_ptr(Address(G5_method, 0), G5_method);
       __ tst(G5_method);
@@ -468,10 +467,9 @@
       __ delayed()->nop();
 
       __ verify_oop(G5_method);
-      __ jump_to(AddressLiteral(c2i_entry), O3_scratch);
+      __ jump_indirect_to(G5_method_fce, O3_scratch);  // jump to compiled entry
       __ delayed()->nop();
 
-      // If we get here, the Java runtime did not do its job of creating the exception.
       // Do something that is at least causes a valid throw from the interpreter.
       __ bind(L_no_method);
       __ unimplemented("call throw_WrongMethodType_entry");
@@ -777,9 +775,13 @@
       switch (ek) {
       case _adapter_opt_i2l:
         {
-          __ ldsw(arg_lsw, O2_scratch);                           // Load LSW
-          NOT_LP64(__ srlx(O2_scratch, BitsPerInt, O3_scratch));  // Move high bits to lower bits for std
-          __ st_long(O2_scratch, arg_msw);                        // Uses O2/O3 on !_LP64
+#ifdef _LP64
+          __ ldsw(arg_lsw, O2_scratch);                 // Load LSW sign-extended
+#else
+          __ ldsw(arg_lsw, O3_scratch);                 // Load LSW sign-extended
+          __ srlx(O3_scratch, BitsPerInt, O2_scratch);  // Move MSW value to lower 32-bits for std
+#endif
+          __ st_long(O2_scratch, arg_msw);              // Uses O2/O3 on !_LP64
         }
         break;
       case _adapter_opt_unboxl:
--- a/src/cpu/sparc/vm/nativeInst_sparc.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/cpu/sparc/vm/nativeInst_sparc.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -52,6 +52,22 @@
   ICache::invalidate_range(instaddr, 7 * BytesPerInstWord);
 }
 
+void NativeInstruction::verify_data64_sethi(address instaddr, intptr_t x) {
+  ResourceMark rm;
+  unsigned char buffer[10 * BytesPerInstWord];
+  CodeBuffer buf(buffer, 10 * BytesPerInstWord);
+  MacroAssembler masm(&buf);
+
+  Register destreg = inv_rd(*(unsigned int *)instaddr);
+  // Generate the proper sequence into a temporary buffer and compare
+  // it with the original sequence.
+  masm.patchable_sethi(x, destreg);
+  int len = buffer - masm.pc();
+  for (int i = 0; i < len; i++) {
+    assert(instaddr[i] == buffer[i], "instructions must match");
+  }
+}
+
 void NativeInstruction::verify() {
   // make sure code pattern is actually an instruction address
   address addr = addr_at(0);
--- a/src/cpu/sparc/vm/nativeInst_sparc.hpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/cpu/sparc/vm/nativeInst_sparc.hpp	Mon Apr 04 19:23:29 2011 -0700
@@ -254,6 +254,7 @@
   // sethi.  This only does the sethi.  The disp field (bottom 10 bits)
   // must be handled separately.
   static void set_data64_sethi(address instaddr, intptr_t x);
+  static void verify_data64_sethi(address instaddr, intptr_t x);
 
   // combine the fields of a sethi/simm13 pair (simm13 = or, add, jmpl, ld/st)
   static int data32(int sethi_insn, int arith_insn) {
--- a/src/cpu/sparc/vm/relocInfo_sparc.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/cpu/sparc/vm/relocInfo_sparc.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -30,7 +30,7 @@
 #include "oops/oop.inline.hpp"
 #include "runtime/safepoint.hpp"
 
-void Relocation::pd_set_data_value(address x, intptr_t o) {
+void Relocation::pd_set_data_value(address x, intptr_t o, bool verify_only) {
   NativeInstruction* ip = nativeInstruction_at(addr());
   jint inst = ip->long_at(0);
   assert(inst != NativeInstruction::illegal_instruction(), "no breakpoint");
@@ -83,7 +83,11 @@
     guarantee(Assembler::is_simm13(simm13), "offset can't overflow simm13");
     inst &= ~Assembler::simm(    -1, 13);
     inst |=  Assembler::simm(simm13, 13);
-    ip->set_long_at(0, inst);
+    if (verify_only) {
+      assert(ip->long_at(0) == inst, "instructions must match");
+    } else {
+      ip->set_long_at(0, inst);
+    }
     }
     break;
 
@@ -97,19 +101,36 @@
       jint np = oopDesc::encode_heap_oop((oop)x);
       inst &= ~Assembler::hi22(-1);
       inst |=  Assembler::hi22((intptr_t)np);
-      ip->set_long_at(0, inst);
+      if (verify_only) {
+        assert(ip->long_at(0) == inst, "instructions must match");
+      } else {
+        ip->set_long_at(0, inst);
+      }
       inst2 = ip->long_at( NativeInstruction::nop_instruction_size );
       guarantee(Assembler::inv_op(inst2)==Assembler::arith_op, "arith op");
-      ip->set_long_at(NativeInstruction::nop_instruction_size, ip->set_data32_simm13( inst2, (intptr_t)np));
+      if (verify_only) {
+        assert(ip->long_at(NativeInstruction::nop_instruction_size) == NativeInstruction::set_data32_simm13( inst2, (intptr_t)np),
+               "instructions must match");
+      } else {
+        ip->set_long_at(NativeInstruction::nop_instruction_size, NativeInstruction::set_data32_simm13( inst2, (intptr_t)np));
+      }
       break;
     }
-    ip->set_data64_sethi( ip->addr_at(0), (intptr_t)x );
+    if (verify_only) {
+      ip->verify_data64_sethi( ip->addr_at(0), (intptr_t)x );
+    } else {
+      ip->set_data64_sethi( ip->addr_at(0), (intptr_t)x );
+    }
 #else
     guarantee(Assembler::inv_op2(inst)==Assembler::sethi_op2, "must be sethi");
     inst &= ~Assembler::hi22(     -1);
     inst |=  Assembler::hi22((intptr_t)x);
     // (ignore offset; it doesn't play into the sethi)
-    ip->set_long_at(0, inst);
+    if (verify_only) {
+      assert(ip->long_at(0) == inst, "instructions must match");
+    } else {
+      ip->set_long_at(0, inst);
+    }
 #endif
     }
     break;
--- a/src/cpu/sparc/vm/stubGenerator_sparc.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/cpu/sparc/vm/stubGenerator_sparc.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -968,19 +968,6 @@
     return start;
   }
 
-  static address disjoint_byte_copy_entry;
-  static address disjoint_short_copy_entry;
-  static address disjoint_int_copy_entry;
-  static address disjoint_long_copy_entry;
-  static address disjoint_oop_copy_entry;
-
-  static address byte_copy_entry;
-  static address short_copy_entry;
-  static address int_copy_entry;
-  static address long_copy_entry;
-  static address oop_copy_entry;
-
-  static address checkcast_copy_entry;
 
   //
   // Verify that a register contains clean 32-bits positive value
@@ -1046,31 +1033,40 @@
   //
   //  The input registers are overwritten.
   //
-  void gen_write_ref_array_pre_barrier(Register addr, Register count) {
+  void gen_write_ref_array_pre_barrier(Register addr, Register count, bool dest_uninitialized) {
     BarrierSet* bs = Universe::heap()->barrier_set();
-    if (bs->has_write_ref_pre_barrier()) {
-      assert(bs->has_write_ref_array_pre_opt(),
-             "Else unsupported barrier set.");
-
-      __ save_frame(0);
-      // Save the necessary global regs... will be used after.
-      if (addr->is_global()) {
-        __ mov(addr, L0);
-      }
-      if (count->is_global()) {
-        __ mov(count, L1);
-      }
-      __ mov(addr->after_save(), O0);
-      // Get the count into O1
-      __ call(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre));
-      __ delayed()->mov(count->after_save(), O1);
-      if (addr->is_global()) {
-        __ mov(L0, addr);
-      }
-      if (count->is_global()) {
-        __ mov(L1, count);
-      }
-      __ restore();
+    switch (bs->kind()) {
+      case BarrierSet::G1SATBCT:
+      case BarrierSet::G1SATBCTLogging:
+        // With G1, don't generate the call if we statically know that the target in uninitialized
+        if (!dest_uninitialized) {
+          __ save_frame(0);
+          // Save the necessary global regs... will be used after.
+          if (addr->is_global()) {
+            __ mov(addr, L0);
+          }
+          if (count->is_global()) {
+            __ mov(count, L1);
+          }
+          __ mov(addr->after_save(), O0);
+          // Get the count into O1
+          __ call(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre));
+          __ delayed()->mov(count->after_save(), O1);
+          if (addr->is_global()) {
+            __ mov(L0, addr);
+          }
+          if (count->is_global()) {
+            __ mov(L1, count);
+          }
+          __ restore();
+        }
+        break;
+      case BarrierSet::CardTableModRef:
+      case BarrierSet::CardTableExtension:
+      case BarrierSet::ModRef:
+        break;
+      default:
+        ShouldNotReachHere();
     }
   }
   //
@@ -1084,7 +1080,7 @@
   //  The input registers are overwritten.
   //
   void gen_write_ref_array_post_barrier(Register addr, Register count,
-                                   Register tmp) {
+                                        Register tmp) {
     BarrierSet* bs = Universe::heap()->barrier_set();
 
     switch (bs->kind()) {
@@ -1283,7 +1279,7 @@
   //      to:    O1
   //      count: O2 treated as signed
   //
-  address generate_disjoint_byte_copy(bool aligned, const char * name) {
+  address generate_disjoint_byte_copy(bool aligned, address *entry, const char *name) {
     __ align(CodeEntryAlignment);
     StubCodeMark mark(this, "StubRoutines", name);
     address start = __ pc();
@@ -1299,9 +1295,11 @@
 
     assert_clean_int(count, O3);     // Make sure 'count' is clean int.
 
-    if (!aligned)  disjoint_byte_copy_entry = __ pc();
-    // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
-    if (!aligned)  BLOCK_COMMENT("Entry:");
+    if (entry != NULL) {
+      *entry = __ pc();
+      // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
+      BLOCK_COMMENT("Entry:");
+    }
 
     // for short arrays, just do single element copy
     __ cmp(count, 23); // 16 + 7
@@ -1391,15 +1389,13 @@
   //      to:    O1
   //      count: O2 treated as signed
   //
-  address generate_conjoint_byte_copy(bool aligned, const char * name) {
+  address generate_conjoint_byte_copy(bool aligned, address nooverlap_target,
+                                      address *entry, const char *name) {
     // Do reverse copy.
 
     __ align(CodeEntryAlignment);
     StubCodeMark mark(this, "StubRoutines", name);
     address start = __ pc();
-    address nooverlap_target = aligned ?
-        StubRoutines::arrayof_jbyte_disjoint_arraycopy() :
-        disjoint_byte_copy_entry;
 
     Label L_skip_alignment, L_align, L_aligned_copy;
     Label L_copy_byte, L_copy_byte_loop, L_exit;
@@ -1412,9 +1408,11 @@
 
     assert_clean_int(count, O3);     // Make sure 'count' is clean int.
 
-    if (!aligned)  byte_copy_entry = __ pc();
-    // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
-    if (!aligned)  BLOCK_COMMENT("Entry:");
+    if (entry != NULL) {
+      *entry = __ pc();
+      // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
+      BLOCK_COMMENT("Entry:");
+    }
 
     array_overlap_test(nooverlap_target, 0);
 
@@ -1504,7 +1502,7 @@
   //      to:    O1
   //      count: O2 treated as signed
   //
-  address generate_disjoint_short_copy(bool aligned, const char * name) {
+  address generate_disjoint_short_copy(bool aligned, address *entry, const char * name) {
     __ align(CodeEntryAlignment);
     StubCodeMark mark(this, "StubRoutines", name);
     address start = __ pc();
@@ -1520,9 +1518,11 @@
 
     assert_clean_int(count, O3);     // Make sure 'count' is clean int.
 
-    if (!aligned)  disjoint_short_copy_entry = __ pc();
-    // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
-    if (!aligned)  BLOCK_COMMENT("Entry:");
+    if (entry != NULL) {
+      *entry = __ pc();
+      // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
+      BLOCK_COMMENT("Entry:");
+    }
 
     // for short arrays, just do single element copy
     __ cmp(count, 11); // 8 + 3  (22 bytes)
@@ -1842,15 +1842,13 @@
   //      to:    O1
   //      count: O2 treated as signed
   //
-  address generate_conjoint_short_copy(bool aligned, const char * name) {
+  address generate_conjoint_short_copy(bool aligned, address nooverlap_target,
+                                       address *entry, const char *name) {
     // Do reverse copy.
 
     __ align(CodeEntryAlignment);
     StubCodeMark mark(this, "StubRoutines", name);
     address start = __ pc();
-    address nooverlap_target = aligned ?
-        StubRoutines::arrayof_jshort_disjoint_arraycopy() :
-        disjoint_short_copy_entry;
 
     Label L_skip_alignment, L_skip_alignment2, L_aligned_copy;
     Label L_copy_2_bytes, L_copy_2_bytes_loop, L_exit;
@@ -1865,9 +1863,11 @@
 
     assert_clean_int(count, O3);     // Make sure 'count' is clean int.
 
-    if (!aligned)  short_copy_entry = __ pc();
-    // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
-    if (!aligned)  BLOCK_COMMENT("Entry:");
+    if (entry != NULL) {
+      *entry = __ pc();
+      // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
+      BLOCK_COMMENT("Entry:");
+    }
 
     array_overlap_test(nooverlap_target, 1);
 
@@ -2072,7 +2072,7 @@
   //      to:    O1
   //      count: O2 treated as signed
   //
-  address generate_disjoint_int_copy(bool aligned, const char * name) {
+  address generate_disjoint_int_copy(bool aligned, address *entry, const char *name) {
     __ align(CodeEntryAlignment);
     StubCodeMark mark(this, "StubRoutines", name);
     address start = __ pc();
@@ -2080,9 +2080,11 @@
     const Register count = O2;
     assert_clean_int(count, O3);     // Make sure 'count' is clean int.
 
-    if (!aligned)  disjoint_int_copy_entry = __ pc();
-    // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
-    if (!aligned)  BLOCK_COMMENT("Entry:");
+    if (entry != NULL) {
+      *entry = __ pc();
+      // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
+      BLOCK_COMMENT("Entry:");
+    }
 
     generate_disjoint_int_copy_core(aligned);
 
@@ -2204,20 +2206,19 @@
   //      to:    O1
   //      count: O2 treated as signed
   //
-  address generate_conjoint_int_copy(bool aligned, const char * name) {
+  address generate_conjoint_int_copy(bool aligned, address nooverlap_target,
+                                     address *entry, const char *name) {
     __ align(CodeEntryAlignment);
     StubCodeMark mark(this, "StubRoutines", name);
     address start = __ pc();
 
-    address nooverlap_target = aligned ?
-        StubRoutines::arrayof_jint_disjoint_arraycopy() :
-        disjoint_int_copy_entry;
-
     assert_clean_int(O2, O3);     // Make sure 'count' is clean int.
 
-    if (!aligned)  int_copy_entry = __ pc();
-    // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
-    if (!aligned)  BLOCK_COMMENT("Entry:");
+    if (entry != NULL) {
+      *entry = __ pc();
+      // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
+      BLOCK_COMMENT("Entry:");
+    }
 
     array_overlap_test(nooverlap_target, 2);
 
@@ -2336,16 +2337,18 @@
   //      to:    O1
   //      count: O2 treated as signed
   //
-  address generate_disjoint_long_copy(bool aligned, const char * name) {
+  address generate_disjoint_long_copy(bool aligned, address *entry, const char *name) {
     __ align(CodeEntryAlignment);
     StubCodeMark mark(this, "StubRoutines", name);
     address start = __ pc();
 
     assert_clean_int(O2, O3);     // Make sure 'count' is clean int.
 
-    if (!aligned)  disjoint_long_copy_entry = __ pc();
-    // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
-    if (!aligned)  BLOCK_COMMENT("Entry:");
+    if (entry != NULL) {
+      *entry = __ pc();
+      // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
+      BLOCK_COMMENT("Entry:");
+    }
 
     generate_disjoint_long_copy_core(aligned);
 
@@ -2406,19 +2409,21 @@
   //      to:    O1
   //      count: O2 treated as signed
   //
-  address generate_conjoint_long_copy(bool aligned, const char * name) {
+  address generate_conjoint_long_copy(bool aligned, address nooverlap_target,
+                                      address *entry, const char *name) {
     __ align(CodeEntryAlignment);
     StubCodeMark mark(this, "StubRoutines", name);
     address start = __ pc();
 
-    assert(!aligned, "usage");
-    address nooverlap_target = disjoint_long_copy_entry;
+    assert(aligned, "Should always be aligned");
 
     assert_clean_int(O2, O3);     // Make sure 'count' is clean int.
 
-    if (!aligned)  long_copy_entry = __ pc();
-    // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
-    if (!aligned)  BLOCK_COMMENT("Entry:");
+    if (entry != NULL) {
+      *entry = __ pc();
+      // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
+      BLOCK_COMMENT("Entry:");
+    }
 
     array_overlap_test(nooverlap_target, 3);
 
@@ -2439,7 +2444,8 @@
   //      to:    O1
   //      count: O2 treated as signed
   //
-  address generate_disjoint_oop_copy(bool aligned, const char * name) {
+  address generate_disjoint_oop_copy(bool aligned, address *entry, const char *name,
+                                     bool dest_uninitialized = false) {
 
     const Register from  = O0;  // source array address
     const Register to    = O1;  // destination array address
@@ -2451,14 +2457,16 @@
 
     assert_clean_int(count, O3);     // Make sure 'count' is clean int.
 
-    if (!aligned)  disjoint_oop_copy_entry = __ pc();
-    // caller can pass a 64-bit byte count here
-    if (!aligned)  BLOCK_COMMENT("Entry:");
+    if (entry != NULL) {
+      *entry = __ pc();
+      // caller can pass a 64-bit byte count here
+      BLOCK_COMMENT("Entry:");
+    }
 
     // save arguments for barrier generation
     __ mov(to, G1);
     __ mov(count, G5);
-    gen_write_ref_array_pre_barrier(G1, G5);
+    gen_write_ref_array_pre_barrier(G1, G5, dest_uninitialized);
   #ifdef _LP64
     assert_clean_int(count, O3);     // Make sure 'count' is clean int.
     if (UseCompressedOops) {
@@ -2487,7 +2495,9 @@
   //      to:    O1
   //      count: O2 treated as signed
   //
-  address generate_conjoint_oop_copy(bool aligned, const char * name) {
+  address generate_conjoint_oop_copy(bool aligned, address nooverlap_target,
+                                     address *entry, const char *name,
+                                     bool dest_uninitialized = false) {
 
     const Register from  = O0;  // source array address
     const Register to    = O1;  // destination array address
@@ -2499,21 +2509,18 @@
 
     assert_clean_int(count, O3);     // Make sure 'count' is clean int.
 
-    if (!aligned)  oop_copy_entry = __ pc();
-    // caller can pass a 64-bit byte count here
-    if (!aligned)  BLOCK_COMMENT("Entry:");
+    if (entry != NULL) {
+      *entry = __ pc();
+      // caller can pass a 64-bit byte count here
+      BLOCK_COMMENT("Entry:");
+    }
+
+    array_overlap_test(nooverlap_target, LogBytesPerHeapOop);
 
     // save arguments for barrier generation
     __ mov(to, G1);
     __ mov(count, G5);
-
-    gen_write_ref_array_pre_barrier(G1, G5);
-
-    address nooverlap_target = aligned ?
-        StubRoutines::arrayof_oop_disjoint_arraycopy() :
-        disjoint_oop_copy_entry;
-
-    array_overlap_test(nooverlap_target, LogBytesPerHeapOop);
+    gen_write_ref_array_pre_barrier(G1, G5, dest_uninitialized);
 
   #ifdef _LP64
     if (UseCompressedOops) {
@@ -2582,7 +2589,7 @@
   //      ckval: O4 (super_klass)
   //      ret:   O0 zero for success; (-1^K) where K is partial transfer count
   //
-  address generate_checkcast_copy(const char* name) {
+  address generate_checkcast_copy(const char *name, address *entry, bool dest_uninitialized = false) {
 
     const Register O0_from   = O0;      // source array address
     const Register O1_to     = O1;      // destination array address
@@ -2600,8 +2607,6 @@
     StubCodeMark mark(this, "StubRoutines", name);
     address start = __ pc();
 
-    gen_write_ref_array_pre_barrier(O1, O2);
-
 #ifdef ASSERT
     // We sometimes save a frame (see generate_type_check below).
     // If this will cause trouble, let's fail now instead of later.
@@ -2625,9 +2630,12 @@
     }
 #endif //ASSERT
 
-    checkcast_copy_entry = __ pc();
-    // caller can pass a 64-bit byte count here (from generic stub)
-    BLOCK_COMMENT("Entry:");
+    if (entry != NULL) {
+      *entry = __ pc();
+      // caller can pass a 64-bit byte count here (from generic stub)
+      BLOCK_COMMENT("Entry:");
+    }
+    gen_write_ref_array_pre_barrier(O1_to, O2_count, dest_uninitialized);
 
     Label load_element, store_element, do_card_marks, fail, done;
     __ addcc(O2_count, 0, G1_remain);   // initialize loop index, and test it
@@ -2700,7 +2708,11 @@
   // Examines the alignment of the operands and dispatches
   // to a long, int, short, or byte copy loop.
   //
-  address generate_unsafe_copy(const char* name) {
+  address generate_unsafe_copy(const char* name,
+                               address byte_copy_entry,
+                               address short_copy_entry,
+                               address int_copy_entry,
+                               address long_copy_entry) {
 
     const Register O0_from   = O0;      // source array address
     const Register O1_to     = O1;      // destination array address
@@ -2796,8 +2808,13 @@
   //    O0 ==  0  -  success
   //    O0 == -1  -  need to call System.arraycopy
   //
-  address generate_generic_copy(const char *name) {
-
+  address generate_generic_copy(const char *name,
+                                address entry_jbyte_arraycopy,
+                                address entry_jshort_arraycopy,
+                                address entry_jint_arraycopy,
+                                address entry_oop_arraycopy,
+                                address entry_jlong_arraycopy,
+                                address entry_checkcast_arraycopy) {
     Label L_failed, L_objArray;
 
     // Input registers
@@ -2970,15 +2987,15 @@
 
     BLOCK_COMMENT("choose copy loop based on element size");
     __ cmp(G3_elsize, 0);
-    __ br(Assembler::equal,true,Assembler::pt,StubRoutines::_jbyte_arraycopy);
+    __ br(Assembler::equal, true, Assembler::pt, entry_jbyte_arraycopy);
     __ delayed()->signx(length, count); // length
 
     __ cmp(G3_elsize, LogBytesPerShort);
-    __ br(Assembler::equal,true,Assembler::pt,StubRoutines::_jshort_arraycopy);
+    __ br(Assembler::equal, true, Assembler::pt, entry_jshort_arraycopy);
     __ delayed()->signx(length, count); // length
 
     __ cmp(G3_elsize, LogBytesPerInt);
-    __ br(Assembler::equal,true,Assembler::pt,StubRoutines::_jint_arraycopy);
+    __ br(Assembler::equal, true, Assembler::pt, entry_jint_arraycopy);
     __ delayed()->signx(length, count); // length
 #ifdef ASSERT
     { Label L;
@@ -2989,7 +3006,7 @@
       __ bind(L);
     }
 #endif
-    __ br(Assembler::always,false,Assembler::pt,StubRoutines::_jlong_arraycopy);
+    __ br(Assembler::always, false, Assembler::pt, entry_jlong_arraycopy);
     __ delayed()->signx(length, count); // length
 
     // objArrayKlass
@@ -3013,7 +3030,7 @@
     __ add(src, src_pos, from);       // src_addr
     __ add(dst, dst_pos, to);         // dst_addr
   __ BIND(L_plain_copy);
-    __ br(Assembler::always, false, Assembler::pt,StubRoutines::_oop_arraycopy);
+    __ br(Assembler::always, false, Assembler::pt, entry_oop_arraycopy);
     __ delayed()->signx(length, count); // length
 
   __ BIND(L_checkcast_copy);
@@ -3057,7 +3074,7 @@
       __ ld_ptr(G4_dst_klass, ek_offset, O4);   // dest elem klass
       // lduw(O4, sco_offset, O3);              // sco of elem klass
 
-      __ br(Assembler::always, false, Assembler::pt, checkcast_copy_entry);
+      __ br(Assembler::always, false, Assembler::pt, entry_checkcast_arraycopy);
       __ delayed()->lduw(O4, sco_offset, O3);
     }
 
@@ -3068,39 +3085,124 @@
   }
 
   void generate_arraycopy_stubs() {
-
-    // Note:  the disjoint stubs must be generated first, some of
-    //        the conjoint stubs use them.
-    StubRoutines::_jbyte_disjoint_arraycopy  = generate_disjoint_byte_copy(false, "jbyte_disjoint_arraycopy");
-    StubRoutines::_jshort_disjoint_arraycopy = generate_disjoint_short_copy(false, "jshort_disjoint_arraycopy");
-    StubRoutines::_jint_disjoint_arraycopy   = generate_disjoint_int_copy(false, "jint_disjoint_arraycopy");
-    StubRoutines::_jlong_disjoint_arraycopy  = generate_disjoint_long_copy(false, "jlong_disjoint_arraycopy");
-    StubRoutines::_oop_disjoint_arraycopy    = generate_disjoint_oop_copy(false, "oop_disjoint_arraycopy");
-    StubRoutines::_arrayof_jbyte_disjoint_arraycopy  = generate_disjoint_byte_copy(true, "arrayof_jbyte_disjoint_arraycopy");
-    StubRoutines::_arrayof_jshort_disjoint_arraycopy = generate_disjoint_short_copy(true, "arrayof_jshort_disjoint_arraycopy");
-    StubRoutines::_arrayof_jint_disjoint_arraycopy   = generate_disjoint_int_copy(true, "arrayof_jint_disjoint_arraycopy");
-    StubRoutines::_arrayof_jlong_disjoint_arraycopy  = generate_disjoint_long_copy(true, "arrayof_jlong_disjoint_arraycopy");
-    StubRoutines::_arrayof_oop_disjoint_arraycopy    =  generate_disjoint_oop_copy(true, "arrayof_oop_disjoint_arraycopy");
-
-    StubRoutines::_jbyte_arraycopy  = generate_conjoint_byte_copy(false, "jbyte_arraycopy");
-    StubRoutines::_jshort_arraycopy = generate_conjoint_short_copy(false, "jshort_arraycopy");
-    StubRoutines::_jint_arraycopy   = generate_conjoint_int_copy(false, "jint_arraycopy");
-    StubRoutines::_jlong_arraycopy  = generate_conjoint_long_copy(false, "jlong_arraycopy");
-    StubRoutines::_oop_arraycopy    = generate_conjoint_oop_copy(false, "oop_arraycopy");
-    StubRoutines::_arrayof_jbyte_arraycopy    = generate_conjoint_byte_copy(true, "arrayof_jbyte_arraycopy");
-    StubRoutines::_arrayof_jshort_arraycopy   = generate_conjoint_short_copy(true, "arrayof_jshort_arraycopy");
+    address entry;
+    address entry_jbyte_arraycopy;
+    address entry_jshort_arraycopy;
+    address entry_jint_arraycopy;
+    address entry_oop_arraycopy;
+    address entry_jlong_arraycopy;
+    address entry_checkcast_arraycopy;
+
+    //*** jbyte
+    // Always need aligned and unaligned versions
+    StubRoutines::_jbyte_disjoint_arraycopy         = generate_disjoint_byte_copy(false, &entry,
+                                                                                  "jbyte_disjoint_arraycopy");
+    StubRoutines::_jbyte_arraycopy                  = generate_conjoint_byte_copy(false, entry,
+                                                                                  &entry_jbyte_arraycopy,
+                                                                                  "jbyte_arraycopy");
+    StubRoutines::_arrayof_jbyte_disjoint_arraycopy = generate_disjoint_byte_copy(true, &entry,
+                                                                                  "arrayof_jbyte_disjoint_arraycopy");
+    StubRoutines::_arrayof_jbyte_arraycopy          = generate_conjoint_byte_copy(true, entry, NULL,
+                                                                                  "arrayof_jbyte_arraycopy");
+
+    //*** jshort
+    // Always need aligned and unaligned versions
+    StubRoutines::_jshort_disjoint_arraycopy         = generate_disjoint_short_copy(false, &entry,
+                                                                                    "jshort_disjoint_arraycopy");
+    StubRoutines::_jshort_arraycopy                  = generate_conjoint_short_copy(false, entry,
+                                                                                    &entry_jshort_arraycopy,
+                                                                                    "jshort_arraycopy");
+    StubRoutines::_arrayof_jshort_disjoint_arraycopy = generate_disjoint_short_copy(true, &entry,
+                                                                                    "arrayof_jshort_disjoint_arraycopy");
+    StubRoutines::_arrayof_jshort_arraycopy          = generate_conjoint_short_copy(true, entry, NULL,
+                                                                                    "arrayof_jshort_arraycopy");
+
+    //*** jint
+    // Aligned versions
+    StubRoutines::_arrayof_jint_disjoint_arraycopy = generate_disjoint_int_copy(true, &entry,
+                                                                                "arrayof_jint_disjoint_arraycopy");
+    StubRoutines::_arrayof_jint_arraycopy          = generate_conjoint_int_copy(true, entry, &entry_jint_arraycopy,
+                                                                                "arrayof_jint_arraycopy");
 #ifdef _LP64
-    // since sizeof(jint) < sizeof(HeapWord), there's a different flavor:
-    StubRoutines::_arrayof_jint_arraycopy     = generate_conjoint_int_copy(true, "arrayof_jint_arraycopy");
-  #else
-    StubRoutines::_arrayof_jint_arraycopy     = StubRoutines::_jint_arraycopy;
+    // In 64 bit we need both aligned and unaligned versions of jint arraycopy.
+    // entry_jint_arraycopy always points to the unaligned version (notice that we overwrite it).
+    StubRoutines::_jint_disjoint_arraycopy         = generate_disjoint_int_copy(false, &entry,
+                                                                                "jint_disjoint_arraycopy");
+    StubRoutines::_jint_arraycopy                  = generate_conjoint_int_copy(false, entry,
+                                                                                &entry_jint_arraycopy,
+                                                                                "jint_arraycopy");
+#else
+    // In 32 bit jints are always HeapWordSize aligned, so always use the aligned version
+    // (in fact in 32bit we always have a pre-loop part even in the aligned version,
+    //  because it uses 64-bit loads/stores, so the aligned flag is actually ignored).
+    StubRoutines::_jint_disjoint_arraycopy = StubRoutines::_arrayof_jint_disjoint_arraycopy;
+    StubRoutines::_jint_arraycopy          = StubRoutines::_arrayof_jint_arraycopy;
 #endif
-    StubRoutines::_arrayof_jlong_arraycopy    = StubRoutines::_jlong_arraycopy;
-    StubRoutines::_arrayof_oop_arraycopy      = StubRoutines::_oop_arraycopy;
-
-    StubRoutines::_checkcast_arraycopy = generate_checkcast_copy("checkcast_arraycopy");
-    StubRoutines::_unsafe_arraycopy    = generate_unsafe_copy("unsafe_arraycopy");
-    StubRoutines::_generic_arraycopy   = generate_generic_copy("generic_arraycopy");
+
+
+    //*** jlong
+    // It is always aligned
+    StubRoutines::_arrayof_jlong_disjoint_arraycopy = generate_disjoint_long_copy(true, &entry,
+                                                                                  "arrayof_jlong_disjoint_arraycopy");
+    StubRoutines::_arrayof_jlong_arraycopy          = generate_conjoint_long_copy(true, entry, &entry_jlong_arraycopy,
+                                                                                  "arrayof_jlong_arraycopy");
+    StubRoutines::_jlong_disjoint_arraycopy         = StubRoutines::_arrayof_jlong_disjoint_arraycopy;
+    StubRoutines::_jlong_arraycopy                  = StubRoutines::_arrayof_jlong_arraycopy;
+
+
+    //*** oops
+    // Aligned versions
+    StubRoutines::_arrayof_oop_disjoint_arraycopy        = generate_disjoint_oop_copy(true, &entry,
+                                                                                      "arrayof_oop_disjoint_arraycopy");
+    StubRoutines::_arrayof_oop_arraycopy                 = generate_conjoint_oop_copy(true, entry, &entry_oop_arraycopy,
+                                                                                      "arrayof_oop_arraycopy");
+    // Aligned versions without pre-barriers
+    StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit = generate_disjoint_oop_copy(true, &entry,
+                                                                                      "arrayof_oop_disjoint_arraycopy_uninit",
+                                                                                      /*dest_uninitialized*/true);
+    StubRoutines::_arrayof_oop_arraycopy_uninit          = generate_conjoint_oop_copy(true, entry, NULL,
+                                                                                      "arrayof_oop_arraycopy_uninit",
+                                                                                      /*dest_uninitialized*/true);
+#ifdef _LP64
+    if (UseCompressedOops) {
+      // With compressed oops we need unaligned versions, notice that we overwrite entry_oop_arraycopy.
+      StubRoutines::_oop_disjoint_arraycopy            = generate_disjoint_oop_copy(false, &entry,
+                                                                                    "oop_disjoint_arraycopy");
+      StubRoutines::_oop_arraycopy                     = generate_conjoint_oop_copy(false, entry, &entry_oop_arraycopy,
+                                                                                    "oop_arraycopy");
+      // Unaligned versions without pre-barriers
+      StubRoutines::_oop_disjoint_arraycopy_uninit     = generate_disjoint_oop_copy(false, &entry,
+                                                                                    "oop_disjoint_arraycopy_uninit",
+                                                                                    /*dest_uninitialized*/true);
+      StubRoutines::_oop_arraycopy_uninit              = generate_conjoint_oop_copy(false, entry, NULL,
+                                                                                    "oop_arraycopy_uninit",
+                                                                                    /*dest_uninitialized*/true);
+    } else
+#endif
+    {
+      // oop arraycopy is always aligned on 32bit and 64bit without compressed oops
+      StubRoutines::_oop_disjoint_arraycopy            = StubRoutines::_arrayof_oop_disjoint_arraycopy;
+      StubRoutines::_oop_arraycopy                     = StubRoutines::_arrayof_oop_arraycopy;
+      StubRoutines::_oop_disjoint_arraycopy_uninit     = StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit;
+      StubRoutines::_oop_arraycopy_uninit              = StubRoutines::_arrayof_oop_arraycopy_uninit;
+    }
+
+    StubRoutines::_checkcast_arraycopy        = generate_checkcast_copy("checkcast_arraycopy", &entry_checkcast_arraycopy);
+    StubRoutines::_checkcast_arraycopy_uninit = generate_checkcast_copy("checkcast_arraycopy_uninit", NULL,
+                                                                        /*dest_uninitialized*/true);
+
+    StubRoutines::_unsafe_arraycopy    = generate_unsafe_copy("unsafe_arraycopy",
+                                                              entry_jbyte_arraycopy,
+                                                              entry_jshort_arraycopy,
+                                                              entry_jint_arraycopy,
+                                                              entry_jlong_arraycopy);
+    StubRoutines::_generic_arraycopy   = generate_generic_copy("generic_arraycopy",
+                                                               entry_jbyte_arraycopy,
+                                                               entry_jshort_arraycopy,
+                                                               entry_jint_arraycopy,
+                                                               entry_oop_arraycopy,
+                                                               entry_jlong_arraycopy,
+                                                               entry_checkcast_arraycopy);
 
     StubRoutines::_jbyte_fill = generate_fill(T_BYTE, false, "jbyte_fill");
     StubRoutines::_jshort_fill = generate_fill(T_SHORT, false, "jshort_fill");
@@ -3224,21 +3326,6 @@
 
 }; // end class declaration
 
-
-address StubGenerator::disjoint_byte_copy_entry  = NULL;
-address StubGenerator::disjoint_short_copy_entry = NULL;
-address StubGenerator::disjoint_int_copy_entry   = NULL;
-address StubGenerator::disjoint_long_copy_entry  = NULL;
-address StubGenerator::disjoint_oop_copy_entry   = NULL;
-
-address StubGenerator::byte_copy_entry  = NULL;
-address StubGenerator::short_copy_entry = NULL;
-address StubGenerator::int_copy_entry   = NULL;
-address StubGenerator::long_copy_entry  = NULL;
-address StubGenerator::oop_copy_entry   = NULL;
-
-address StubGenerator::checkcast_copy_entry = NULL;
-
 void StubGenerator_generate(CodeBuffer* code, bool all) {
   StubGenerator g(code, all);
 }
--- a/src/cpu/sparc/vm/templateTable_sparc.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/cpu/sparc/vm/templateTable_sparc.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -3303,7 +3303,7 @@
   __ sll(Rret, LogBytesPerWord, Rret);
   __ ld_ptr(Rtemp, Rret, Rret);  // get return address
 
-  __ load_heap_oop(G5_callsite, __ delayed_value(java_dyn_CallSite::target_offset_in_bytes, Rscratch), G3_method_handle);
+  __ load_heap_oop(G5_callsite, __ delayed_value(java_lang_invoke_CallSite::target_offset_in_bytes, Rscratch), G3_method_handle);
   __ null_check(G3_method_handle);
 
   // Adjust Rret first so Llast_SP can be same as Rret
--- a/src/cpu/x86/vm/assembler_x86.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/cpu/x86/vm/assembler_x86.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -1601,6 +1601,17 @@
   emit_byte(0xC0 | encode);
 }
 
+void Assembler::movdl(XMMRegister dst, Address src) {
+  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
+  InstructionMark im(this);
+  emit_byte(0x66);
+  prefix(src, dst);
+  emit_byte(0x0F);
+  emit_byte(0x6E);
+  emit_operand(dst, src);
+}
+
+
 void Assembler::movdqa(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   InstructionMark im(this);
@@ -2412,7 +2423,10 @@
 }
 
 void Assembler::psrlq(XMMRegister dst, int shift) {
-  // HMM Table D-1 says sse2 or mmx
+  // Shift 64 bit value logically right by specified number of bits.
+  // HMM Table D-1 says sse2 or mmx.
+  // Do not confuse it with psrldq SSE2 instruction which
+  // shifts 128 bit value in xmm register by number of bytes.
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
 
   int encode = prefixq_and_encode(xmm2->encoding(), dst->encoding());
@@ -2423,6 +2437,18 @@
   emit_byte(shift);
 }
 
+void Assembler::psrldq(XMMRegister dst, int shift) {
+  // Shift 128 bit value in xmm register by number of bytes.
+  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
+
+  int encode = prefixq_and_encode(xmm3->encoding(), dst->encoding());
+  emit_byte(0x66);
+  emit_byte(0x0F);
+  emit_byte(0x73);
+  emit_byte(0xC0 | encode);
+  emit_byte(shift);
+}
+
 void Assembler::ptest(XMMRegister dst, Address src) {
   assert(VM_Version::supports_sse4_1(), "");
 
@@ -7805,7 +7831,7 @@
 void MacroAssembler::check_method_handle_type(Register mtype_reg, Register mh_reg,
                                               Register temp_reg,
                                               Label& wrong_method_type) {
-  Address type_addr(mh_reg, delayed_value(java_dyn_MethodHandle::type_offset_in_bytes, temp_reg));
+  Address type_addr(mh_reg, delayed_value(java_lang_invoke_MethodHandle::type_offset_in_bytes, temp_reg));
   // compare method type against that of the receiver
   if (UseCompressedOops) {
     load_heap_oop(temp_reg, type_addr);
@@ -7825,14 +7851,14 @@
                                                 Register temp_reg) {
   assert_different_registers(vmslots_reg, mh_reg, temp_reg);
   // load mh.type.form.vmslots
-  if (java_dyn_MethodHandle::vmslots_offset_in_bytes() != 0) {
+  if (java_lang_invoke_MethodHandle::vmslots_offset_in_bytes() != 0) {
     // hoist vmslots into every mh to avoid dependent load chain
-    movl(vmslots_reg, Address(mh_reg, delayed_value(java_dyn_MethodHandle::vmslots_offset_in_bytes, temp_reg)));
+    movl(vmslots_reg, Address(mh_reg, delayed_value(java_lang_invoke_MethodHandle::vmslots_offset_in_bytes, temp_reg)));
   } else {
     Register temp2_reg = vmslots_reg;
-    load_heap_oop(temp2_reg, Address(mh_reg,    delayed_value(java_dyn_MethodHandle::type_offset_in_bytes, temp_reg)));
-    load_heap_oop(temp2_reg, Address(temp2_reg, delayed_value(java_dyn_MethodType::form_offset_in_bytes, temp_reg)));
-    movl(vmslots_reg, Address(temp2_reg, delayed_value(java_dyn_MethodTypeForm::vmslots_offset_in_bytes, temp_reg)));
+    load_heap_oop(temp2_reg, Address(mh_reg,    delayed_value(java_lang_invoke_MethodHandle::type_offset_in_bytes, temp_reg)));
+    load_heap_oop(temp2_reg, Address(temp2_reg, delayed_value(java_lang_invoke_MethodType::form_offset_in_bytes, temp_reg)));
+    movl(vmslots_reg, Address(temp2_reg, delayed_value(java_lang_invoke_MethodTypeForm::vmslots_offset_in_bytes, temp_reg)));
   }
 }
 
@@ -7847,7 +7873,7 @@
 
   // pick out the interpreted side of the handler
   // NOTE: vmentry is not an oop!
-  movptr(temp_reg, Address(mh_reg, delayed_value(java_dyn_MethodHandle::vmentry_offset_in_bytes, temp_reg)));
+  movptr(temp_reg, Address(mh_reg, delayed_value(java_lang_invoke_MethodHandle::vmentry_offset_in_bytes, temp_reg)));
 
   // off we go...
   jmp(Address(temp_reg, MethodHandleEntry::from_interpreted_entry_offset_in_bytes()));
@@ -8567,101 +8593,418 @@
 }
 #endif // _LP64
 
-// IndexOf substring.
-void MacroAssembler::string_indexof(Register str1, Register str2,
-                                    Register cnt1, Register cnt2, Register result,
-                                    XMMRegister vec, Register tmp) {
+// IndexOf for constant substrings with size >= 8 chars
+// which don't need to be loaded through stack.
+void MacroAssembler::string_indexofC8(Register str1, Register str2,
+                                      Register cnt1, Register cnt2,
+                                      int int_cnt2,  Register result,
+                                      XMMRegister vec, Register tmp) {
   assert(UseSSE42Intrinsics, "SSE4.2 is required");
 
-  Label RELOAD_SUBSTR, PREP_FOR_SCAN, SCAN_TO_SUBSTR,
-        SCAN_SUBSTR, RET_NOT_FOUND, CLEANUP;
-
-  push(str1); // string addr
-  push(str2); // substr addr
-  push(cnt2); // substr count
-  jmpb(PREP_FOR_SCAN);
-
-  // Substr count saved at sp
-  // Substr saved at sp+1*wordSize
-  // String saved at sp+2*wordSize
-
-  // Reload substr for rescan
-  bind(RELOAD_SUBSTR);
-  movl(cnt2, Address(rsp, 0));
-  movptr(str2, Address(rsp, wordSize));
-  // We came here after the beginninig of the substring was
-  // matched but the rest of it was not so we need to search
-  // again. Start from the next element after the previous match.
-  subptr(str1, result); // Restore counter
-  shrl(str1, 1);
-  addl(cnt1, str1);
-  decrementl(cnt1);
-  lea(str1, Address(result, 2)); // Reload string
-
-  // Load substr
-  bind(PREP_FOR_SCAN);
-  movdqu(vec, Address(str2, 0));
-  addl(cnt1, 8);  // prime the loop
-  subptr(str1, 16);
-
-  // Scan string for substr in 16-byte vectors
-  bind(SCAN_TO_SUBSTR);
-  subl(cnt1, 8);
-  addptr(str1, 16);
-
-  // pcmpestri
+  // This method uses pcmpestri inxtruction with bound registers
   //   inputs:
   //     xmm - substring
   //     rax - substring length (elements count)
-  //     mem - scaned string
+  //     mem - scanned string
   //     rdx - string length (elements count)
   //     0xd - mode: 1100 (substring search) + 01 (unsigned shorts)
   //   outputs:
   //     rcx - matched index in string
   assert(cnt1 == rdx && cnt2 == rax && tmp == rcx, "pcmpestri");
 
-  pcmpestri(vec, Address(str1, 0), 0x0d);
-  jcc(Assembler::above, SCAN_TO_SUBSTR);      // CF == 0 && ZF == 0
-  jccb(Assembler::aboveEqual, RET_NOT_FOUND); // CF == 0
-
-  // Fallthrough: found a potential substr
+  Label RELOAD_SUBSTR, SCAN_TO_SUBSTR, SCAN_SUBSTR,
+        RET_FOUND, RET_NOT_FOUND, EXIT, FOUND_SUBSTR,
+        MATCH_SUBSTR_HEAD, RELOAD_STR, FOUND_CANDIDATE;
+
+  // Note, inline_string_indexOf() generates checks:
+  // if (substr.count > string.count) return -1;
+  // if (substr.count == 0) return 0;
+  assert(int_cnt2 >= 8, "this code isused only for cnt2 >= 8 chars");
+
+  // Load substring.
+  movdqu(vec, Address(str2, 0));
+  movl(cnt2, int_cnt2);
+  movptr(result, str1); // string addr
+
+  if (int_cnt2 > 8) {
+    jmpb(SCAN_TO_SUBSTR);
+
+    // Reload substr for rescan, this code
+    // is executed only for large substrings (> 8 chars)
+    bind(RELOAD_SUBSTR);
+    movdqu(vec, Address(str2, 0));
+    negptr(cnt2); // Jumped here with negative cnt2, convert to positive
+
+    bind(RELOAD_STR);
+    // We came here after the beginning of the substring was
+    // matched but the rest of it was not so we need to search
+    // again. Start from the next element after the previous match.
+
+    // cnt2 is number of substring reminding elements and
+    // cnt1 is number of string reminding elements when cmp failed.
+    // Restored cnt1 = cnt1 - cnt2 + int_cnt2
+    subl(cnt1, cnt2);
+    addl(cnt1, int_cnt2);
+    movl(cnt2, int_cnt2); // Now restore cnt2
+
+    decrementl(cnt1);     // Shift to next element
+    cmpl(cnt1, cnt2);
+    jccb(Assembler::negative, RET_NOT_FOUND);  // Left less then substring
+
+    addptr(result, 2);
+
+  } // (int_cnt2 > 8)
+
+  // Scan string for start of substr in 16-byte vectors
+  bind(SCAN_TO_SUBSTR);
+  pcmpestri(vec, Address(result, 0), 0x0d);
+  jccb(Assembler::below, FOUND_CANDIDATE);   // CF == 1
+  subl(cnt1, 8);
+  jccb(Assembler::lessEqual, RET_NOT_FOUND); // Scanned full string
+  cmpl(cnt1, cnt2);
+  jccb(Assembler::negative, RET_NOT_FOUND);  // Left less then substring
+  addptr(result, 16);
+  jmpb(SCAN_TO_SUBSTR);
+
+  // Found a potential substr
+  bind(FOUND_CANDIDATE);
+  // Matched whole vector if first element matched (tmp(rcx) == 0).
+  if (int_cnt2 == 8) {
+    jccb(Assembler::overflow, RET_FOUND);    // OF == 1
+  } else { // int_cnt2 > 8
+    jccb(Assembler::overflow, FOUND_SUBSTR);
+  }
+  // After pcmpestri tmp(rcx) contains matched element index
+  // Compute start addr of substr
+  lea(result, Address(result, tmp, Address::times_2));
 
   // Make sure string is still long enough
   subl(cnt1, tmp);
   cmpl(cnt1, cnt2);
-  jccb(Assembler::negative, RET_NOT_FOUND);
-  // Compute start addr of substr
-  lea(str1, Address(str1, tmp, Address::times_2));
-  movptr(result, str1); // save
-
-  // Compare potential substr
-  addl(cnt1, 8);     // prime the loop
-  addl(cnt2, 8);
-  subptr(str1, 16);
-  subptr(str2, 16);
-
-  // Scan 16-byte vectors of string and substr
-  bind(SCAN_SUBSTR);
-  subl(cnt1, 8);
-  subl(cnt2, 8);
-  addptr(str1, 16);
-  addptr(str2, 16);
-  movdqu(vec, Address(str2, 0));
-  pcmpestri(vec, Address(str1, 0), 0x0d);
-  jcc(Assembler::noOverflow, RELOAD_SUBSTR); // OF == 0
-  jcc(Assembler::positive, SCAN_SUBSTR);     // SF == 0
-
-  // Compute substr offset
-  subptr(result, Address(rsp, 2*wordSize));
-  shrl(result, 1); // index
-  jmpb(CLEANUP);
+  if (int_cnt2 == 8) {
+    jccb(Assembler::greaterEqual, SCAN_TO_SUBSTR);
+  } else { // int_cnt2 > 8
+    jccb(Assembler::greaterEqual, MATCH_SUBSTR_HEAD);
+  }
+  // Left less then substring.
 
   bind(RET_NOT_FOUND);
   movl(result, -1);
+  jmpb(EXIT);
+
+  if (int_cnt2 > 8) {
+    // This code is optimized for the case when whole substring
+    // is matched if its head is matched.
+    bind(MATCH_SUBSTR_HEAD);
+    pcmpestri(vec, Address(result, 0), 0x0d);
+    // Reload only string if does not match
+    jccb(Assembler::noOverflow, RELOAD_STR); // OF == 0
+
+    Label CONT_SCAN_SUBSTR;
+    // Compare the rest of substring (> 8 chars).
+    bind(FOUND_SUBSTR);
+    // First 8 chars are already matched.
+    negptr(cnt2);
+    addptr(cnt2, 8);
+
+    bind(SCAN_SUBSTR);
+    subl(cnt1, 8);
+    cmpl(cnt2, -8); // Do not read beyond substring
+    jccb(Assembler::lessEqual, CONT_SCAN_SUBSTR);
+    // Back-up strings to avoid reading beyond substring:
+    // cnt1 = cnt1 - cnt2 + 8
+    addl(cnt1, cnt2); // cnt2 is negative
+    addl(cnt1, 8);
+    movl(cnt2, 8); negptr(cnt2);
+    bind(CONT_SCAN_SUBSTR);
+    if (int_cnt2 < (int)G) {
+      movdqu(vec, Address(str2, cnt2, Address::times_2, int_cnt2*2));
+      pcmpestri(vec, Address(result, cnt2, Address::times_2, int_cnt2*2), 0x0d);
+    } else {
+      // calculate index in register to avoid integer overflow (int_cnt2*2)
+      movl(tmp, int_cnt2);
+      addptr(tmp, cnt2);
+      movdqu(vec, Address(str2, tmp, Address::times_2, 0));
+      pcmpestri(vec, Address(result, tmp, Address::times_2, 0), 0x0d);
+    }
+    // Need to reload strings pointers if not matched whole vector
+    jccb(Assembler::noOverflow, RELOAD_SUBSTR); // OF == 0
+    addptr(cnt2, 8);
+    jccb(Assembler::negative, SCAN_SUBSTR);
+    // Fall through if found full substring
+
+  } // (int_cnt2 > 8)
+
+  bind(RET_FOUND);
+  // Found result if we matched full small substring.
+  // Compute substr offset
+  subptr(result, str1);
+  shrl(result, 1); // index
+  bind(EXIT);
+
+} // string_indexofC8
+
+// Small strings are loaded through stack if they cross page boundary.
+void MacroAssembler::string_indexof(Register str1, Register str2,
+                                    Register cnt1, Register cnt2,
+                                    int int_cnt2,  Register result,
+                                    XMMRegister vec, Register tmp) {
+  assert(UseSSE42Intrinsics, "SSE4.2 is required");
+  //
+  // int_cnt2 is length of small (< 8 chars) constant substring
+  // or (-1) for non constant substring in which case its length
+  // is in cnt2 register.
+  //
+  // Note, inline_string_indexOf() generates checks:
+  // if (substr.count > string.count) return -1;
+  // if (substr.count == 0) return 0;
+  //
+  assert(int_cnt2 == -1 || (0 < int_cnt2 && int_cnt2 < 8), "should be != 0");
+
+  // This method uses pcmpestri inxtruction with bound registers
+  //   inputs:
+  //     xmm - substring
+  //     rax - substring length (elements count)
+  //     mem - scanned string
+  //     rdx - string length (elements count)
+  //     0xd - mode: 1100 (substring search) + 01 (unsigned shorts)
+  //   outputs:
+  //     rcx - matched index in string
+  assert(cnt1 == rdx && cnt2 == rax && tmp == rcx, "pcmpestri");
+
+  Label RELOAD_SUBSTR, SCAN_TO_SUBSTR, SCAN_SUBSTR, ADJUST_STR,
+        RET_FOUND, RET_NOT_FOUND, CLEANUP, FOUND_SUBSTR,
+        FOUND_CANDIDATE;
+
+  { //========================================================
+    // We don't know where these strings are located
+    // and we can't read beyond them. Load them through stack.
+    Label BIG_STRINGS, CHECK_STR, COPY_SUBSTR, COPY_STR;
+
+    movptr(tmp, rsp); // save old SP
+
+    if (int_cnt2 > 0) {     // small (< 8 chars) constant substring
+      if (int_cnt2 == 1) {  // One char
+        load_unsigned_short(result, Address(str2, 0));
+        movdl(vec, result); // move 32 bits
+      } else if (int_cnt2 == 2) { // Two chars
+        movdl(vec, Address(str2, 0)); // move 32 bits
+      } else if (int_cnt2 == 4) { // Four chars
+        movq(vec, Address(str2, 0));  // move 64 bits
+      } else { // cnt2 = { 3, 5, 6, 7 }
+        // Array header size is 12 bytes in 32-bit VM
+        // + 6 bytes for 3 chars == 18 bytes,
+        // enough space to load vec and shift.
+        assert(HeapWordSize*typeArrayKlass::header_size() >= 12,"sanity");
+        movdqu(vec, Address(str2, (int_cnt2*2)-16));
+        psrldq(vec, 16-(int_cnt2*2));
+      }
+    } else { // not constant substring
+      cmpl(cnt2, 8);
+      jccb(Assembler::aboveEqual, BIG_STRINGS); // Both strings are big enough
+
+      // We can read beyond string if srt+16 does not cross page boundary
+      // since heaps are aligned and mapped by pages.
+      assert(os::vm_page_size() < (int)G, "default page should be small");
+      movl(result, str2); // We need only low 32 bits
+      andl(result, (os::vm_page_size()-1));
+      cmpl(result, (os::vm_page_size()-16));
+      jccb(Assembler::belowEqual, CHECK_STR);
+
+      // Move small strings to stack to allow load 16 bytes into vec.
+      subptr(rsp, 16);
+      int stk_offset = wordSize-2;
+      push(cnt2);
+
+      bind(COPY_SUBSTR);
+      load_unsigned_short(result, Address(str2, cnt2, Address::times_2, -2));
+      movw(Address(rsp, cnt2, Address::times_2, stk_offset), result);
+      decrement(cnt2);
+      jccb(Assembler::notZero, COPY_SUBSTR);
+
+      pop(cnt2);
+      movptr(str2, rsp);  // New substring address
+    } // non constant
+
+    bind(CHECK_STR);
+    cmpl(cnt1, 8);
+    jccb(Assembler::aboveEqual, BIG_STRINGS);
+
+    // Check cross page boundary.
+    movl(result, str1); // We need only low 32 bits
+    andl(result, (os::vm_page_size()-1));
+    cmpl(result, (os::vm_page_size()-16));
+    jccb(Assembler::belowEqual, BIG_STRINGS);
+
+    subptr(rsp, 16);
+    int stk_offset = -2;
+    if (int_cnt2 < 0) { // not constant
+      push(cnt2);
+      stk_offset += wordSize;
+    }
+    movl(cnt2, cnt1);
+
+    bind(COPY_STR);
+    load_unsigned_short(result, Address(str1, cnt2, Address::times_2, -2));
+    movw(Address(rsp, cnt2, Address::times_2, stk_offset), result);
+    decrement(cnt2);
+    jccb(Assembler::notZero, COPY_STR);
+
+    if (int_cnt2 < 0) { // not constant
+      pop(cnt2);
+    }
+    movptr(str1, rsp);  // New string address
+
+    bind(BIG_STRINGS);
+    // Load substring.
+    if (int_cnt2 < 0) { // -1
+      movdqu(vec, Address(str2, 0));
+      push(cnt2);       // substr count
+      push(str2);       // substr addr
+      push(str1);       // string addr
+    } else {
+      // Small (< 8 chars) constant substrings are loaded already.
+      movl(cnt2, int_cnt2);
+    }
+    push(tmp);  // original SP
+
+  } // Finished loading
+
+  //========================================================
+  // Start search
+  //
+
+  movptr(result, str1); // string addr
+
+  if (int_cnt2  < 0) {  // Only for non constant substring
+    jmpb(SCAN_TO_SUBSTR);
+
+    // SP saved at sp+0
+    // String saved at sp+1*wordSize
+    // Substr saved at sp+2*wordSize
+    // Substr count saved at sp+3*wordSize
+
+    // Reload substr for rescan, this code
+    // is executed only for large substrings (> 8 chars)
+    bind(RELOAD_SUBSTR);
+    movptr(str2, Address(rsp, 2*wordSize));
+    movl(cnt2, Address(rsp, 3*wordSize));
+    movdqu(vec, Address(str2, 0));
+    // We came here after the beginning of the substring was
+    // matched but the rest of it was not so we need to search
+    // again. Start from the next element after the previous match.
+    subptr(str1, result); // Restore counter
+    shrl(str1, 1);
+    addl(cnt1, str1);
+    decrementl(cnt1);   // Shift to next element
+    cmpl(cnt1, cnt2);
+    jccb(Assembler::negative, RET_NOT_FOUND);  // Left less then substring
+
+    addptr(result, 2);
+  } // non constant
+
+  // Scan string for start of substr in 16-byte vectors
+  bind(SCAN_TO_SUBSTR);
+  assert(cnt1 == rdx && cnt2 == rax && tmp == rcx, "pcmpestri");
+  pcmpestri(vec, Address(result, 0), 0x0d);
+  jccb(Assembler::below, FOUND_CANDIDATE);   // CF == 1
+  subl(cnt1, 8);
+  jccb(Assembler::lessEqual, RET_NOT_FOUND); // Scanned full string
+  cmpl(cnt1, cnt2);
+  jccb(Assembler::negative, RET_NOT_FOUND);  // Left less then substring
+  addptr(result, 16);
+
+  bind(ADJUST_STR);
+  cmpl(cnt1, 8); // Do not read beyond string
+  jccb(Assembler::greaterEqual, SCAN_TO_SUBSTR);
+  // Back-up string to avoid reading beyond string.
+  lea(result, Address(result, cnt1, Address::times_2, -16));
+  movl(cnt1, 8);
+  jmpb(SCAN_TO_SUBSTR);
+
+  // Found a potential substr
+  bind(FOUND_CANDIDATE);
+  // After pcmpestri tmp(rcx) contains matched element index
+
+  // Make sure string is still long enough
+  subl(cnt1, tmp);
+  cmpl(cnt1, cnt2);
+  jccb(Assembler::greaterEqual, FOUND_SUBSTR);
+  // Left less then substring.
+
+  bind(RET_NOT_FOUND);
+  movl(result, -1);
+  jmpb(CLEANUP);
+
+  bind(FOUND_SUBSTR);
+  // Compute start addr of substr
+  lea(result, Address(result, tmp, Address::times_2));
+
+  if (int_cnt2 > 0) { // Constant substring
+    // Repeat search for small substring (< 8 chars)
+    // from new point without reloading substring.
+    // Have to check that we don't read beyond string.
+    cmpl(tmp, 8-int_cnt2);
+    jccb(Assembler::greater, ADJUST_STR);
+    // Fall through if matched whole substring.
+  } else { // non constant
+    assert(int_cnt2 == -1, "should be != 0");
+
+    addl(tmp, cnt2);
+    // Found result if we matched whole substring.
+    cmpl(tmp, 8);
+    jccb(Assembler::lessEqual, RET_FOUND);
+
+    // Repeat search for small substring (<= 8 chars)
+    // from new point 'str1' without reloading substring.
+    cmpl(cnt2, 8);
+    // Have to check that we don't read beyond string.
+    jccb(Assembler::lessEqual, ADJUST_STR);
+
+    Label CHECK_NEXT, CONT_SCAN_SUBSTR, RET_FOUND_LONG;
+    // Compare the rest of substring (> 8 chars).
+    movptr(str1, result);
+
+    cmpl(tmp, cnt2);
+    // First 8 chars are already matched.
+    jccb(Assembler::equal, CHECK_NEXT);
+
+    bind(SCAN_SUBSTR);
+    pcmpestri(vec, Address(str1, 0), 0x0d);
+    // Need to reload strings pointers if not matched whole vector
+    jcc(Assembler::noOverflow, RELOAD_SUBSTR); // OF == 0
+
+    bind(CHECK_NEXT);
+    subl(cnt2, 8);
+    jccb(Assembler::lessEqual, RET_FOUND_LONG); // Found full substring
+    addptr(str1, 16);
+    addptr(str2, 16);
+    subl(cnt1, 8);
+    cmpl(cnt2, 8); // Do not read beyond substring
+    jccb(Assembler::greaterEqual, CONT_SCAN_SUBSTR);
+    // Back-up strings to avoid reading beyond substring.
+    lea(str2, Address(str2, cnt2, Address::times_2, -16));
+    lea(str1, Address(str1, cnt2, Address::times_2, -16));
+    subl(cnt1, cnt2);
+    movl(cnt2, 8);
+    addl(cnt1, 8);
+    bind(CONT_SCAN_SUBSTR);
+    movdqu(vec, Address(str2, 0));
+    jmpb(SCAN_SUBSTR);
+
+    bind(RET_FOUND_LONG);
+    movptr(str1, Address(rsp, wordSize));
+  } // non constant
+
+  bind(RET_FOUND);
+  // Compute substr offset
+  subptr(result, str1);
+  shrl(result, 1); // index
 
   bind(CLEANUP);
-  addptr(rsp, 3*wordSize);
-}
+  pop(rsp); // restore SP
+
+} // string_indexof
 
 // Compare strings.
 void MacroAssembler::string_compare(Register str1, Register str2,
--- a/src/cpu/x86/vm/assembler_x86.hpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/cpu/x86/vm/assembler_x86.hpp	Mon Apr 04 19:23:29 2011 -0700
@@ -1121,6 +1121,7 @@
 
   void movdl(XMMRegister dst, Register src);
   void movdl(Register dst, XMMRegister src);
+  void movdl(XMMRegister dst, Address src);
 
   // Move Double Quadword
   void movdq(XMMRegister dst, Register src);
@@ -1288,9 +1289,12 @@
   void pshuflw(XMMRegister dst, XMMRegister src, int mode);
   void pshuflw(XMMRegister dst, Address src,     int mode);
 
-  // Shift Right Logical Quadword Immediate
+  // Shift Right by bits Logical Quadword Immediate
   void psrlq(XMMRegister dst, int shift);
 
+  // Shift Right by bytes Logical DoubleQuadword Immediate
+  void psrldq(XMMRegister dst, int shift);
+
   // Logical Compare Double Quadword
   void ptest(XMMRegister dst, XMMRegister src);
   void ptest(XMMRegister dst, Address src);
@@ -2290,10 +2294,22 @@
   void movl2ptr(Register dst, Register src) { LP64_ONLY(movslq(dst, src)) NOT_LP64(if (dst != src) movl(dst, src)); }
 
   // IndexOf strings.
+  // Small strings are loaded through stack if they cross page boundary.
   void string_indexof(Register str1, Register str2,
-                      Register cnt1, Register cnt2, Register result,
+                      Register cnt1, Register cnt2,
+                      int int_cnt2,  Register result,
                       XMMRegister vec, Register tmp);
 
+  // IndexOf for constant substrings with size >= 8 elements
+  // which don't need to be loaded through stack.
+  void string_indexofC8(Register str1, Register str2,
+                      Register cnt1, Register cnt2,
+                      int int_cnt2,  Register result,
+                      XMMRegister vec, Register tmp);
+
+    // Smallest code: we don't need to load through stack,
+    // check string tail.
+
   // Compare strings.
   void string_compare(Register str1, Register str2,
                       Register cnt1, Register cnt2, Register result,
--- a/src/cpu/x86/vm/c1_CodeStubs_x86.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/cpu/x86/vm/c1_CodeStubs_x86.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -313,10 +313,13 @@
     }
     assert(_obj != noreg, "must be a valid register");
     Register tmp = rax;
-    if (_obj == tmp) tmp = rbx;
+    Register tmp2 = rbx;
     __ push(tmp);
+    __ push(tmp2);
+    __ load_heap_oop(tmp2, Address(_obj, java_lang_Class::klass_offset_in_bytes()));
     __ get_thread(tmp);
-    __ cmpptr(tmp, Address(_obj, instanceKlass::init_thread_offset_in_bytes() + sizeof(klassOopDesc)));
+    __ cmpptr(tmp, Address(tmp2, instanceKlass::init_thread_offset_in_bytes() + sizeof(klassOopDesc)));
+    __ pop(tmp2);
     __ pop(tmp);
     __ jcc(Assembler::notEqual, call_patch);
 
--- a/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -456,10 +456,8 @@
   __ verify_not_null_oop(rax);
 
   // search an exception handler (rax: exception oop, rdx: throwing pc)
-  __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::handle_exception_nofpu_id)));
-
-  __ stop("should not reach here");
-
+  __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::handle_exception_from_callee_id)));
+  __ should_not_reach_here();
   assert(code_offset() - offset <= exception_handler_size, "overflow");
   __ end_a_stub();
 
--- a/src/cpu/x86/vm/c1_Runtime1_x86.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/cpu/x86/vm/c1_Runtime1_x86.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -248,11 +248,14 @@
 #ifdef _LP64
   align_dummy_0, align_dummy_1,
 #endif // _LP64
-  dummy1, SLOT2(dummy1H)                                                                    // 0, 4
-  dummy2, SLOT2(dummy2H)                                                                    // 8, 12
-  // Two temps to be used as needed by users of save/restore callee registers
-  temp_2_off, SLOT2(temp_2H_off)                                                            // 16, 20
-  temp_1_off, SLOT2(temp_1H_off)                                                            // 24, 28
+#ifdef _WIN64
+  // Windows always allocates space for it's argument registers (see
+  // frame::arg_reg_save_area_bytes).
+  arg_reg_save_1, arg_reg_save_1H,                                                          // 0, 4
+  arg_reg_save_2, arg_reg_save_2H,                                                          // 8, 12
+  arg_reg_save_3, arg_reg_save_3H,                                                          // 16, 20
+  arg_reg_save_4, arg_reg_save_4H,                                                          // 24, 28
+#endif // _WIN64
   xmm_regs_as_doubles_off,                                                                  // 32
   float_regs_as_doubles_off = xmm_regs_as_doubles_off + xmm_regs_as_doubles_size_in_slots,  // 160
   fpu_state_off = float_regs_as_doubles_off + float_regs_as_doubles_size_in_slots,          // 224
@@ -282,24 +285,7 @@
   rax_off, SLOT2(raxH_off)                                                                  // 480, 484
   saved_rbp_off, SLOT2(saved_rbpH_off)                                                      // 488, 492
   return_off, SLOT2(returnH_off)                                                            // 496, 500
-  reg_save_frame_size,  // As noted: neglects any parameters to runtime                     // 504
-
-#ifdef _WIN64
-  c_rarg0_off = rcx_off,
-#else
-  c_rarg0_off = rdi_off,
-#endif // WIN64
-
-  // equates
-
-  // illegal instruction handler
-  continue_dest_off = temp_1_off,
-
-  // deoptimization equates
-  fp0_off = float_regs_as_doubles_off, // slot for java float/double return value
-  xmm0_off = xmm_regs_as_doubles_off,  // slot for java float/double return value
-  deopt_type = temp_2_off,             // slot for type of deopt in progress
-  ret_type = temp_1_off                // slot for return type
+  reg_save_frame_size   // As noted: neglects any parameters to runtime                     // 504
 };
 
 
@@ -405,11 +391,6 @@
                                    bool save_fpu_registers = true) {
   __ block_comment("save_live_registers");
 
-  // 64bit passes the args in regs to the c++ runtime
-  int frame_size_in_slots = reg_save_frame_size NOT_LP64(+ num_rt_args); // args + thread
-  // frame_size = round_to(frame_size, 4);
-  sasm->set_frame_size(frame_size_in_slots / VMRegImpl::slots_per_word );
-
   __ pusha();         // integer registers
 
   // assert(float_regs_as_doubles_off % 2 == 0, "misaligned offset");
@@ -642,19 +623,58 @@
 }
 
 
-void Runtime1::generate_handle_exception(StubAssembler *sasm, OopMapSet* oop_maps, OopMap* oop_map, bool save_fpu_registers) {
+OopMapSet* Runtime1::generate_handle_exception(StubID id, StubAssembler *sasm) {
+  __ block_comment("generate_handle_exception");
+
   // incoming parameters
   const Register exception_oop = rax;
-  const Register exception_pc = rdx;
+  const Register exception_pc  = rdx;
   // other registers used in this stub
-  const Register real_return_addr = rbx;
   const Register thread = NOT_LP64(rdi) LP64_ONLY(r15_thread);
 
-  __ block_comment("generate_handle_exception");
+  // Save registers, if required.
+  OopMapSet* oop_maps = new OopMapSet();
+  OopMap* oop_map = NULL;
+  switch (id) {
+  case forward_exception_id:
+    // We're handling an exception in the context of a compiled frame.
+    // The registers have been saved in the standard places.  Perform
+    // an exception lookup in the caller and dispatch to the handler
+    // if found.  Otherwise unwind and dispatch to the callers
+    // exception handler.
+    oop_map = generate_oop_map(sasm, 1 /*thread*/);
+
+    // load and clear pending exception oop into RAX
+    __ movptr(exception_oop, Address(thread, Thread::pending_exception_offset()));
+    __ movptr(Address(thread, Thread::pending_exception_offset()), NULL_WORD);
+
+    // load issuing PC (the return address for this stub) into rdx
+    __ movptr(exception_pc, Address(rbp, 1*BytesPerWord));
+
+    // make sure that the vm_results are cleared (may be unnecessary)
+    __ movptr(Address(thread, JavaThread::vm_result_offset()),   NULL_WORD);
+    __ movptr(Address(thread, JavaThread::vm_result_2_offset()), NULL_WORD);
+    break;
+  case handle_exception_nofpu_id:
+  case handle_exception_id:
+    // At this point all registers MAY be live.
+    oop_map = save_live_registers(sasm, 1 /*thread*/, id == handle_exception_nofpu_id);
+    break;
+  case handle_exception_from_callee_id: {
+    // At this point all registers except exception oop (RAX) and
+    // exception pc (RDX) are dead.
+    const int frame_size = 2 /*BP, return address*/ NOT_LP64(+ 1 /*thread*/) WIN64_ONLY(+ frame::arg_reg_save_area_bytes / BytesPerWord);
+    oop_map = new OopMap(frame_size * VMRegImpl::slots_per_word, 0);
+    sasm->set_frame_size(frame_size);
+    WIN64_ONLY(__ subq(rsp, frame::arg_reg_save_area_bytes));
+    break;
+  }
+  default:  ShouldNotReachHere();
+  }
 
 #ifdef TIERED
   // C2 can leave the fpu stack dirty
-  if (UseSSE < 2 ) {
+  if (UseSSE < 2) {
     __ empty_FPU_stack();
   }
 #endif // TIERED
@@ -686,11 +706,7 @@
   // save exception oop and issuing pc into JavaThread
   // (exception handler will load it from here)
   __ movptr(Address(thread, JavaThread::exception_oop_offset()), exception_oop);
-  __ movptr(Address(thread, JavaThread::exception_pc_offset()), exception_pc);
-
-  // save real return address (pc that called this stub)
-  __ movptr(real_return_addr, Address(rbp, 1*BytesPerWord));
-  __ movptr(Address(rsp, temp_1_off * VMRegImpl::stack_slot_size), real_return_addr);
+  __ movptr(Address(thread, JavaThread::exception_pc_offset()),  exception_pc);
 
   // patch throwing pc into return address (has bci & oop map)
   __ movptr(Address(rbp, 1*BytesPerWord), exception_pc);
@@ -700,33 +716,41 @@
   int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, exception_handler_for_pc));
   oop_maps->add_gc_map(call_offset, oop_map);
 
-  // rax,: handler address
+  // rax: handler address
   //      will be the deopt blob if nmethod was deoptimized while we looked up
   //      handler regardless of whether handler existed in the nmethod.
 
   // only rax, is valid at this time, all other registers have been destroyed by the runtime call
   __ invalidate_registers(false, true, true, true, true, true);
 
-#ifdef ASSERT
-  // Do we have an exception handler in the nmethod?
-  Label done;
-  __ testptr(rax, rax);
-  __ jcc(Assembler::notZero, done);
-  __ stop("no handler found");
-  __ bind(done);
-#endif
-
-  // exception handler found
-  // patch the return address -> the stub will directly return to the exception handler
+  // patch the return address, this stub will directly return to the exception handler
   __ movptr(Address(rbp, 1*BytesPerWord), rax);
 
-  // restore registers
-  restore_live_registers(sasm, save_fpu_registers);
+  switch (id) {
+  case forward_exception_id:
+  case handle_exception_nofpu_id:
+  case handle_exception_id:
+    // Restore the registers that were saved at the beginning.
+    restore_live_registers(sasm, id == handle_exception_nofpu_id);
+    break;
+  case handle_exception_from_callee_id:
+    // WIN64_ONLY: No need to add frame::arg_reg_save_area_bytes to SP
+    // since we do a leave anyway.
 
-  // return to exception handler
-  __ leave();
-  __ ret(0);
+    // Pop the return address since we are possibly changing SP (restoring from BP).
+    __ leave();
+    __ pop(rcx);
 
+    // Restore SP from BP if the exception PC is a method handle call site.
+    NOT_LP64(__ get_thread(thread);)
+    __ cmpl(Address(thread, JavaThread::is_method_handle_return_offset()), 0);
+    __ cmovptr(Assembler::notEqual, rsp, rbp_mh_SP_save);
+    __ jmp(rcx);  // jump to exception handler
+    break;
+  default:  ShouldNotReachHere();
+  }
+
+  return oop_maps;
 }
 
 
@@ -791,7 +815,7 @@
   // the pop is also necessary to simulate the effect of a ret(0)
   __ pop(exception_pc);
 
-  // Restore SP from BP if the exception PC is a MethodHandle call site.
+  // Restore SP from BP if the exception PC is a method handle call site.
   NOT_LP64(__ get_thread(thread);)
   __ cmpl(Address(thread, JavaThread::is_method_handle_return_offset()), 0);
   __ cmovptr(Assembler::notEqual, rsp, rbp_mh_SP_save);
@@ -934,7 +958,6 @@
   __ ret(0);
 
   return oop_maps;
-
 }
 
 
@@ -952,35 +975,9 @@
   switch (id) {
     case forward_exception_id:
       {
-        // we're handling an exception in the context of a compiled
-        // frame.  The registers have been saved in the standard
-        // places.  Perform an exception lookup in the caller and
-        // dispatch to the handler if found.  Otherwise unwind and
-        // dispatch to the callers exception handler.
-
-        const Register thread = NOT_LP64(rdi) LP64_ONLY(r15_thread);
-        const Register exception_oop = rax;
-        const Register exception_pc = rdx;
-
-        // load pending exception oop into rax,
-        __ movptr(exception_oop, Address(thread, Thread::pending_exception_offset()));
-        // clear pending exception
-        __ movptr(Address(thread, Thread::pending_exception_offset()), NULL_WORD);
-
-        // load issuing PC (the return address for this stub) into rdx
-        __ movptr(exception_pc, Address(rbp, 1*BytesPerWord));
-
-        // make sure that the vm_results are cleared (may be unnecessary)
-        __ movptr(Address(thread, JavaThread::vm_result_offset()), NULL_WORD);
-        __ movptr(Address(thread, JavaThread::vm_result_2_offset()), NULL_WORD);
-
-        // verify that that there is really a valid exception in rax,
-        __ verify_not_null_oop(exception_oop);
-
-        oop_maps = new OopMapSet();
-        OopMap* oop_map = generate_oop_map(sasm, 1);
-        generate_handle_exception(sasm, oop_maps, oop_map);
-        __ stop("should not reach here");
+        oop_maps = generate_handle_exception(id, sasm);
+        __ leave();
+        __ ret(0);
       }
       break;
 
@@ -1315,13 +1312,15 @@
       break;
 
     case handle_exception_nofpu_id:
-      save_fpu_registers = false;
-      // fall through
     case handle_exception_id:
       { StubFrame f(sasm, "handle_exception", dont_gc_arguments);
-        oop_maps = new OopMapSet();
-        OopMap* oop_map = save_live_registers(sasm, 1, save_fpu_registers);
-        generate_handle_exception(sasm, oop_maps, oop_map, save_fpu_registers);
+        oop_maps = generate_handle_exception(id, sasm);
+      }
+      break;
+
+    case handle_exception_from_callee_id:
+      { StubFrame f(sasm, "handle_exception_from_callee", dont_gc_arguments);
+        oop_maps = generate_handle_exception(id, sasm);
       }
       break;
 
--- a/src/cpu/x86/vm/globals_x86.hpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/cpu/x86/vm/globals_x86.hpp	Mon Apr 04 19:23:29 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -76,4 +76,6 @@
 define_pd_global(bool, UseMembar,            false);
 #endif
 
+// GC Ergo Flags
+define_pd_global(intx, CMSYoungGenPerWorker, 64*M);  // default max size of CMS young gen, per GC worker thread
 #endif // CPU_X86_VM_GLOBALS_X86_HPP
--- a/src/cpu/x86/vm/interpreter_x86_32.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/cpu/x86/vm/interpreter_x86_32.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -231,7 +231,7 @@
 
 
 // Method handle invoker
-// Dispatch a method of the form java.dyn.MethodHandles::invoke(...)
+// Dispatch a method of the form java.lang.invoke.MethodHandles::invoke(...)
 address InterpreterGenerator::generate_method_handle_entry(void) {
   if (!EnableMethodHandles) {
     return generate_abstract_entry();
--- a/src/cpu/x86/vm/interpreter_x86_64.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/cpu/x86/vm/interpreter_x86_64.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -318,7 +318,7 @@
 
 
 // Method handle invoker
-// Dispatch a method of the form java.dyn.MethodHandles::invoke(...)
+// Dispatch a method of the form java.lang.invoke.MethodHandles::invoke(...)
 address InterpreterGenerator::generate_method_handle_entry(void) {
   if (!EnableMethodHandles) {
     return generate_abstract_entry();
--- a/src/cpu/x86/vm/methodHandles_x86.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/cpu/x86/vm/methodHandles_x86.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -125,9 +125,9 @@
   }
 
   // given the MethodType, find out where the MH argument is buried
-  __ load_heap_oop(rdx_temp, Address(rax_mtype, __ delayed_value(java_dyn_MethodType::form_offset_in_bytes, rdi_temp)));
+  __ load_heap_oop(rdx_temp, Address(rax_mtype, __ delayed_value(java_lang_invoke_MethodType::form_offset_in_bytes, rdi_temp)));
   Register rdx_vmslots = rdx_temp;
-  __ movl(rdx_vmslots, Address(rdx_temp, __ delayed_value(java_dyn_MethodTypeForm::vmslots_offset_in_bytes, rdi_temp)));
+  __ movl(rdx_vmslots, Address(rdx_temp, __ delayed_value(java_lang_invoke_MethodTypeForm::vmslots_offset_in_bytes, rdi_temp)));
   __ movptr(rcx_recv, __ argument_address(rdx_vmslots));
 
   trace_method_handle(_masm, "invokeExact");
@@ -154,11 +154,11 @@
                    rcx_argslot, rbx_temp, rdx_temp);
 
   // load up an adapter from the calling type (Java weaves this)
-  __ load_heap_oop(rdx_temp, Address(rax_mtype, __ delayed_value(java_dyn_MethodType::form_offset_in_bytes, rdi_temp)));
+  __ load_heap_oop(rdx_temp, Address(rax_mtype, __ delayed_value(java_lang_invoke_MethodType::form_offset_in_bytes, rdi_temp)));
   Register rdx_adapter = rdx_temp;
-  // __ load_heap_oop(rdx_adapter, Address(rdx_temp, java_dyn_MethodTypeForm::genericInvoker_offset_in_bytes()));
+  // __ load_heap_oop(rdx_adapter, Address(rdx_temp, java_lang_invoke_MethodTypeForm::genericInvoker_offset_in_bytes()));
   // deal with old JDK versions:
-  __ lea(rdi_temp, Address(rdx_temp, __ delayed_value(java_dyn_MethodTypeForm::genericInvoker_offset_in_bytes, rdi_temp)));
+  __ lea(rdi_temp, Address(rdx_temp, __ delayed_value(java_lang_invoke_MethodTypeForm::genericInvoker_offset_in_bytes, rdi_temp)));
   __ cmpptr(rdi_temp, rdx_temp);
   Label sorry_no_invoke_generic;
   __ jcc(Assembler::below, sorry_no_invoke_generic);
@@ -371,16 +371,16 @@
 
 // which conversion op types are implemented here?
 int MethodHandles::adapter_conversion_ops_supported_mask() {
-  return ((1<<sun_dyn_AdapterMethodHandle::OP_RETYPE_ONLY)
-         |(1<<sun_dyn_AdapterMethodHandle::OP_RETYPE_RAW)
-         |(1<<sun_dyn_AdapterMethodHandle::OP_CHECK_CAST)
-         |(1<<sun_dyn_AdapterMethodHandle::OP_PRIM_TO_PRIM)
-         |(1<<sun_dyn_AdapterMethodHandle::OP_REF_TO_PRIM)
-         |(1<<sun_dyn_AdapterMethodHandle::OP_SWAP_ARGS)
-         |(1<<sun_dyn_AdapterMethodHandle::OP_ROT_ARGS)
-         |(1<<sun_dyn_AdapterMethodHandle::OP_DUP_ARGS)
-         |(1<<sun_dyn_AdapterMethodHandle::OP_DROP_ARGS)
-         //|(1<<sun_dyn_AdapterMethodHandle::OP_SPREAD_ARGS) //BUG!
+  return ((1<<java_lang_invoke_AdapterMethodHandle::OP_RETYPE_ONLY)
+         |(1<<java_lang_invoke_AdapterMethodHandle::OP_RETYPE_RAW)
+         |(1<<java_lang_invoke_AdapterMethodHandle::OP_CHECK_CAST)
+         |(1<<java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_PRIM)
+         |(1<<java_lang_invoke_AdapterMethodHandle::OP_REF_TO_PRIM)
+         |(1<<java_lang_invoke_AdapterMethodHandle::OP_SWAP_ARGS)
+         |(1<<java_lang_invoke_AdapterMethodHandle::OP_ROT_ARGS)
+         |(1<<java_lang_invoke_AdapterMethodHandle::OP_DUP_ARGS)
+         |(1<<java_lang_invoke_AdapterMethodHandle::OP_DROP_ARGS)
+         //|(1<<java_lang_invoke_AdapterMethodHandle::OP_SPREAD_ARGS) //BUG!
          );
   // FIXME: MethodHandlesTest gets a crash if we enable OP_SPREAD_ARGS.
 }
@@ -415,20 +415,21 @@
   const Register rarg2_required = LP64_ONLY(j_rarg2) NOT_LP64(rdi);
   assert_different_registers(rarg0_code, rarg1_actual, rarg2_required, saved_last_sp);
 
-  guarantee(java_dyn_MethodHandle::vmentry_offset_in_bytes() != 0, "must have offsets");
+  guarantee(java_lang_invoke_MethodHandle::vmentry_offset_in_bytes() != 0, "must have offsets");
 
   // some handy addresses
   Address rbx_method_fie(     rbx,      methodOopDesc::from_interpreted_offset() );
+  Address rbx_method_fce(     rbx,      methodOopDesc::from_compiled_offset() );
 
-  Address rcx_mh_vmtarget(    rcx_recv, java_dyn_MethodHandle::vmtarget_offset_in_bytes() );
-  Address rcx_dmh_vmindex(    rcx_recv, sun_dyn_DirectMethodHandle::vmindex_offset_in_bytes() );
+  Address rcx_mh_vmtarget(    rcx_recv, java_lang_invoke_MethodHandle::vmtarget_offset_in_bytes() );
+  Address rcx_dmh_vmindex(    rcx_recv, java_lang_invoke_DirectMethodHandle::vmindex_offset_in_bytes() );
 
-  Address rcx_bmh_vmargslot(  rcx_recv, sun_dyn_BoundMethodHandle::vmargslot_offset_in_bytes() );
-  Address rcx_bmh_argument(   rcx_recv, sun_dyn_BoundMethodHandle::argument_offset_in_bytes() );
+  Address rcx_bmh_vmargslot(  rcx_recv, java_lang_invoke_BoundMethodHandle::vmargslot_offset_in_bytes() );
+  Address rcx_bmh_argument(   rcx_recv, java_lang_invoke_BoundMethodHandle::argument_offset_in_bytes() );
 
-  Address rcx_amh_vmargslot(  rcx_recv, sun_dyn_AdapterMethodHandle::vmargslot_offset_in_bytes() );
-  Address rcx_amh_argument(   rcx_recv, sun_dyn_AdapterMethodHandle::argument_offset_in_bytes() );
-  Address rcx_amh_conversion( rcx_recv, sun_dyn_AdapterMethodHandle::conversion_offset_in_bytes() );
+  Address rcx_amh_vmargslot(  rcx_recv, java_lang_invoke_AdapterMethodHandle::vmargslot_offset_in_bytes() );
+  Address rcx_amh_argument(   rcx_recv, java_lang_invoke_AdapterMethodHandle::argument_offset_in_bytes() );
+  Address rcx_amh_conversion( rcx_recv, java_lang_invoke_AdapterMethodHandle::conversion_offset_in_bytes() );
   Address vmarg;                // __ argument_address(vmargslot)
 
   const int java_mirror_offset = klassOopDesc::klass_part_offset_in_bytes() + Klass::java_mirror_offset_in_bytes();
@@ -448,12 +449,10 @@
   case _raise_exception:
     {
       // Not a real MH entry, but rather shared code for raising an
-      // exception.  Since we use a C2I adapter to set up the
-      // interpreter state, arguments are expected in compiler
-      // argument registers.
+      // exception.  Since we use the compiled entry, arguments are
+      // expected in compiler argument registers.
       assert(raise_exception_method(), "must be set");
-      address c2i_entry = raise_exception_method()->get_c2i_entry();
-      assert(c2i_entry, "method must be linked");
+      assert(raise_exception_method()->from_compiled_entry(), "method must be linked");
 
       const Register rdi_pc = rax;
       __ pop(rdi_pc);  // caller PC
@@ -461,7 +460,7 @@
 
       Register rbx_method = rbx_temp;
       Label L_no_method;
-      // FIXME: fill in _raise_exception_method with a suitable sun.dyn method
+      // FIXME: fill in _raise_exception_method with a suitable java.lang.invoke method
       __ movptr(rbx_method, ExternalAddress((address) &_raise_exception_method));
       __ testptr(rbx_method, rbx_method);
       __ jccb(Assembler::zero, L_no_method);
@@ -472,13 +471,10 @@
       __ jccb(Assembler::zero, L_no_method);
       __ verify_oop(rbx_method);
 
-      // 32-bit: push remaining arguments as if coming from the compiler.
       NOT_LP64(__ push(rarg2_required));
+      __ push(rdi_pc);         // restore caller PC
+      __ jmp(rbx_method_fce);  // jump to compiled entry
 
-      __ push(rdi_pc);  // restore caller PC
-      __ jump(ExternalAddress(c2i_entry));  // do C2I transition
-
-      // If we get here, the Java runtime did not do its job of creating the exception.
       // Do something that is at least causes a valid throw from the interpreter.
       __ bind(L_no_method);
       __ push(rarg2_required);
--- a/src/cpu/x86/vm/relocInfo_x86.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/cpu/x86/vm/relocInfo_x86.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -31,7 +31,7 @@
 #include "runtime/safepoint.hpp"
 
 
-void Relocation::pd_set_data_value(address x, intptr_t o) {
+void Relocation::pd_set_data_value(address x, intptr_t o, bool verify_only) {
 #ifdef AMD64
   x += o;
   typedef Assembler::WhichOperand WhichOperand;
@@ -40,19 +40,35 @@
          which == Assembler::narrow_oop_operand ||
          which == Assembler::imm_operand, "format unpacks ok");
   if (which == Assembler::imm_operand) {
-    *pd_address_in_code() = x;
+    if (verify_only) {
+      assert(*pd_address_in_code() == x, "instructions must match");
+    } else {
+      *pd_address_in_code() = x;
+    }
   } else if (which == Assembler::narrow_oop_operand) {
     address disp = Assembler::locate_operand(addr(), which);
-    *(int32_t*) disp = oopDesc::encode_heap_oop((oop)x);
+    if (verify_only) {
+      assert(*(uint32_t*) disp == oopDesc::encode_heap_oop((oop)x), "instructions must match");
+    } else {
+      *(int32_t*) disp = oopDesc::encode_heap_oop((oop)x);
+    }
   } else {
     // Note:  Use runtime_call_type relocations for call32_operand.
     address ip = addr();
     address disp = Assembler::locate_operand(ip, which);
     address next_ip = Assembler::locate_next_instruction(ip);
-    *(int32_t*) disp = x - next_ip;
+    if (verify_only) {
+      assert(*(int32_t*) disp == (x - next_ip), "instructions must match");
+    } else {
+      *(int32_t*) disp = x - next_ip;
+    }
   }
 #else
-  *pd_address_in_code() = x + o;
+  if (verify_only) {
+    assert(*pd_address_in_code() == (x + o), "instructions must match");
+  } else {
+    *pd_address_in_code() = x + o;
+  }
 #endif // AMD64
 }
 
--- a/src/cpu/x86/vm/stubGenerator_x86_32.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/cpu/x86/vm/stubGenerator_x86_32.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -442,10 +442,6 @@
     // Verify that there is really a valid exception in RAX.
     __ verify_oop(exception_oop);
 
-    // Restore SP from BP if the exception PC is a MethodHandle call site.
-    __ cmpl(Address(thread, JavaThread::is_method_handle_return_offset()), 0);
-    __ cmovptr(Assembler::notEqual, rsp, rbp);
-
     // continue at exception handler (return address removed)
     // rax: exception
     // rbx: exception handler
@@ -736,18 +732,19 @@
   //  Input:
   //     start   -  starting address
   //     count   -  element count
-  void  gen_write_ref_array_pre_barrier(Register start, Register count) {
+  void  gen_write_ref_array_pre_barrier(Register start, Register count, bool uninitialized_target) {
     assert_different_registers(start, count);
     BarrierSet* bs = Universe::heap()->barrier_set();
     switch (bs->kind()) {
       case BarrierSet::G1SATBCT:
       case BarrierSet::G1SATBCTLogging:
-        {
-          __ pusha();                      // push registers
-          __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre),
-                          start, count);
-          __ popa();
-        }
+        // With G1, don't generate the call if we statically know that the target in uninitialized
+        if (!uninitialized_target) {
+           __ pusha();                      // push registers
+           __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre),
+                           start, count);
+           __ popa();
+         }
         break;
       case BarrierSet::CardTableModRef:
       case BarrierSet::CardTableExtension:
@@ -926,7 +923,8 @@
 
   address generate_disjoint_copy(BasicType t, bool aligned,
                                  Address::ScaleFactor sf,
-                                 address* entry, const char *name) {
+                                 address* entry, const char *name,
+                                 bool dest_uninitialized = false) {
     __ align(CodeEntryAlignment);
     StubCodeMark mark(this, "StubRoutines", name);
     address start = __ pc();
@@ -948,16 +946,19 @@
     __ movptr(from , Address(rsp, 12+ 4));
     __ movptr(to   , Address(rsp, 12+ 8));
     __ movl(count, Address(rsp, 12+ 12));
+
+    if (entry != NULL) {
+      *entry = __ pc(); // Entry point from conjoint arraycopy stub.
+      BLOCK_COMMENT("Entry:");
+    }
+
     if (t == T_OBJECT) {
       __ testl(count, count);
       __ jcc(Assembler::zero, L_0_count);
-      gen_write_ref_array_pre_barrier(to, count);
+      gen_write_ref_array_pre_barrier(to, count, dest_uninitialized);
       __ mov(saved_to, to);          // save 'to'
     }
 
-    *entry = __ pc(); // Entry point from conjoint arraycopy stub.
-    BLOCK_COMMENT("Entry:");
-
     __ subptr(to, from); // to --> to_from
     __ cmpl(count, 2<<shift); // Short arrays (< 8 bytes) copy by element
     __ jcc(Assembler::below, L_copy_4_bytes); // use unsigned cmp
@@ -1088,7 +1089,8 @@
   address generate_conjoint_copy(BasicType t, bool aligned,
                                  Address::ScaleFactor sf,
                                  address nooverlap_target,
-                                 address* entry, const char *name) {
+                                 address* entry, const char *name,
+                                 bool dest_uninitialized = false) {
     __ align(CodeEntryAlignment);
     StubCodeMark mark(this, "StubRoutines", name);
     address start = __ pc();
@@ -1111,23 +1113,17 @@
     __ movptr(src  , Address(rsp, 12+ 4));   // from
     __ movptr(dst  , Address(rsp, 12+ 8));   // to
     __ movl2ptr(count, Address(rsp, 12+12)); // count
-    if (t == T_OBJECT) {
-       gen_write_ref_array_pre_barrier(dst, count);
-    }
 
     if (entry != NULL) {
       *entry = __ pc(); // Entry point from generic arraycopy stub.
       BLOCK_COMMENT("Entry:");
     }
 
-    if (t == T_OBJECT) {
-      __ testl(count, count);
-      __ jcc(Assembler::zero, L_0_count);
-    }
+    // nooverlap_target expects arguments in rsi and rdi.
     __ mov(from, src);
     __ mov(to  , dst);
 
-    // arrays overlap test
+    // arrays overlap test: dispatch to disjoint stub if necessary.
     RuntimeAddress nooverlap(nooverlap_target);
     __ cmpptr(dst, src);
     __ lea(end, Address(src, count, sf, 0)); // src + count * elem_size
@@ -1135,6 +1131,12 @@
     __ cmpptr(dst, end);
     __ jump_cc(Assembler::aboveEqual, nooverlap);
 
+    if (t == T_OBJECT) {
+      __ testl(count, count);
+      __ jcc(Assembler::zero, L_0_count);
+      gen_write_ref_array_pre_barrier(dst, count, dest_uninitialized);
+    }
+
     // copy from high to low
     __ cmpl(count, 2<<shift); // Short arrays (< 8 bytes) copy by element
     __ jcc(Assembler::below, L_copy_4_bytes); // use unsigned cmp
@@ -1419,7 +1421,7 @@
   //    rax, ==  0  -  success
   //    rax, == -1^K - failure, where K is partial transfer count
   //
-  address generate_checkcast_copy(const char *name, address* entry) {
+  address generate_checkcast_copy(const char *name, address* entry, bool dest_uninitialized = false) {
     __ align(CodeEntryAlignment);
     StubCodeMark mark(this, "StubRoutines", name);
     address start = __ pc();
@@ -1454,8 +1456,10 @@
     __ movptr(to,         to_arg);
     __ movl2ptr(length, length_arg);
 
-    *entry = __ pc(); // Entry point from generic arraycopy stub.
-    BLOCK_COMMENT("Entry:");
+    if (entry != NULL) {
+      *entry = __ pc(); // Entry point from generic arraycopy stub.
+      BLOCK_COMMENT("Entry:");
+    }
 
     //---------------------------------------------------------------
     // Assembler stub will be used for this call to arraycopy
@@ -1478,7 +1482,7 @@
     Address elem_klass_addr(elem, oopDesc::klass_offset_in_bytes());
 
     // Copy from low to high addresses, indexed from the end of each array.
-    gen_write_ref_array_pre_barrier(to, count);
+    gen_write_ref_array_pre_barrier(to, count, dest_uninitialized);
     __ lea(end_from, end_from_addr);
     __ lea(end_to,   end_to_addr);
     assert(length == count, "");        // else fix next line:
@@ -2041,6 +2045,15 @@
         generate_conjoint_copy(T_OBJECT, true, Address::times_ptr,  entry,
                                &entry_oop_arraycopy, "oop_arraycopy");
 
+    StubRoutines::_oop_disjoint_arraycopy_uninit =
+        generate_disjoint_copy(T_OBJECT, true, Address::times_ptr, &entry,
+                               "oop_disjoint_arraycopy_uninit",
+                               /*dest_uninitialized*/true);
+    StubRoutines::_oop_arraycopy_uninit =
+        generate_conjoint_copy(T_OBJECT, true, Address::times_ptr,  entry,
+                               NULL, "oop_arraycopy_uninit",
+                               /*dest_uninitialized*/true);
+
     StubRoutines::_jlong_disjoint_arraycopy =
         generate_disjoint_long_copy(&entry, "jlong_disjoint_arraycopy");
     StubRoutines::_jlong_arraycopy =
@@ -2054,20 +2067,20 @@
     StubRoutines::_arrayof_jshort_fill = generate_fill(T_SHORT, true, "arrayof_jshort_fill");
     StubRoutines::_arrayof_jint_fill = generate_fill(T_INT, true, "arrayof_jint_fill");
 
-    StubRoutines::_arrayof_jint_disjoint_arraycopy  =
-        StubRoutines::_jint_disjoint_arraycopy;
-    StubRoutines::_arrayof_oop_disjoint_arraycopy   =
-        StubRoutines::_oop_disjoint_arraycopy;
-    StubRoutines::_arrayof_jlong_disjoint_arraycopy =
-        StubRoutines::_jlong_disjoint_arraycopy;
+    StubRoutines::_arrayof_jint_disjoint_arraycopy       = StubRoutines::_jint_disjoint_arraycopy;
+    StubRoutines::_arrayof_oop_disjoint_arraycopy        = StubRoutines::_oop_disjoint_arraycopy;
+    StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit = StubRoutines::_oop_disjoint_arraycopy_uninit;
+    StubRoutines::_arrayof_jlong_disjoint_arraycopy      = StubRoutines::_jlong_disjoint_arraycopy;
 
-    StubRoutines::_arrayof_jint_arraycopy  = StubRoutines::_jint_arraycopy;
-    StubRoutines::_arrayof_oop_arraycopy   = StubRoutines::_oop_arraycopy;
-    StubRoutines::_arrayof_jlong_arraycopy = StubRoutines::_jlong_arraycopy;
+    StubRoutines::_arrayof_jint_arraycopy       = StubRoutines::_jint_arraycopy;
+    StubRoutines::_arrayof_oop_arraycopy        = StubRoutines::_oop_arraycopy;
+    StubRoutines::_arrayof_oop_arraycopy_uninit = StubRoutines::_oop_arraycopy_uninit;
+    StubRoutines::_arrayof_jlong_arraycopy      = StubRoutines::_jlong_arraycopy;
 
     StubRoutines::_checkcast_arraycopy =
-        generate_checkcast_copy("checkcast_arraycopy",
-                                  &entry_checkcast_arraycopy);
+        generate_checkcast_copy("checkcast_arraycopy", &entry_checkcast_arraycopy);
+    StubRoutines::_checkcast_arraycopy_uninit =
+        generate_checkcast_copy("checkcast_arraycopy_uninit", NULL, /*dest_uninitialized*/true);
 
     StubRoutines::_unsafe_arraycopy =
         generate_unsafe_copy("unsafe_arraycopy",
--- a/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -1060,20 +1060,6 @@
     return start;
   }
 
-  static address disjoint_byte_copy_entry;
-  static address disjoint_short_copy_entry;
-  static address disjoint_int_copy_entry;
-  static address disjoint_long_copy_entry;
-  static address disjoint_oop_copy_entry;
-
-  static address byte_copy_entry;
-  static address short_copy_entry;
-  static address int_copy_entry;
-  static address long_copy_entry;
-  static address oop_copy_entry;
-
-  static address checkcast_copy_entry;
-
   //
   // Verify that a register contains clean 32-bits positive value
   // (high 32-bits are 0) so it could be used in 64-bits shifts.
@@ -1176,34 +1162,35 @@
   // Generate code for an array write pre barrier
   //
   //     addr    -  starting address
-  //     count    -  element count
+  //     count   -  element count
+  //     tmp     - scratch register
   //
   //     Destroy no registers!
   //
-  void  gen_write_ref_array_pre_barrier(Register addr, Register count) {
+  void  gen_write_ref_array_pre_barrier(Register addr, Register count, bool dest_uninitialized) {
     BarrierSet* bs = Universe::heap()->barrier_set();
     switch (bs->kind()) {
       case BarrierSet::G1SATBCT:
       case BarrierSet::G1SATBCTLogging:
-        {
-          __ pusha();                      // push registers
-          if (count == c_rarg0) {
-            if (addr == c_rarg1) {
-              // exactly backwards!!
-              __ xchgptr(c_rarg1, c_rarg0);
-            } else {
-              __ movptr(c_rarg1, count);
-              __ movptr(c_rarg0, addr);
-            }
-
-          } else {
-            __ movptr(c_rarg0, addr);
-            __ movptr(c_rarg1, count);
-          }
-          __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre), 2);
-          __ popa();
+        // With G1, don't generate the call if we statically know that the target in uninitialized
+        if (!dest_uninitialized) {
+           __ pusha();                      // push registers
+           if (count == c_rarg0) {
+             if (addr == c_rarg1) {
+               // exactly backwards!!
+               __ xchgptr(c_rarg1, c_rarg0);
+             } else {
+               __ movptr(c_rarg1, count);
+               __ movptr(c_rarg0, addr);
+             }
+           } else {
+             __ movptr(c_rarg0, addr);
+             __ movptr(c_rarg1, count);
+           }
+           __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre), 2);
+           __ popa();
         }
-        break;
+         break;
       case BarrierSet::CardTableModRef:
       case BarrierSet::CardTableExtension:
       case BarrierSet::ModRef:
@@ -1382,7 +1369,7 @@
   //   disjoint_byte_copy_entry is set to the no-overlap entry point
   //   used by generate_conjoint_byte_copy().
   //
-  address generate_disjoint_byte_copy(bool aligned, const char *name) {
+  address generate_disjoint_byte_copy(bool aligned, address* entry, const char *name) {
     __ align(CodeEntryAlignment);
     StubCodeMark mark(this, "StubRoutines", name);
     address start = __ pc();
@@ -1402,9 +1389,11 @@
     __ enter(); // required for proper stackwalking of RuntimeStub frame
     assert_clean_int(c_rarg2, rax);    // Make sure 'count' is clean int.
 
-    disjoint_byte_copy_entry = __ pc();
-    BLOCK_COMMENT("Entry:");
-    // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
+    if (entry != NULL) {
+      *entry = __ pc();
+       // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
+      BLOCK_COMMENT("Entry:");
+    }
 
     setup_arg_regs(); // from => rdi, to => rsi, count => rdx
                       // r9 and r10 may be used to save non-volatile registers
@@ -1482,7 +1471,8 @@
   // dwords or qwords that span cache line boundaries will still be loaded
   // and stored atomically.
   //
-  address generate_conjoint_byte_copy(bool aligned, const char *name) {
+  address generate_conjoint_byte_copy(bool aligned, address nooverlap_target,
+                                      address* entry, const char *name) {
     __ align(CodeEntryAlignment);
     StubCodeMark mark(this, "StubRoutines", name);
     address start = __ pc();
@@ -1497,11 +1487,13 @@
     __ enter(); // required for proper stackwalking of RuntimeStub frame
     assert_clean_int(c_rarg2, rax);    // Make sure 'count' is clean int.
 
-    byte_copy_entry = __ pc();
-    BLOCK_COMMENT("Entry:");
-    // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
-
-    array_overlap_test(disjoint_byte_copy_entry, Address::times_1);
+    if (entry != NULL) {
+      *entry = __ pc();
+      // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
+      BLOCK_COMMENT("Entry:");
+    }
+
+    array_overlap_test(nooverlap_target, Address::times_1);
     setup_arg_regs(); // from => rdi, to => rsi, count => rdx
                       // r9 and r10 may be used to save non-volatile registers
 
@@ -1577,7 +1569,7 @@
   //   disjoint_short_copy_entry is set to the no-overlap entry point
   //   used by generate_conjoint_short_copy().
   //
-  address generate_disjoint_short_copy(bool aligned, const char *name) {
+  address generate_disjoint_short_copy(bool aligned, address *entry, const char *name) {
     __ align(CodeEntryAlignment);
     StubCodeMark mark(this, "StubRoutines", name);
     address start = __ pc();
@@ -1596,9 +1588,11 @@
     __ enter(); // required for proper stackwalking of RuntimeStub frame
     assert_clean_int(c_rarg2, rax);    // Make sure 'count' is clean int.
 
-    disjoint_short_copy_entry = __ pc();
-    BLOCK_COMMENT("Entry:");
-    // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
+    if (entry != NULL) {
+      *entry = __ pc();
+      // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
+      BLOCK_COMMENT("Entry:");
+    }
 
     setup_arg_regs(); // from => rdi, to => rsi, count => rdx
                       // r9 and r10 may be used to save non-volatile registers
@@ -1689,7 +1683,8 @@
   // or qwords that span cache line boundaries will still be loaded
   // and stored atomically.
   //
-  address generate_conjoint_short_copy(bool aligned, const char *name) {
+  address generate_conjoint_short_copy(bool aligned, address nooverlap_target,
+                                       address *entry, const char *name) {
     __ align(CodeEntryAlignment);
     StubCodeMark mark(this, "StubRoutines", name);
     address start = __ pc();
@@ -1704,11 +1699,13 @@
     __ enter(); // required for proper stackwalking of RuntimeStub frame
     assert_clean_int(c_rarg2, rax);    // Make sure 'count' is clean int.
 
-    short_copy_entry = __ pc();
-    BLOCK_COMMENT("Entry:");
-    // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
-
-    array_overlap_test(disjoint_short_copy_entry, Address::times_2);
+    if (entry != NULL) {
+      *entry = __ pc();
+      // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
+      BLOCK_COMMENT("Entry:");
+    }
+
+    array_overlap_test(nooverlap_target, Address::times_2);
     setup_arg_regs(); // from => rdi, to => rsi, count => rdx
                       // r9 and r10 may be used to save non-volatile registers
 
@@ -1776,7 +1773,8 @@
   //   disjoint_int_copy_entry is set to the no-overlap entry point
   //   used by generate_conjoint_int_oop_copy().
   //
-  address generate_disjoint_int_oop_copy(bool aligned, bool is_oop, const char *name) {
+  address generate_disjoint_int_oop_copy(bool aligned, bool is_oop, address* entry,
+                                         const char *name, bool dest_uninitialized = false) {
     __ align(CodeEntryAlignment);
     StubCodeMark mark(this, "StubRoutines", name);
     address start = __ pc();
@@ -1796,21 +1794,17 @@
     __ enter(); // required for proper stackwalking of RuntimeStub frame
     assert_clean_int(c_rarg2, rax);    // Make sure 'count' is clean int.
 
-    (is_oop ? disjoint_oop_copy_entry : disjoint_int_copy_entry) = __ pc();
-
-    if (is_oop) {
-      // no registers are destroyed by this call
-      gen_write_ref_array_pre_barrier(/* dest */ c_rarg1, /* count */ c_rarg2);
+    if (entry != NULL) {
+      *entry = __ pc();
+      // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
+      BLOCK_COMMENT("Entry:");
     }
 
-    BLOCK_COMMENT("Entry:");
-    // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
-
     setup_arg_regs(); // from => rdi, to => rsi, count => rdx
                       // r9 and r10 may be used to save non-volatile registers
-
     if (is_oop) {
       __ movq(saved_to, to);
+      gen_write_ref_array_pre_barrier(to, count, dest_uninitialized);
     }
 
     // 'from', 'to' and 'count' are now valid
@@ -1870,7 +1864,9 @@
   // the hardware handle it.  The two dwords within qwords that span
   // cache line boundaries will still be loaded and stored atomicly.
   //
-  address generate_conjoint_int_oop_copy(bool aligned, bool is_oop, const char *name) {
+  address generate_conjoint_int_oop_copy(bool aligned, bool is_oop, address nooverlap_target,
+                                         address *entry, const char *name,
+                                         bool dest_uninitialized = false) {
     __ align(CodeEntryAlignment);
     StubCodeMark mark(this, "StubRoutines", name);
     address start = __ pc();
@@ -1885,20 +1881,21 @@
     __ enter(); // required for proper stackwalking of RuntimeStub frame
     assert_clean_int(c_rarg2, rax);    // Make sure 'count' is clean int.
 
+    if (entry != NULL) {
+      *entry = __ pc();
+       // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
+      BLOCK_COMMENT("Entry:");
+    }
+
+    array_overlap_test(nooverlap_target, Address::times_4);
+    setup_arg_regs(); // from => rdi, to => rsi, count => rdx
+                      // r9 and r10 may be used to save non-volatile registers
+
     if (is_oop) {
       // no registers are destroyed by this call
-      gen_write_ref_array_pre_barrier(/* dest */ c_rarg1, /* count */ c_rarg2);
+      gen_write_ref_array_pre_barrier(to, count, dest_uninitialized);
     }
 
-    (is_oop ? oop_copy_entry : int_copy_entry) = __ pc();
-    BLOCK_COMMENT("Entry:");
-    // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
-
-    array_overlap_test(is_oop ? disjoint_oop_copy_entry : disjoint_int_copy_entry,
-                       Address::times_4);
-    setup_arg_regs(); // from => rdi, to => rsi, count => rdx
-                      // r9 and r10 may be used to save non-volatile registers
-
     assert_clean_int(count, rax); // Make sure 'count' is clean int.
     // 'from', 'to' and 'count' are now valid
     __ movptr(dword_count, count);
@@ -1962,7 +1959,8 @@
   //   disjoint_oop_copy_entry or disjoint_long_copy_entry is set to the
   //   no-overlap entry point used by generate_conjoint_long_oop_copy().
   //
-  address generate_disjoint_long_oop_copy(bool aligned, bool is_oop, const char *name) {
+  address generate_disjoint_long_oop_copy(bool aligned, bool is_oop, address *entry,
+                                          const char *name, bool dest_uninitialized = false) {
     __ align(CodeEntryAlignment);
     StubCodeMark mark(this, "StubRoutines", name);
     address start = __ pc();
@@ -1981,20 +1979,19 @@
     // Save no-overlap entry point for generate_conjoint_long_oop_copy()
     assert_clean_int(c_rarg2, rax);    // Make sure 'count' is clean int.
 
-    if (is_oop) {
-      disjoint_oop_copy_entry  = __ pc();
-      // no registers are destroyed by this call
-      gen_write_ref_array_pre_barrier(/* dest */ c_rarg1, /* count */ c_rarg2);
-    } else {
-      disjoint_long_copy_entry = __ pc();
+    if (entry != NULL) {
+      *entry = __ pc();
+      // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
+      BLOCK_COMMENT("Entry:");
     }
-    BLOCK_COMMENT("Entry:");
-    // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
 
     setup_arg_regs(); // from => rdi, to => rsi, count => rdx
                       // r9 and r10 may be used to save non-volatile registers
-
     // 'from', 'to' and 'qword_count' are now valid
+    if (is_oop) {
+      // no registers are destroyed by this call
+      gen_write_ref_array_pre_barrier(to, qword_count, dest_uninitialized);
+    }
 
     // Copy from low to high addresses.  Use 'to' as scratch.
     __ lea(end_from, Address(from, qword_count, Address::times_8, -8));
@@ -2048,7 +2045,9 @@
   //   c_rarg1   - destination array address
   //   c_rarg2   - element count, treated as ssize_t, can be zero
   //
-  address generate_conjoint_long_oop_copy(bool aligned, bool is_oop, const char *name) {
+  address generate_conjoint_long_oop_copy(bool aligned, bool is_oop,
+                                          address nooverlap_target, address *entry,
+                                          const char *name, bool dest_uninitialized = false) {
     __ align(CodeEntryAlignment);
     StubCodeMark mark(this, "StubRoutines", name);
     address start = __ pc();
@@ -2062,31 +2061,21 @@
     __ enter(); // required for proper stackwalking of RuntimeStub frame
     assert_clean_int(c_rarg2, rax);    // Make sure 'count' is clean int.
 
-    address disjoint_copy_entry = NULL;
-    if (is_oop) {
-      assert(!UseCompressedOops, "shouldn't be called for compressed oops");
-      disjoint_copy_entry = disjoint_oop_copy_entry;
-      oop_copy_entry  = __ pc();
-      array_overlap_test(disjoint_oop_copy_entry, Address::times_8);
-    } else {
-      disjoint_copy_entry = disjoint_long_copy_entry;
-      long_copy_entry = __ pc();
-      array_overlap_test(disjoint_long_copy_entry, Address::times_8);
+    if (entry != NULL) {
+      *entry = __ pc();
+      // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
+      BLOCK_COMMENT("Entry:");
     }
-    BLOCK_COMMENT("Entry:");
-    // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
-
-    array_overlap_test(disjoint_copy_entry, Address::times_8);
+
+    array_overlap_test(nooverlap_target, Address::times_8);
     setup_arg_regs(); // from => rdi, to => rsi, count => rdx
                       // r9 and r10 may be used to save non-volatile registers
-
     // 'from', 'to' and 'qword_count' are now valid
-
     if (is_oop) {
       // Save to and count for store barrier
       __ movptr(saved_count, qword_count);
       // No registers are destroyed by this call
-      gen_write_ref_array_pre_barrier(to, saved_count);
+      gen_write_ref_array_pre_barrier(to, saved_count, dest_uninitialized);
     }
 
     __ jmp(L_copy_32_bytes);
@@ -2165,7 +2154,8 @@
   //    rax ==  0  -  success
   //    rax == -1^K - failure, where K is partial transfer count
   //
-  address generate_checkcast_copy(const char *name) {
+  address generate_checkcast_copy(const char *name, address *entry,
+                                  bool dest_uninitialized = false) {
 
     Label L_load_element, L_store_element, L_do_card_marks, L_done;
 
@@ -2219,8 +2209,10 @@
 #endif
 
     // Caller of this entry point must set up the argument registers.
-    checkcast_copy_entry  = __ pc();
-    BLOCK_COMMENT("Entry:");
+    if (entry != NULL) {
+      *entry = __ pc();
+      BLOCK_COMMENT("Entry:");
+    }
 
     // allocate spill slots for r13, r14
     enum {
@@ -2257,7 +2249,7 @@
     Address from_element_addr(end_from, count, TIMES_OOP, 0);
     Address   to_element_addr(end_to,   count, TIMES_OOP, 0);
 
-    gen_write_ref_array_pre_barrier(to, count);
+    gen_write_ref_array_pre_barrier(to, count, dest_uninitialized);
 
     // Copy from low to high addresses, indexed from the end of each array.
     __ lea(end_from, end_from_addr);
@@ -2337,7 +2329,9 @@
   // Examines the alignment of the operands and dispatches
   // to a long, int, short, or byte copy loop.
   //
-  address generate_unsafe_copy(const char *name) {
+  address generate_unsafe_copy(const char *name,
+                               address byte_copy_entry, address short_copy_entry,
+                               address int_copy_entry, address long_copy_entry) {
 
     Label L_long_aligned, L_int_aligned, L_short_aligned;
 
@@ -2435,7 +2429,10 @@
   //    rax ==  0  -  success
   //    rax == -1^K - failure, where K is partial transfer count
   //
-  address generate_generic_copy(const char *name) {
+  address generate_generic_copy(const char *name,
+                                address byte_copy_entry, address short_copy_entry,
+                                address int_copy_entry, address long_copy_entry,
+                                address oop_copy_entry, address checkcast_copy_entry) {
 
     Label L_failed, L_failed_0, L_objArray;
     Label L_copy_bytes, L_copy_shorts, L_copy_ints, L_copy_longs;
@@ -2728,33 +2725,75 @@
   }
 
   void generate_arraycopy_stubs() {
-    // Call the conjoint generation methods immediately after
-    // the disjoint ones so that short branches from the former
-    // to the latter can be generated.
-    StubRoutines::_jbyte_disjoint_arraycopy  = generate_disjoint_byte_copy(false, "jbyte_disjoint_arraycopy");
-    StubRoutines::_jbyte_arraycopy           = generate_conjoint_byte_copy(false, "jbyte_arraycopy");
-
-    StubRoutines::_jshort_disjoint_arraycopy = generate_disjoint_short_copy(false, "jshort_disjoint_arraycopy");
-    StubRoutines::_jshort_arraycopy          = generate_conjoint_short_copy(false, "jshort_arraycopy");
-
-    StubRoutines::_jint_disjoint_arraycopy   = generate_disjoint_int_oop_copy(false, false, "jint_disjoint_arraycopy");
-    StubRoutines::_jint_arraycopy            = generate_conjoint_int_oop_copy(false, false, "jint_arraycopy");
-
-    StubRoutines::_jlong_disjoint_arraycopy  = generate_disjoint_long_oop_copy(false, false, "jlong_disjoint_arraycopy");
-    StubRoutines::_jlong_arraycopy           = generate_conjoint_long_oop_copy(false, false, "jlong_arraycopy");
+    address entry;
+    address entry_jbyte_arraycopy;
+    address entry_jshort_arraycopy;
+    address entry_jint_arraycopy;
+    address entry_oop_arraycopy;
+    address entry_jlong_arraycopy;
+    address entry_checkcast_arraycopy;
+
+    StubRoutines::_jbyte_disjoint_arraycopy  = generate_disjoint_byte_copy(false, &entry,
+                                                                           "jbyte_disjoint_arraycopy");
+    StubRoutines::_jbyte_arraycopy           = generate_conjoint_byte_copy(false, entry, &entry_jbyte_arraycopy,
+                                                                           "jbyte_arraycopy");
+
+    StubRoutines::_jshort_disjoint_arraycopy = generate_disjoint_short_copy(false, &entry,
+                                                                            "jshort_disjoint_arraycopy");
+    StubRoutines::_jshort_arraycopy          = generate_conjoint_short_copy(false, entry, &entry_jshort_arraycopy,
+                                                                            "jshort_arraycopy");
+
+    StubRoutines::_jint_disjoint_arraycopy   = generate_disjoint_int_oop_copy(false, false, &entry,
+                                                                              "jint_disjoint_arraycopy");
+    StubRoutines::_jint_arraycopy            = generate_conjoint_int_oop_copy(false, false, entry,
+                                                                              &entry_jint_arraycopy, "jint_arraycopy");
+
+    StubRoutines::_jlong_disjoint_arraycopy  = generate_disjoint_long_oop_copy(false, false, &entry,
+                                                                               "jlong_disjoint_arraycopy");
+    StubRoutines::_jlong_arraycopy           = generate_conjoint_long_oop_copy(false, false, entry,
+                                                                               &entry_jlong_arraycopy, "jlong_arraycopy");
 
 
     if (UseCompressedOops) {
-      StubRoutines::_oop_disjoint_arraycopy  = generate_disjoint_int_oop_copy(false, true, "oop_disjoint_arraycopy");
-      StubRoutines::_oop_arraycopy           = generate_conjoint_int_oop_copy(false, true, "oop_arraycopy");
+      StubRoutines::_oop_disjoint_arraycopy  = generate_disjoint_int_oop_copy(false, true, &entry,
+                                                                              "oop_disjoint_arraycopy");
+      StubRoutines::_oop_arraycopy           = generate_conjoint_int_oop_copy(false, true, entry,
+                                                                              &entry_oop_arraycopy, "oop_arraycopy");
+      StubRoutines::_oop_disjoint_arraycopy_uninit  = generate_disjoint_int_oop_copy(false, true, &entry,
+                                                                                     "oop_disjoint_arraycopy_uninit",
+                                                                                     /*dest_uninitialized*/true);
+      StubRoutines::_oop_arraycopy_uninit           = generate_conjoint_int_oop_copy(false, true, entry,
+                                                                                     NULL, "oop_arraycopy_uninit",
+                                                                                     /*dest_uninitialized*/true);
     } else {
-      StubRoutines::_oop_disjoint_arraycopy  = generate_disjoint_long_oop_copy(false, true, "oop_disjoint_arraycopy");
-      StubRoutines::_oop_arraycopy           = generate_conjoint_long_oop_copy(false, true, "oop_arraycopy");
+      StubRoutines::_oop_disjoint_arraycopy  = generate_disjoint_long_oop_copy(false, true, &entry,
+                                                                               "oop_disjoint_arraycopy");
+      StubRoutines::_oop_arraycopy           = generate_conjoint_long_oop_copy(false, true, entry,
+                                                                               &entry_oop_arraycopy, "oop_arraycopy");
+      StubRoutines::_oop_disjoint_arraycopy_uninit  = generate_disjoint_long_oop_copy(false, true, &entry,
+                                                                                      "oop_disjoint_arraycopy_uninit",
+                                                                                      /*dest_uninitialized*/true);
+      StubRoutines::_oop_arraycopy_uninit           = generate_conjoint_long_oop_copy(false, true, entry,
+                                                                                      NULL, "oop_arraycopy_uninit",
+                                                                                      /*dest_uninitialized*/true);
     }
 
-    StubRoutines::_checkcast_arraycopy = generate_checkcast_copy("checkcast_arraycopy");
-    StubRoutines::_unsafe_arraycopy    = generate_unsafe_copy("unsafe_arraycopy");
-    StubRoutines::_generic_arraycopy   = generate_generic_copy("generic_arraycopy");
+    StubRoutines::_checkcast_arraycopy        = generate_checkcast_copy("checkcast_arraycopy", &entry_checkcast_arraycopy);
+    StubRoutines::_checkcast_arraycopy_uninit = generate_checkcast_copy("checkcast_arraycopy_uninit", NULL,
+                                                                        /*dest_uninitialized*/true);
+
+    StubRoutines::_unsafe_arraycopy    = generate_unsafe_copy("unsafe_arraycopy",
+                                                              entry_jbyte_arraycopy,
+                                                              entry_jshort_arraycopy,
+                                                              entry_jint_arraycopy,
+                                                              entry_jlong_arraycopy);
+    StubRoutines::_generic_arraycopy   = generate_generic_copy("generic_arraycopy",
+                                                               entry_jbyte_arraycopy,
+                                                               entry_jshort_arraycopy,
+                                                               entry_jint_arraycopy,
+                                                               entry_oop_arraycopy,
+                                                               entry_jlong_arraycopy,
+                                                               entry_checkcast_arraycopy);
 
     StubRoutines::_jbyte_fill = generate_fill(T_BYTE, false, "jbyte_fill");
     StubRoutines::_jshort_fill = generate_fill(T_SHORT, false, "jshort_fill");
@@ -2779,6 +2818,9 @@
 
     StubRoutines::_arrayof_oop_disjoint_arraycopy    = StubRoutines::_oop_disjoint_arraycopy;
     StubRoutines::_arrayof_oop_arraycopy             = StubRoutines::_oop_arraycopy;
+
+    StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit    = StubRoutines::_oop_disjoint_arraycopy_uninit;
+    StubRoutines::_arrayof_oop_arraycopy_uninit             = StubRoutines::_oop_arraycopy_uninit;
   }
 
   void generate_math_stubs() {
@@ -3072,20 +3114,6 @@
   }
 }; // end class declaration
 
-address StubGenerator::disjoint_byte_copy_entry  = NULL;
-address StubGenerator::disjoint_short_copy_entry = NULL;
-address StubGenerator::disjoint_int_copy_entry   = NULL;
-address StubGenerator::disjoint_long_copy_entry  = NULL;
-address StubGenerator::disjoint_oop_copy_entry   = NULL;
-
-address StubGenerator::byte_copy_entry  = NULL;
-address StubGenerator::short_copy_entry = NULL;
-address StubGenerator::int_copy_entry   = NULL;
-address StubGenerator::long_copy_entry  = NULL;
-address StubGenerator::oop_copy_entry   = NULL;
-
-address StubGenerator::checkcast_copy_entry = NULL;
-
 void StubGenerator_generate(CodeBuffer* code, bool all) {
   StubGenerator g(code, all);
 }
--- a/src/cpu/x86/vm/templateTable_x86_32.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/cpu/x86/vm/templateTable_x86_32.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -3110,7 +3110,7 @@
     __ profile_call(rsi);
   }
 
-  __ movptr(rcx_method_handle, Address(rax_callsite, __ delayed_value(java_dyn_CallSite::target_offset_in_bytes, rcx)));
+  __ movptr(rcx_method_handle, Address(rax_callsite, __ delayed_value(java_lang_invoke_CallSite::target_offset_in_bytes, rcx)));
   __ null_check(rcx_method_handle);
   __ prepare_to_jump_from_interpreted();
   __ jump_to_method_handle_entry(rcx_method_handle, rdx);
--- a/src/cpu/x86/vm/templateTable_x86_64.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/cpu/x86/vm/templateTable_x86_64.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -3145,7 +3145,7 @@
     __ profile_call(r13);
   }
 
-  __ load_heap_oop(rcx_method_handle, Address(rax_callsite, __ delayed_value(java_dyn_CallSite::target_offset_in_bytes, rcx)));
+  __ load_heap_oop(rcx_method_handle, Address(rax_callsite, __ delayed_value(java_lang_invoke_CallSite::target_offset_in_bytes, rcx)));
   __ null_check(rcx_method_handle);
   __ prepare_to_jump_from_interpreted();
   __ jump_to_method_handle_entry(rcx_method_handle, rdx);
--- a/src/cpu/x86/vm/vm_version_x86.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/cpu/x86/vm/vm_version_x86.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -439,6 +439,13 @@
         UseCountLeadingZerosInstruction = true;
       }
     }
+
+    // On family 21 processors default is no sw prefetch
+    if ( cpu_family() == 21 ) {
+      if (FLAG_IS_DEFAULT(AllocatePrefetchStyle)) {
+        AllocatePrefetchStyle = 0;
+      }
+    }
   }
 
   if( is_intel() ) { // Intel cpus specific settings
--- a/src/cpu/x86/vm/x86_32.ad	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/cpu/x86/vm/x86_32.ad	Mon Apr 04 19:23:29 2011 -0700
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+// Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 //
 // This code is free software; you can redistribute it and/or modify it
@@ -12658,17 +12658,46 @@
   ins_pipe( pipe_slow );
 %}
 
+// fast search of substring with known size.
+instruct string_indexof_con(eDIRegP str1, eDXRegI cnt1, eSIRegP str2, immI int_cnt2,
+                            eBXRegI result, regXD vec, eAXRegI cnt2, eCXRegI tmp, eFlagsReg cr) %{
+  predicate(UseSSE42Intrinsics);
+  match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
+  effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr);
+
+  format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result   // KILL $vec, $cnt1, $cnt2, $tmp" %}
+  ins_encode %{
+    int icnt2 = (int)$int_cnt2$$constant;
+    if (icnt2 >= 8) {
+      // IndexOf for constant substrings with size >= 8 elements
+      // which don't need to be loaded through stack.
+      __ string_indexofC8($str1$$Register, $str2$$Register,
+                          $cnt1$$Register, $cnt2$$Register,
+                          icnt2, $result$$Register,
+                          $vec$$XMMRegister, $tmp$$Register);
+    } else {
+      // Small strings are loaded through stack if they cross page boundary.
+      __ string_indexof($str1$$Register, $str2$$Register,
+                        $cnt1$$Register, $cnt2$$Register,
+                        icnt2, $result$$Register,
+                        $vec$$XMMRegister, $tmp$$Register);
+    }
+  %}
+  ins_pipe( pipe_slow );
+%}
+
 instruct string_indexof(eDIRegP str1, eDXRegI cnt1, eSIRegP str2, eAXRegI cnt2,
-                        eBXRegI result, regXD tmp1, eCXRegI tmp2, eFlagsReg cr) %{
+                        eBXRegI result, regXD vec, eCXRegI tmp, eFlagsReg cr) %{
   predicate(UseSSE42Intrinsics);
   match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
-  effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp2, KILL cr);
-
-  format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result   // KILL $tmp2, $tmp1" %}
+  effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr);
+
+  format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result   // KILL all" %}
   ins_encode %{
     __ string_indexof($str1$$Register, $str2$$Register,
-                      $cnt1$$Register, $cnt2$$Register, $result$$Register,
-                      $tmp1$$XMMRegister, $tmp2$$Register);
+                      $cnt1$$Register, $cnt2$$Register,
+                      (-1), $result$$Register,
+                      $vec$$XMMRegister, $tmp$$Register);
   %}
   ins_pipe( pipe_slow );
 %}
--- a/src/cpu/x86/vm/x86_64.ad	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/cpu/x86/vm/x86_64.ad	Mon Apr 04 19:23:29 2011 -0700
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+// Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 //
 // This code is free software; you can redistribute it and/or modify it
@@ -11598,18 +11598,48 @@
   ins_pipe( pipe_slow );
 %}
 
+// fast search of substring with known size.
+instruct string_indexof_con(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2,
+                            rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr)
+%{
+  predicate(UseSSE42Intrinsics);
+  match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
+  effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr);
+
+  format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result   // KILL $vec, $cnt1, $cnt2, $tmp" %}
+  ins_encode %{
+    int icnt2 = (int)$int_cnt2$$constant;
+    if (icnt2 >= 8) {
+      // IndexOf for constant substrings with size >= 8 elements
+      // which don't need to be loaded through stack.
+      __ string_indexofC8($str1$$Register, $str2$$Register,
+                          $cnt1$$Register, $cnt2$$Register,
+                          icnt2, $result$$Register,
+                          $vec$$XMMRegister, $tmp$$Register);
+    } else {
+      // Small strings are loaded through stack if they cross page boundary.
+      __ string_indexof($str1$$Register, $str2$$Register,
+                        $cnt1$$Register, $cnt2$$Register,
+                        icnt2, $result$$Register,
+                        $vec$$XMMRegister, $tmp$$Register);
+    }
+  %}
+  ins_pipe( pipe_slow );
+%}
+
 instruct string_indexof(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2,
-                        rbx_RegI result, regD tmp1, rcx_RegI tmp2, rFlagsReg cr)
+                        rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr)
 %{
   predicate(UseSSE42Intrinsics);
   match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
-  effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp2, KILL cr);
-
-  format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result   // KILL $tmp1, $tmp2" %}
+  effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr);
+
+  format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result   // KILL all" %}
   ins_encode %{
     __ string_indexof($str1$$Register, $str2$$Register,
-                      $cnt1$$Register, $cnt2$$Register, $result$$Register,
-                      $tmp1$$XMMRegister, $tmp2$$Register);
+                      $cnt1$$Register, $cnt2$$Register,
+                      (-1), $result$$Register,
+                      $vec$$XMMRegister, $tmp$$Register);
   %}
   ins_pipe( pipe_slow );
 %}
--- a/src/cpu/zero/vm/cppInterpreter_zero.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/cpu/zero/vm/cppInterpreter_zero.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2007, 2008, 2009, 2010 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -281,7 +281,7 @@
 
     if (method->is_static()) {
       istate->set_oop_temp(
-        method->constants()->pool_holder()->klass_part()->java_mirror());
+        method->constants()->pool_holder()->java_mirror());
       mirror = istate->oop_temp_addr();
       *(dst++) = &mirror;
     }
@@ -667,7 +667,7 @@
       (BasicObjectLock *) stack->alloc(monitor_words * wordSize);
     oop object;
     if (method->is_static())
-      object = method->constants()->pool_holder()->klass_part()->java_mirror();
+      object = method->constants()->pool_holder()->java_mirror();
     else
       object = (oop) locals[0];
     monitor->set_obj(object);
--- a/src/os/linux/vm/os_linux.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/os/linux/vm/os_linux.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -2211,7 +2211,7 @@
   if (rp == NULL)
     return;
 
-  if (strcmp(Arguments::sun_java_launcher(), "gamma") == 0) {
+  if (Arguments::created_by_gamma_launcher()) {
     // Support for the gamma launcher.  Typical value for buf is
     // "<JAVA_HOME>/jre/lib/<arch>/<vmtype>/libjvm.so".  If "/jre/lib/" appears at
     // the right place in the string, then assume we are installed in a JDK and
--- a/src/os/posix/vm/os_posix.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/os/posix/vm/os_posix.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -59,3 +59,12 @@
   VMError::report_coredump_status(buffer, success);
 }
 
+bool os::is_debugger_attached() {
+  // not implemented
+  return false;
+}
+
+void os::wait_for_keypress_at_exit(void) {
+  // don't do anything on posix platforms
+  return;
+}
--- a/src/os/solaris/dtrace/libjvm_db.c	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/os/solaris/dtrace/libjvm_db.c	Mon Apr 04 19:23:29 2011 -0700
@@ -524,6 +524,8 @@
   CHECK_FAIL(err);
   err = read_pointer(J, constantPool + nameIndex * POINTER_SIZE + SIZE_constantPoolOopDesc, &nameSymbol);
   CHECK_FAIL(err);
+  // The symbol is a CPSlot and has lower bit set to indicate metadata
+  nameSymbol &= (~1); // remove metadata lsb
   err = ps_pread(J->P, nameSymbol + OFFSET_Symbol_length, &nameSymbolLength, 2);
   CHECK_FAIL(err);
   nameString = (char*)calloc(nameSymbolLength + 1, 1);
@@ -535,6 +537,7 @@
   CHECK_FAIL(err);
   err = read_pointer(J, constantPool + signatureIndex * POINTER_SIZE + SIZE_constantPoolOopDesc, &signatureSymbol);
   CHECK_FAIL(err);
+  signatureSymbol &= (~1);  // remove metadata lsb
   err = ps_pread(J->P, signatureSymbol + OFFSET_Symbol_length, &signatureSymbolLength, 2);
   CHECK_FAIL(err);
   signatureString = (char*)calloc(signatureSymbolLength + 1, 1);
--- a/src/os/solaris/vm/os_solaris.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/os/solaris/vm/os_solaris.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -2511,7 +2511,7 @@
   assert(ret != 0, "cannot locate libjvm");
   realpath((char *)dlinfo.dli_fname, buf);
 
-  if (strcmp(Arguments::sun_java_launcher(), "gamma") == 0) {
+  if (Arguments::created_by_gamma_launcher()) {
     // Support for the gamma launcher.  Typical value for buf is
     // "<JAVA_HOME>/jre/lib/<arch>/<vmtype>/libjvm.so".  If "/jre/lib/" appears at
     // the right place in the string, then assume we are installed in a JDK and
--- a/src/os/windows/vm/os_windows.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/os/windows/vm/os_windows.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -22,10 +22,8 @@
  *
  */
 
-#ifdef _WIN64
-// Must be at least Windows 2000 or XP to use VectoredExceptions
+// Must be at least Windows 2000 or XP to use VectoredExceptions and IsDebuggerPresent
 #define _WIN32_WINNT 0x500
-#endif
 
 // no precompiled headers
 #include "classfile/classLoader.hpp"
@@ -1788,7 +1786,7 @@
   }
 
   buf[0] = '\0';
-  if (strcmp(Arguments::sun_java_launcher(), "gamma") == 0) {
+  if (Arguments::created_by_gamma_launcher()) {
      // Support for the gamma launcher. Check for an
      // JAVA_HOME environment variable
      // and fix up the path so it looks like
@@ -3299,9 +3297,14 @@
          "possibility of dangling Thread pointer");
 
   OSThread* osthread = thread->osthread();
-  bool interrupted;
-  interrupted = osthread->interrupted();
-  if (clear_interrupted == true) {
+  bool interrupted = osthread->interrupted();
+  // There is no synchronization between the setting of the interrupt
+  // and it being cleared here. It is critical - see 6535709 - that
+  // we only clear the interrupt state, and reset the interrupt event,
+  // if we are going to report that we were indeed interrupted - else
+  // an interrupt can be "lost", leading to spurious wakeups or lost wakeups
+  // depending on the timing
+  if (interrupted && clear_interrupted) {
     osthread->set_interrupted(false);
     ResetEvent(osthread->interrupt_event());
   } // Otherwise leave the interrupted state alone
@@ -3418,6 +3421,19 @@
 }
 
 
+bool os::is_debugger_attached() {
+  return IsDebuggerPresent() ? true : false;
+}
+
+
+void os::wait_for_keypress_at_exit(void) {
+  if (PauseAtExit) {
+    fprintf(stderr, "Press any key to continue...\n");
+    fgetc(stdin);
+  }
+}
+
+
 int os::message_box(const char* title, const char* message) {
   int result = MessageBox(NULL, message, title,
                           MB_YESNO | MB_ICONERROR | MB_SYSTEMMODAL | MB_DEFAULT_DESKTOP_ONLY);
--- a/src/share/tools/hsdis/hsdis-demo.c	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/tools/hsdis/hsdis-demo.c	Mon Apr 04 19:23:29 2011 -0700
@@ -22,8 +22,6 @@
  *
  */
 
-#include "precompiled.hpp"
-
 /* hsdis-demo.c -- dump a range of addresses as native instructions
    This demonstrates the protocol required by the HotSpot PrintAssembly option.
 */
--- a/src/share/tools/hsdis/hsdis.c	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/tools/hsdis/hsdis.c	Mon Apr 04 19:23:29 2011 -0700
@@ -22,8 +22,6 @@
  *
  */
 
-#include "precompiled.hpp"
-
 /* hsdis.c -- dump a range of addresses as native instructions
    This implements the plugin protocol required by the
    HotSpot PrintAssembly option.
--- a/src/share/vm/c1/c1_Canonicalizer.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/c1/c1_Canonicalizer.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -209,7 +209,7 @@
     // limit this optimization to current block
     if (value != NULL && in_current_block(conv)) {
       set_canonical(new StoreField(x->obj(), x->offset(), x->field(), value, x->is_static(),
-                                       x->state_before(), x->is_loaded(), x->is_initialized()));
+                                   x->state_before(), x->needs_patching()));
       return;
     }
   }
--- a/src/share/vm/c1/c1_GraphBuilder.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/c1/c1_GraphBuilder.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -1456,12 +1456,12 @@
   BasicType field_type = field->type()->basic_type();
   ValueType* type = as_ValueType(field_type);
   // call will_link again to determine if the field is valid.
-  const bool is_loaded = holder->is_loaded() &&
-                         field->will_link(method()->holder(), code);
-  const bool is_initialized = is_loaded && holder->is_initialized();
+  const bool needs_patching = !holder->is_loaded() ||
+                              !field->will_link(method()->holder(), code) ||
+                              PatchALot;
 
   ValueStack* state_before = NULL;
-  if (!is_initialized || PatchALot) {
+  if (!holder->is_initialized() || needs_patching) {
     // save state before instruction for debug info when
     // deoptimization happens during patching
     state_before = copy_state_before();
@@ -1469,20 +1469,16 @@
 
   Value obj = NULL;
   if (code == Bytecodes::_getstatic || code == Bytecodes::_putstatic) {
-    // commoning of class constants should only occur if the class is
-    // fully initialized and resolved in this constant pool.  The will_link test
-    // above essentially checks if this class is resolved in this constant pool
-    // so, the is_initialized flag should be suffiect.
     if (state_before != NULL) {
       // build a patching constant
-      obj = new Constant(new ClassConstant(holder), state_before);
+      obj = new Constant(new InstanceConstant(holder->java_mirror()), state_before);
     } else {
-      obj = new Constant(new ClassConstant(holder));
+      obj = new Constant(new InstanceConstant(holder->java_mirror()));
     }
   }
 
 
-  const int offset = is_loaded ? field->offset() : -1;
+  const int offset = !needs_patching ? field->offset() : -1;
   switch (code) {
     case Bytecodes::_getstatic: {
       // check for compile-time constants, i.e., initialized static final fields
@@ -1509,7 +1505,7 @@
           state_before = copy_state_for_exception();
         }
         push(type, append(new LoadField(append(obj), offset, field, true,
-                                        state_before, is_loaded, is_initialized)));
+                                        state_before, needs_patching)));
       }
       break;
     }
@@ -1518,7 +1514,7 @@
         if (state_before == NULL) {
           state_before = copy_state_for_exception();
         }
-        append(new StoreField(append(obj), offset, field, val, true, state_before, is_loaded, is_initialized));
+        append(new StoreField(append(obj), offset, field, val, true, state_before, needs_patching));
       }
       break;
     case Bytecodes::_getfield :
@@ -1526,8 +1522,8 @@
         if (state_before == NULL) {
           state_before = copy_state_for_exception();
         }
-        LoadField* load = new LoadField(apop(), offset, field, false, state_before, is_loaded, true);
-        Value replacement = is_loaded ? _memory->load(load) : load;
+        LoadField* load = new LoadField(apop(), offset, field, false, state_before, needs_patching);
+        Value replacement = !needs_patching ? _memory->load(load) : load;
         if (replacement != load) {
           assert(replacement->is_linked() || !replacement->can_be_linked(), "should already by linked");
           push(type, replacement);
@@ -1542,8 +1538,8 @@
         if (state_before == NULL) {
           state_before = copy_state_for_exception();
         }
-        StoreField* store = new StoreField(apop(), offset, field, val, false, state_before, is_loaded, true);
-        if (is_loaded) store = _memory->store(store);
+        StoreField* store = new StoreField(apop(), offset, field, val, false, state_before, needs_patching);
+        if (!needs_patching) store = _memory->store(store);
         if (store != NULL) {
           append(store);
         }
@@ -3308,22 +3304,23 @@
   Value exception = append_with_bci(new ExceptionObject(), SynchronizationEntryBCI);
   assert(exception->is_pinned(), "must be");
 
+  int bci = SynchronizationEntryBCI;
   if (compilation()->env()->dtrace_method_probes()) {
-    // Report exit from inline methods
+    // Report exit from inline methods.  We don't have a stream here
+    // so pass an explicit bci of SynchronizationEntryBCI.
     Values* args = new Values(1);
-    args->push(append(new Constant(new ObjectConstant(method()))));
-    append(new RuntimeCall(voidType, "dtrace_method_exit", CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit), args));
+    args->push(append_with_bci(new Constant(new ObjectConstant(method())), bci));
+    append_with_bci(new RuntimeCall(voidType, "dtrace_method_exit", CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit), args), bci);
   }
 
-  int bci = SynchronizationEntryBCI;
   if (lock) {
     assert(state()->locks_size() > 0 && state()->lock_at(state()->locks_size() - 1) == lock, "lock is missing");
     if (!lock->is_linked()) {
-      lock = append_with_bci(lock, -1);
+      lock = append_with_bci(lock, bci);
     }
 
     // exit the monitor in the context of the synchronized method
-    monitorexit(lock, SynchronizationEntryBCI);
+    monitorexit(lock, bci);
 
     // exit the context of the synchronized method
     if (!default_handler) {
--- a/src/share/vm/c1/c1_Instruction.hpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/c1/c1_Instruction.hpp	Mon Apr 04 19:23:29 2011 -0700
@@ -323,8 +323,6 @@
     CanTrapFlag,
     DirectCompareFlag,
     IsEliminatedFlag,
-    IsInitializedFlag,
-    IsLoadedFlag,
     IsSafepointFlag,
     IsStaticFlag,
     IsStrictfpFlag,
@@ -693,7 +691,7 @@
  public:
   // creation
   AccessField(Value obj, int offset, ciField* field, bool is_static,
-              ValueStack* state_before, bool is_loaded, bool is_initialized)
+              ValueStack* state_before, bool needs_patching)
   : Instruction(as_ValueType(field->type()->basic_type()), state_before)
   , _obj(obj)
   , _offset(offset)
@@ -701,16 +699,9 @@
   , _explicit_null_check(NULL)
   {
     set_needs_null_check(!is_static);
-    set_flag(IsLoadedFlag, is_loaded);
-    set_flag(IsInitializedFlag, is_initialized);
     set_flag(IsStaticFlag, is_static);
+    set_flag(NeedsPatchingFlag, needs_patching);
     ASSERT_VALUES
-      if (!is_loaded || (PatchALot && !field->is_volatile())) {
-      // need to patch if the holder wasn't loaded or we're testing
-      // using PatchALot.  Don't allow PatchALot for fields which are
-      // known to be volatile they aren't patchable.
-      set_flag(NeedsPatchingFlag, true);
-    }
     // pin of all instructions with memory access
     pin();
   }
@@ -721,11 +712,14 @@
   ciField* field() const                         { return _field; }
   BasicType field_type() const                   { return _field->type()->basic_type(); }
   bool is_static() const                         { return check_flag(IsStaticFlag); }
-  bool is_loaded() const                         { return check_flag(IsLoadedFlag); }
-  bool is_initialized() const                    { return check_flag(IsInitializedFlag); }
   NullCheck* explicit_null_check() const         { return _explicit_null_check; }
   bool needs_patching() const                    { return check_flag(NeedsPatchingFlag); }
 
+  // Unresolved getstatic and putstatic can cause initialization.
+  // Technically it occurs at the Constant that materializes the base
+  // of the static fields but it's simpler to model it here.
+  bool is_init_point() const                     { return is_static() && (needs_patching() || !_field->holder()->is_initialized()); }
+
   // manipulation
 
   // Under certain circumstances, if a previous NullCheck instruction
@@ -745,15 +739,15 @@
  public:
   // creation
   LoadField(Value obj, int offset, ciField* field, bool is_static,
-            ValueStack* state_before, bool is_loaded, bool is_initialized)
-  : AccessField(obj, offset, field, is_static, state_before, is_loaded, is_initialized)
+            ValueStack* state_before, bool needs_patching)
+  : AccessField(obj, offset, field, is_static, state_before, needs_patching)
   {}
 
   ciType* declared_type() const;
   ciType* exact_type() const;
 
   // generic
-  HASHING2(LoadField, is_loaded() && !field()->is_volatile(), obj()->subst(), offset())  // cannot be eliminated if not yet loaded or if volatile
+  HASHING2(LoadField, !needs_patching() && !field()->is_volatile(), obj()->subst(), offset())  // cannot be eliminated if needs patching or if volatile
 };
 
 
@@ -764,8 +758,8 @@
  public:
   // creation
   StoreField(Value obj, int offset, ciField* field, Value value, bool is_static,
-             ValueStack* state_before, bool is_loaded, bool is_initialized)
-  : AccessField(obj, offset, field, is_static, state_before, is_loaded, is_initialized)
+             ValueStack* state_before, bool needs_patching)
+  : AccessField(obj, offset, field, is_static, state_before, needs_patching)
   , _value(value)
   {
     set_flag(NeedsWriteBarrierFlag, as_ValueType(field_type())->is_object());
--- a/src/share/vm/c1/c1_LIR.hpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/c1/c1_LIR.hpp	Mon Apr 04 19:23:29 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -1156,7 +1156,7 @@
     return
       is_invokedynamic()  // An invokedynamic is always a MethodHandle call site.
       ||
-      (method()->holder()->name() == ciSymbol::java_dyn_MethodHandle() &&
+      (method()->holder()->name() == ciSymbol::java_lang_invoke_MethodHandle() &&
        methodOopDesc::is_method_handle_invoke_name(method()->name()->sid()));
   }
 
--- a/src/share/vm/c1/c1_LIRGenerator.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/c1/c1_LIRGenerator.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -1559,9 +1559,7 @@
                 (info ? new CodeEmitInfo(info) : NULL));
   }
 
-  if (is_volatile) {
-    assert(!needs_patching && x->is_loaded(),
-           "how do we know it's volatile if it's not loaded");
+  if (is_volatile && !needs_patching) {
     volatile_field_store(value.result(), address, info);
   } else {
     LIR_PatchCode patch_code = needs_patching ? lir_patch_normal : lir_patch_none;
@@ -1627,9 +1625,7 @@
     address = generate_address(object.result(), x->offset(), field_type);
   }
 
-  if (is_volatile) {
-    assert(!needs_patching && x->is_loaded(),
-           "how do we know it's volatile if it's not loaded");
+  if (is_volatile && !needs_patching) {
     volatile_field_load(address, reg, info);
   } else {
     LIR_PatchCode patch_code = needs_patching ? lir_patch_normal : lir_patch_none;
@@ -2516,7 +2512,7 @@
       __ load(new LIR_Address(tmp, call_site_offset, T_OBJECT), tmp);
 
       // Load target MethodHandle from CallSite object.
-      __ load(new LIR_Address(tmp, java_dyn_CallSite::target_offset_in_bytes(), T_OBJECT), receiver);
+      __ load(new LIR_Address(tmp, java_lang_invoke_CallSite::target_offset_in_bytes(), T_OBJECT), receiver);
 
       __ call_dynamic(target, receiver, result_register,
                       SharedRuntime::get_resolve_opt_virtual_call_stub(),
--- a/src/share/vm/c1/c1_LinearScan.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/c1/c1_LinearScan.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -2703,7 +2703,7 @@
       assert(_fpu_stack_allocator != NULL, "must be present");
       opr = _fpu_stack_allocator->to_fpu_stack(opr);
 
-      assert(opr->fpu_regnrLo() == opr->fpu_regnrHi(), "assumed in calculation (only fpu_regnrHi is used)");
+      assert(opr->fpu_regnrLo() == opr->fpu_regnrHi(), "assumed in calculation (only fpu_regnrLo is used)");
 #endif
 #ifdef SPARC
       assert(opr->fpu_regnrLo() == opr->fpu_regnrHi() + 1, "assumed in calculation (only fpu_regnrHi is used)");
@@ -2715,7 +2715,12 @@
       assert(opr->fpu_regnrLo() == opr->fpu_regnrHi(), "assumed in calculation (only fpu_regnrHi is used)");
 #endif
 
+#ifdef VM_LITTLE_ENDIAN
+      VMReg rname_first = frame_map()->fpu_regname(opr->fpu_regnrLo());
+#else
       VMReg rname_first = frame_map()->fpu_regname(opr->fpu_regnrHi());
+#endif
+
 #ifdef _LP64
       first = new LocationValue(Location::new_reg_loc(Location::dbl, rname_first));
       second = &_int_0_scope_value;
--- a/src/share/vm/c1/c1_Runtime1.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/c1/c1_Runtime1.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -426,10 +426,9 @@
 // been deoptimized. If that is the case we return the deopt blob
 // unpack_with_exception entry instead. This makes life for the exception blob easier
 // because making that same check and diverting is painful from assembly language.
-//
-
-
 JRT_ENTRY_NO_ASYNC(static address, exception_handler_for_pc_helper(JavaThread* thread, oopDesc* ex, address pc, nmethod*& nm))
+  // Reset method handle flag.
+  thread->set_is_method_handle_return(false);
 
   Handle exception(thread, ex);
   nm = CodeCache::find_nmethod(pc);
@@ -480,11 +479,12 @@
     return SharedRuntime::deopt_blob()->unpack_with_exception_in_tls();
   }
 
-  // ExceptionCache is used only for exceptions at call and not for implicit exceptions
+  // ExceptionCache is used only for exceptions at call sites and not for implicit exceptions
   if (guard_pages_enabled) {
     address fast_continuation = nm->handler_for_exception_and_pc(exception, pc);
     if (fast_continuation != NULL) {
-      if (fast_continuation == ExceptionCache::unwind_handler()) fast_continuation = NULL;
+      // Set flag if return address is a method handle call site.
+      thread->set_is_method_handle_return(nm->is_method_handle_return(pc));
       return fast_continuation;
     }
   }
@@ -522,14 +522,14 @@
     thread->set_exception_pc(pc);
 
     // the exception cache is used only by non-implicit exceptions
-    if (continuation == NULL) {
-      nm->add_handler_for_exception_and_pc(exception, pc, ExceptionCache::unwind_handler());
-    } else {
+    if (continuation != NULL) {
       nm->add_handler_for_exception_and_pc(exception, pc, continuation);
     }
   }
 
   thread->set_vm_result(exception());
+  // Set flag if return address is a method handle call site.
+  thread->set_is_method_handle_return(nm->is_method_handle_return(pc));
 
   if (TraceExceptions) {
     ttyLocker ttyl;
@@ -542,20 +542,19 @@
 JRT_END
 
 // Enter this method from compiled code only if there is a Java exception handler
-// in the method handling the exception
+// in the method handling the exception.
 // We are entering here from exception stub. We don't do a normal VM transition here.
 // We do it in a helper. This is so we can check to see if the nmethod we have just
 // searched for an exception handler has been deoptimized in the meantime.
-address  Runtime1::exception_handler_for_pc(JavaThread* thread) {
+address Runtime1::exception_handler_for_pc(JavaThread* thread) {
   oop exception = thread->exception_oop();
   address pc = thread->exception_pc();
   // Still in Java mode
-  debug_only(ResetNoHandleMark rnhm);
+  DEBUG_ONLY(ResetNoHandleMark rnhm);
   nmethod* nm = NULL;
   address continuation = NULL;
   {
     // Enter VM mode by calling the helper
-
     ResetNoHandleMark rnhm;
     continuation = exception_handler_for_pc_helper(thread, exception, pc, nm);
   }
@@ -563,11 +562,11 @@
 
   // Now check to see if the nmethod we were called from is now deoptimized.
   // If so we must return to the deopt blob and deoptimize the nmethod
-
   if (nm != NULL && caller_is_deopted()) {
     continuation = SharedRuntime::deopt_blob()->unpack_with_exception_in_tls();
   }
 
+  assert(continuation != NULL, "no handler found");
   return continuation;
 }
 
@@ -809,7 +808,7 @@
         { klassOop klass = resolve_field_return_klass(caller_method, bci, CHECK);
           // Save a reference to the class that has to be checked for initialization
           init_klass = KlassHandle(THREAD, klass);
-          k = klass;
+          k = klass->java_mirror();
         }
         break;
       case Bytecodes::_new:
--- a/src/share/vm/c1/c1_Runtime1.hpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/c1/c1_Runtime1.hpp	Mon Apr 04 19:23:29 2011 -0700
@@ -54,6 +54,7 @@
   stub(new_multi_array)              \
   stub(handle_exception_nofpu)         /* optimized version that does not preserve fpu registers */ \
   stub(handle_exception)             \
+  stub(handle_exception_from_callee) \
   stub(throw_array_store_exception)  \
   stub(throw_class_cast_exception)   \
   stub(throw_incompatible_class_change_error)   \
@@ -116,11 +117,11 @@
   static const char* _blob_names[];
 
   // stub generation
-  static void generate_blob_for(BufferBlob* blob, StubID id);
-  static OopMapSet* generate_code_for(StubID id, StubAssembler* masm);
+  static void       generate_blob_for(BufferBlob* blob, StubID id);
+  static OopMapSet* generate_code_for(StubID id, StubAssembler* sasm);
   static OopMapSet* generate_exception_throw(StubAssembler* sasm, address target, bool has_argument);
-  static void generate_handle_exception(StubAssembler *sasm, OopMapSet* oop_maps, OopMap* oop_map, bool ignore_fpu_registers = false);
-  static void generate_unwind_exception(StubAssembler *sasm);
+  static OopMapSet* generate_handle_exception(StubID id, StubAssembler* sasm);
+  static void       generate_unwind_exception(StubAssembler *sasm);
   static OopMapSet* generate_patching(StubAssembler* sasm, address target);
 
   static OopMapSet* generate_stub_call(StubAssembler* sasm, Register result, address entry,
--- a/src/share/vm/c1/c1_ValueMap.hpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/c1/c1_ValueMap.hpp	Mon Apr 04 19:23:29 2011 -0700
@@ -141,7 +141,8 @@
 
   // visitor functions
   void do_StoreField     (StoreField*      x) {
-    if (!x->is_initialized()) {
+    if (x->is_init_point()) {
+      // putstatic is an initialization point so treat it as a wide kill
       kill_memory();
     } else {
       kill_field(x->field());
@@ -159,7 +160,8 @@
   void do_Local          (Local*           x) { /* nothing to do */ }
   void do_Constant       (Constant*        x) { /* nothing to do */ }
   void do_LoadField      (LoadField*       x) {
-    if (!x->is_initialized()) {
+    if (x->is_init_point()) {
+      // getstatic is an initialization point so treat it as a wide kill
       kill_memory();
     }
   }
--- a/src/share/vm/ci/ciCPCache.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/ci/ciCPCache.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -46,8 +46,7 @@
 // ciCPCache::is_f1_null_at
 bool ciCPCache::is_f1_null_at(int index) {
   VM_ENTRY_MARK;
-  oop f1 = entry_at(index)->f1();
-  return (f1 == NULL);
+  return entry_at(index)->is_f1_null();
 }
 
 
--- a/src/share/vm/ci/ciCallSite.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/ci/ciCallSite.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -34,7 +34,7 @@
 // Return the target MethodHandle of this CallSite.
 ciMethodHandle* ciCallSite::get_target() const {
   VM_ENTRY_MARK;
-  oop method_handle_oop = java_dyn_CallSite::target(get_oop());
+  oop method_handle_oop = java_lang_invoke_CallSite::target(get_oop());
   return CURRENT_ENV->get_object(method_handle_oop)->as_method_handle();
 }
 
--- a/src/share/vm/ci/ciCallSite.hpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/ci/ciCallSite.hpp	Mon Apr 04 19:23:29 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,7 +29,7 @@
 
 // ciCallSite
 //
-// The class represents a java.dyn.CallSite object.
+// The class represents a java.lang.invoke.CallSite object.
 class ciCallSite : public ciInstance {
 public:
   ciCallSite(instanceHandle h_i) : ciInstance(h_i) {}
--- a/src/share/vm/ci/ciField.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/ci/ciField.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -177,7 +177,7 @@
     // Never trust strangely unstable finals:  System.out, etc.
     return false;
   // Even if general trusting is disabled, trust system-built closures in these packages.
-  if (holder->is_in_package("java/dyn") || holder->is_in_package("sun/dyn"))
+  if (holder->is_in_package("java/lang/invoke") || holder->is_in_package("sun/invoke"))
     return true;
   return TrustFinalNonStaticFields;
 }
@@ -191,8 +191,9 @@
   // Check to see if the field is constant.
   if (_holder->is_initialized() && this->is_final()) {
     if (!this->is_static()) {
-      // A field can be constant if it's a final static field or if it's
-      // a final non-static field of a trusted class ({java,sun}.dyn).
+      // A field can be constant if it's a final static field or if
+      // it's a final non-static field of a trusted class (classes in
+      // java.lang.invoke and sun.invoke packages and subpackages).
       if (trust_final_non_static_fields(_holder)) {
         _is_constant = true;
         return;
@@ -212,7 +213,7 @@
     //    may change.  The three examples are java.lang.System.in,
     //    java.lang.System.out, and java.lang.System.err.
 
-    Handle k = _holder->get_klassOop();
+    KlassHandle k = _holder->get_klassOop();
     assert( SystemDictionary::System_klass() != NULL, "Check once per vm");
     if( k() == SystemDictionary::System_klass() ) {
       // Check offsets for case 2: System.in, System.out, or System.err
@@ -224,36 +225,38 @@
       }
     }
 
+    Handle mirror = k->java_mirror();
+
     _is_constant = true;
     switch(type()->basic_type()) {
     case T_BYTE:
-      _constant_value = ciConstant(type()->basic_type(), k->byte_field(_offset));
+      _constant_value = ciConstant(type()->basic_type(), mirror->byte_field(_offset));
       break;
     case T_CHAR:
-      _constant_value = ciConstant(type()->basic_type(), k->char_field(_offset));
+      _constant_value = ciConstant(type()->basic_type(), mirror->char_field(_offset));
       break;
     case T_SHORT:
-      _constant_value = ciConstant(type()->basic_type(), k->short_field(_offset));
+      _constant_value = ciConstant(type()->basic_type(), mirror->short_field(_offset));
       break;
     case T_BOOLEAN:
-      _constant_value = ciConstant(type()->basic_type(), k->bool_field(_offset));
+      _constant_value = ciConstant(type()->basic_type(), mirror->bool_field(_offset));
       break;
     case T_INT:
-      _constant_value = ciConstant(type()->basic_type(), k->int_field(_offset));
+      _constant_value = ciConstant(type()->basic_type(), mirror->int_field(_offset));
       break;
     case T_FLOAT:
-      _constant_value = ciConstant(k->float_field(_offset));
+      _constant_value = ciConstant(mirror->float_field(_offset));
       break;
     case T_DOUBLE:
-      _constant_value = ciConstant(k->double_field(_offset));
+      _constant_value = ciConstant(mirror->double_field(_offset));
       break;
     case T_LONG:
-      _constant_value = ciConstant(k->long_field(_offset));
+      _constant_value = ciConstant(mirror->long_field(_offset));
       break;
     case T_OBJECT:
     case T_ARRAY:
       {
-        oop o = k->obj_field(_offset);
+        oop o = mirror->obj_field(_offset);
 
         // A field will be "constant" if it is known always to be
         // a non-null reference to an instance of a particular class,
--- a/src/share/vm/ci/ciInstance.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/ci/ciInstance.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -138,3 +138,9 @@
   st->print(" type=");
   klass()->print(st);
 }
+
+
+ciKlass* ciInstance::java_lang_Class_klass() {
+  VM_ENTRY_MARK;
+  return CURRENT_ENV->get_object(java_lang_Class::as_klassOop(get_oop()))->as_klass();
+}
--- a/src/share/vm/ci/ciInstance.hpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/ci/ciInstance.hpp	Mon Apr 04 19:23:29 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -64,6 +64,8 @@
 
   // Constant value of a field at the specified offset.
   ciConstant field_value_by_offset(int field_offset);
+
+  ciKlass* java_lang_Class_klass();
 };
 
 #endif // SHARE_VM_CI_CIINSTANCE_HPP
--- a/src/share/vm/ci/ciInstanceKlass.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/ci/ciInstanceKlass.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -85,7 +85,6 @@
     if (h_k() != SystemDictionary::Object_klass()) {
       super();
     }
-    java_mirror();
     //compute_nonstatic_fields();  // done outside of constructor
   }
 
@@ -320,6 +319,9 @@
 // Get the instance of java.lang.Class corresponding to this klass.
 // Cache it on this->_java_mirror.
 ciInstance* ciInstanceKlass::java_mirror() {
+  if (is_shared()) {
+    return ciKlass::java_mirror();
+  }
   if (_java_mirror == NULL) {
     _java_mirror = ciKlass::java_mirror();
   }
--- a/src/share/vm/ci/ciMethod.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/ci/ciMethod.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -769,7 +769,7 @@
 // signature-polymorphic MethodHandle methods, invokeExact or invokeGeneric.
 bool ciMethod::is_method_handle_invoke() const {
   if (!is_loaded()) {
-    bool flag = (holder()->name() == ciSymbol::java_dyn_MethodHandle() &&
+    bool flag = (holder()->name() == ciSymbol::java_lang_invoke_MethodHandle() &&
                  methodOopDesc::is_method_handle_invoke_name(name()->sid()));
     return flag;
   }
--- a/src/share/vm/ci/ciMethodHandle.hpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/ci/ciMethodHandle.hpp	Mon Apr 04 19:23:29 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,7 +30,7 @@
 
 // ciMethodHandle
 //
-// The class represents a java.dyn.MethodHandle object.
+// The class represents a java.lang.invoke.MethodHandle object.
 class ciMethodHandle : public ciInstance {
 private:
   ciMethod* _callee;
--- a/src/share/vm/ci/ciObjectFactory.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/ci/ciObjectFactory.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -342,9 +342,9 @@
     return new (arena()) ciMethodData(h_md);
   } else if (o->is_instance()) {
     instanceHandle h_i(THREAD, (instanceOop)o);
-    if (java_dyn_CallSite::is_instance(o))
+    if (java_lang_invoke_CallSite::is_instance(o))
       return new (arena()) ciCallSite(h_i);
-    else if (java_dyn_MethodHandle::is_instance(o))
+    else if (java_lang_invoke_MethodHandle::is_instance(o))
       return new (arena()) ciMethodHandle(h_i);
     else
       return new (arena()) ciInstance(h_i);
@@ -663,7 +663,7 @@
   if (key->is_perm() && _non_perm_count == 0) {
     return emptyBucket;
   } else if (key->is_instance()) {
-    if (key->klass() == SystemDictionary::Class_klass()) {
+    if (key->klass() == SystemDictionary::Class_klass() && JavaObjectsInPerm) {
       // class mirror instances are always perm
       return emptyBucket;
     }
--- a/src/share/vm/ci/ciStreams.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/ci/ciStreams.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -380,7 +380,7 @@
   bool ignore;
   // report as InvokeDynamic for invokedynamic, which is syntactically classless
   if (cur_bc() == Bytecodes::_invokedynamic)
-    return CURRENT_ENV->get_klass_by_name(_holder, ciSymbol::java_dyn_InvokeDynamic(), false);
+    return CURRENT_ENV->get_klass_by_name(_holder, ciSymbol::java_lang_invoke_InvokeDynamic(), false);
   return CURRENT_ENV->get_klass_by_index(cpool, get_method_holder_index(), ignore, _holder);
 }
 
--- a/src/share/vm/classfile/classFileParser.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/classfile/classFileParser.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -37,6 +37,7 @@
 #include "memory/universe.inline.hpp"
 #include "oops/constantPoolOop.hpp"
 #include "oops/instanceKlass.hpp"
+#include "oops/instanceMirrorKlass.hpp"
 #include "oops/klass.inline.hpp"
 #include "oops/klassOop.hpp"
 #include "oops/klassVtable.hpp"
@@ -146,12 +147,14 @@
         break;
       case JVM_CONSTANT_MethodHandle :
       case JVM_CONSTANT_MethodType :
-        if (!EnableMethodHandles ||
-            _major_version < Verifier::INVOKEDYNAMIC_MAJOR_VERSION) {
+        if (_major_version < Verifier::INVOKEDYNAMIC_MAJOR_VERSION) {
           classfile_parse_error(
-            (!EnableMethodHandles ?
-             "This JVM does not support constant tag %u in class file %s" :
-             "Class file version does not support constant tag %u in class file %s"),
+            "Class file version does not support constant tag %u in class file %s",
+            tag, CHECK);
+        }
+        if (!EnableMethodHandles) {
+          classfile_parse_error(
+            "This JVM does not support constant tag %u in class file %s",
             tag, CHECK);
         }
         if (tag == JVM_CONSTANT_MethodHandle) {
@@ -170,12 +173,14 @@
       case JVM_CONSTANT_InvokeDynamicTrans :  // this tag appears only in old classfiles
       case JVM_CONSTANT_InvokeDynamic :
         {
-          if (!EnableInvokeDynamic ||
-              _major_version < Verifier::INVOKEDYNAMIC_MAJOR_VERSION) {
+          if (_major_version < Verifier::INVOKEDYNAMIC_MAJOR_VERSION) {
             classfile_parse_error(
-              (!EnableInvokeDynamic ?
-               "This JVM does not support constant tag %u in class file %s" :
-               "Class file version does not support constant tag %u in class file %s"),
+              "Class file version does not support constant tag %u in class file %s",
+              tag, CHECK);
+          }
+          if (!EnableInvokeDynamic) {
+            classfile_parse_error(
+              "This JVM does not support constant tag %u in class file %s",
               tag, CHECK);
           }
           cfs->guarantee_more(5, CHECK);  // bsm_index, nt, tag/access_flags
@@ -1616,8 +1621,13 @@
 
   AccessFlags access_flags;
   if (name == vmSymbols::class_initializer_name()) {
-    // We ignore the access flags for a class initializer. (JVM Spec. p. 116)
-    flags = JVM_ACC_STATIC;
+    // We ignore the other access flags for a valid class initializer.
+    // (JVM Spec 2nd ed., chapter 4.6)
+    if (_major_version < 51) { // backward compatibility
+      flags = JVM_ACC_STATIC;
+    } else if ((flags & JVM_ACC_STATIC) == JVM_ACC_STATIC) {
+      flags &= JVM_ACC_STATIC | JVM_ACC_STRICT;
+    }
   } else {
     verify_legal_method_modifiers(flags, is_interface, name, CHECK_(nullHandle));
   }
@@ -2597,54 +2607,6 @@
 }
 
 
-static void initialize_static_field(fieldDescriptor* fd, TRAPS) {
-  KlassHandle h_k (THREAD, fd->field_holder());
-  assert(h_k.not_null() && fd->is_static(), "just checking");
-  if (fd->has_initial_value()) {
-    BasicType t = fd->field_type();
-    switch (t) {
-      case T_BYTE:
-        h_k()->byte_field_put(fd->offset(), fd->int_initial_value());
-              break;
-      case T_BOOLEAN:
-        h_k()->bool_field_put(fd->offset(), fd->int_initial_value());
-              break;
-      case T_CHAR:
-        h_k()->char_field_put(fd->offset(), fd->int_initial_value());
-              break;
-      case T_SHORT:
-        h_k()->short_field_put(fd->offset(), fd->int_initial_value());
-              break;
-      case T_INT:
-        h_k()->int_field_put(fd->offset(), fd->int_initial_value());
-        break;
-      case T_FLOAT:
-        h_k()->float_field_put(fd->offset(), fd->float_initial_value());
-        break;
-      case T_DOUBLE:
-        h_k()->double_field_put(fd->offset(), fd->double_initial_value());
-        break;
-      case T_LONG:
-        h_k()->long_field_put(fd->offset(), fd->long_initial_value());
-        break;
-      case T_OBJECT:
-        {
-          #ifdef ASSERT
-          TempNewSymbol sym = SymbolTable::new_symbol("Ljava/lang/String;", CHECK);
-          assert(fd->signature() == sym, "just checking");
-          #endif
-          oop string = fd->string_initial_value(CHECK);
-          h_k()->obj_field_put(fd->offset(), string);
-        }
-        break;
-      default:
-        THROW_MSG(vmSymbols::java_lang_ClassFormatError(),
-                  "Illegal ConstantValue attribute in class file");
-    }
-  }
-}
-
-
 void ClassFileParser::java_lang_ref_Reference_fix_pre(typeArrayHandle* fields_ptr,
   constantPoolHandle cp, FieldAllocationCount *fac_ptr, TRAPS) {
   // This code is for compatibility with earlier jdk's that do not
@@ -2760,8 +2722,8 @@
 }
 
 
-void ClassFileParser::java_lang_Class_fix_pre(objArrayHandle* methods_ptr,
-  FieldAllocationCount *fac_ptr, TRAPS) {
+void ClassFileParser::java_lang_Class_fix_pre(int* nonstatic_field_size,
+                                              FieldAllocationCount *fac_ptr) {
   // Add fake fields for java.lang.Class instances
   //
   // This is not particularly nice. We should consider adding a
@@ -2778,10 +2740,13 @@
   // versions because when the offsets are computed at bootstrap
   // time we don't know yet which version of the JDK we're running in.
 
-  // The values below are fake but will force two non-static oop fields and
+  // The values below are fake but will force three non-static oop fields and
   // a corresponding non-static oop map block to be allocated.
   const int extra = java_lang_Class::number_of_fake_oop_fields;
   fac_ptr->nonstatic_oop_count += extra;
+
+  // Reserve some leading space for fake ints
+  *nonstatic_field_size += align_size_up(java_lang_Class::hc_number_of_fake_int_fields * BytesPerInt, heapOopSize) / heapOopSize;
 }
 
 
@@ -2797,11 +2762,11 @@
 
 // Force MethodHandle.vmentry to be an unmanaged pointer.
 // There is no way for a classfile to express this, so we must help it.
-void ClassFileParser::java_dyn_MethodHandle_fix_pre(constantPoolHandle cp,
+void ClassFileParser::java_lang_invoke_MethodHandle_fix_pre(constantPoolHandle cp,
                                                     typeArrayHandle fields,
                                                     FieldAllocationCount *fac_ptr,
                                                     TRAPS) {
-  // Add fake fields for java.dyn.MethodHandle instances
+  // Add fake fields for java.lang.invoke.MethodHandle instances
   //
   // This is not particularly nice, but since there is no way to express
   // a native wordSize field in Java, we must do it at this level.
@@ -2818,9 +2783,10 @@
     }
   }
 
+  if (AllowTransitionalJSR292 && word_sig_index == 0)  return;
   if (word_sig_index == 0)
     THROW_MSG(vmSymbols::java_lang_VirtualMachineError(),
-              "missing I or J signature (for vmentry) in java.dyn.MethodHandle");
+              "missing I or J signature (for vmentry) in java.lang.invoke.MethodHandle");
 
   // Find vmentry field and change the signature.
   bool found_vmentry = false;
@@ -2857,9 +2823,10 @@
     }
   }
 
+  if (AllowTransitionalJSR292 && !found_vmentry)  return;
   if (!found_vmentry)
     THROW_MSG(vmSymbols::java_lang_VirtualMachineError(),
-              "missing vmentry byte field in java.dyn.MethodHandle");
+              "missing vmentry byte field in java.lang.invoke.MethodHandle");
 }
 
 
@@ -3194,9 +3161,7 @@
     int next_nonstatic_field_offset;
 
     // Calculate the starting byte offsets
-    next_static_oop_offset      = (instanceKlass::header_size() +
-                                  align_object_offset(vtable_size) +
-                                  align_object_offset(itable_size)) * wordSize;
+    next_static_oop_offset      = instanceMirrorKlass::offset_of_static_fields();
     next_static_double_offset   = next_static_oop_offset +
                                   (fac.static_oop_count * heapOopSize);
     if ( fac.static_double_count &&
@@ -3215,18 +3180,28 @@
                                   fac.static_byte_count ), wordSize );
     static_field_size           = (next_static_type_offset -
                                   next_static_oop_offset) / wordSize;
+
+    // Add fake fields for java.lang.Class instances (also see below)
+    if (class_name == vmSymbols::java_lang_Class() && class_loader.is_null()) {
+      java_lang_Class_fix_pre(&nonstatic_field_size, &fac);
+    }
+
     first_nonstatic_field_offset = instanceOopDesc::base_offset_in_bytes() +
                                    nonstatic_field_size * heapOopSize;
     next_nonstatic_field_offset = first_nonstatic_field_offset;
 
-    // Add fake fields for java.lang.Class instances (also see below)
-    if (class_name == vmSymbols::java_lang_Class() && class_loader.is_null()) {
-      java_lang_Class_fix_pre(&methods, &fac, CHECK_(nullHandle));
+    // adjust the vmentry field declaration in java.lang.invoke.MethodHandle
+    if (EnableMethodHandles && class_name == vmSymbols::java_lang_invoke_MethodHandle() && class_loader.is_null()) {
+      java_lang_invoke_MethodHandle_fix_pre(cp, fields, &fac, CHECK_(nullHandle));
     }
-
-    // adjust the vmentry field declaration in java.dyn.MethodHandle
-    if (EnableMethodHandles && class_name == vmSymbols::sun_dyn_MethodHandleImpl() && class_loader.is_null()) {
-      java_dyn_MethodHandle_fix_pre(cp, fields, &fac, CHECK_(nullHandle));
+    if (AllowTransitionalJSR292 &&
+        EnableMethodHandles && class_name == vmSymbols::java_dyn_MethodHandle() && class_loader.is_null()) {
+      java_lang_invoke_MethodHandle_fix_pre(cp, fields, &fac, CHECK_(nullHandle));
+    }
+    if (AllowTransitionalJSR292 &&
+        EnableMethodHandles && class_name == vmSymbols::sun_dyn_MethodHandleImpl() && class_loader.is_null()) {
+      // allow vmentry field in MethodHandleImpl also
+      java_lang_invoke_MethodHandle_fix_pre(cp, fields, &fac, CHECK_(nullHandle));
     }
 
     // Add a fake "discovered" field if it is not present
@@ -3546,7 +3521,7 @@
     }
 
     // We can now create the basic klassOop for this klass
-    klassOop ik = oopFactory::new_instanceKlass(vtable_size, itable_size,
+    klassOop ik = oopFactory::new_instanceKlass(name, vtable_size, itable_size,
                                                 static_field_size,
                                                 total_oop_map_count,
                                                 rt, CHECK_(nullHandle));
@@ -3568,7 +3543,7 @@
     this_klass->set_class_loader(class_loader());
     this_klass->set_nonstatic_field_size(nonstatic_field_size);
     this_klass->set_has_nonstatic_fields(has_nonstatic_fields);
-    this_klass->set_static_oop_field_size(fac.static_oop_count);
+    this_klass->set_static_oop_field_count(fac.static_oop_count);
     cp->set_pool_holder(this_klass());
     error_handler.set_in_error(false);   // turn off error handler for cp
     this_klass->set_constants(cp());
@@ -3629,9 +3604,6 @@
     // Make sure this is the end of class file stream
     guarantee_property(cfs->at_eos(), "Extra bytes at the end of class file %s", CHECK_(nullHandle));
 
-    // Initialize static fields
-    this_klass->do_local_static_fields(&initialize_static_field, CHECK_(nullHandle));
-
     // VerifyOops believes that once this has been set, the object is completely loaded.
     // Compute transitive closure of interfaces this class implements
     this_klass->set_transitive_interfaces(transitive_interfaces());
@@ -3665,6 +3637,9 @@
       check_illegal_static_method(this_klass, CHECK_(nullHandle));
     }
 
+    // Allocate mirror and initialize static fields
+    java_lang_Class::create_mirror(this_klass, CHECK_(nullHandle));
+
     ClassLoadingService::notify_class_loaded(instanceKlass::cast(this_klass()),
                                              false /* not shared class */);
 
--- a/src/share/vm/classfile/classFileParser.hpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/classfile/classFileParser.hpp	Mon Apr 04 19:23:29 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -154,17 +154,18 @@
   // Add the "discovered" field to java.lang.ref.Reference if
   // it does not exist.
   void java_lang_ref_Reference_fix_pre(typeArrayHandle* fields_ptr,
-    constantPoolHandle cp, FieldAllocationCount *fac_ptr, TRAPS);
+                                       constantPoolHandle cp,
+                                       FieldAllocationCount *fac_ptr, TRAPS);
   // Adjust the field allocation counts for java.lang.Class to add
   // fake fields.
-  void java_lang_Class_fix_pre(objArrayHandle* methods_ptr,
-    FieldAllocationCount *fac_ptr, TRAPS);
+  void java_lang_Class_fix_pre(int* nonstatic_field_size,
+                               FieldAllocationCount *fac_ptr);
   // Adjust the next_nonstatic_oop_offset to place the fake fields
   // before any Java fields.
   void java_lang_Class_fix_post(int* next_nonstatic_oop_offset);
-  // Adjust the field allocation counts for java.dyn.MethodHandle to add
+  // Adjust the field allocation counts for java.lang.invoke.MethodHandle to add
   // a fake address (void*) field.
-  void java_dyn_MethodHandle_fix_pre(constantPoolHandle cp,
+  void java_lang_invoke_MethodHandle_fix_pre(constantPoolHandle cp,
                                      typeArrayHandle fields,
                                      FieldAllocationCount *fac_ptr, TRAPS);
 
--- a/src/share/vm/classfile/classLoader.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/classfile/classLoader.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -1335,7 +1335,7 @@
       }
 
       if (_compile_the_world_counter >= CompileTheWorldStartAt) {
-        if (k.is_null() || (exception_occurred && !CompileTheWorldIgnoreInitErrors)) {
+        if (k.is_null() || exception_occurred) {
           // If something went wrong (e.g. ExceptionInInitializerError) we skip this class
           tty->print_cr("CompileTheWorld (%d) : Skipping %s", _compile_the_world_counter, buffer);
         } else {
--- a/src/share/vm/classfile/javaClasses.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/classfile/javaClasses.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,6 +33,7 @@
 #include "memory/resourceArea.hpp"
 #include "memory/universe.inline.hpp"
 #include "oops/instanceKlass.hpp"
+#include "oops/instanceMirrorKlass.hpp"
 #include "oops/klass.hpp"
 #include "oops/klassOop.hpp"
 #include "oops/methodOop.hpp"
@@ -69,6 +70,28 @@
     return ik->find_local_field(name_symbol, signature_symbol, fd);
 }
 
+static bool find_hacked_field(instanceKlass* ik,
+                              Symbol* name_symbol, Symbol* signature_symbol,
+                              fieldDescriptor* fd,
+                              bool allow_super = false) {
+  bool found = find_field(ik, name_symbol, signature_symbol, fd, allow_super);
+  if (!found && AllowTransitionalJSR292) {
+    Symbol* backup_sig = SystemDictionary::find_backup_signature(signature_symbol);
+    if (backup_sig != NULL) {
+      found = find_field(ik, name_symbol, backup_sig, fd, allow_super);
+      if (TraceMethodHandles) {
+        ResourceMark rm;
+        tty->print_cr("MethodHandles: %s.%s: backup for %s => %s%s",
+                      ik->name()->as_C_string(), name_symbol->as_C_string(),
+                      signature_symbol->as_C_string(), backup_sig->as_C_string(),
+                      (found ? "" : " (NOT FOUND)"));
+      }
+    }
+  }
+  return found;
+}
+#define find_field find_hacked_field  /* remove after AllowTransitionalJSR292 */
+
 // Helpful routine for computing field offsets at run time rather than hardcoding them
 static void
 compute_offset(int &dest_offset,
@@ -142,7 +165,7 @@
 }
 
 Handle java_lang_String::create_tenured_from_unicode(jchar* unicode, int length, TRAPS) {
-  return basic_create_from_unicode(unicode, length, true, CHECK_NH);
+  return basic_create_from_unicode(unicode, length, JavaObjectsInPerm, CHECK_NH);
 }
 
 oop java_lang_String::create_oop_from_unicode(jchar* unicode, int length, TRAPS) {
@@ -372,6 +395,75 @@
   }
 }
 
+static void initialize_static_field(fieldDescriptor* fd, TRAPS) {
+  Handle mirror (THREAD, fd->field_holder()->java_mirror());
+  assert(mirror.not_null() && fd->is_static(), "just checking");
+  if (fd->has_initial_value()) {
+    BasicType t = fd->field_type();
+    switch (t) {
+      case T_BYTE:
+        mirror()->byte_field_put(fd->offset(), fd->int_initial_value());
+              break;
+      case T_BOOLEAN:
+        mirror()->bool_field_put(fd->offset(), fd->int_initial_value());
+              break;
+      case T_CHAR:
+        mirror()->char_field_put(fd->offset(), fd->int_initial_value());
+              break;
+      case T_SHORT:
+        mirror()->short_field_put(fd->offset(), fd->int_initial_value());
+              break;
+      case T_INT:
+        mirror()->int_field_put(fd->offset(), fd->int_initial_value());
+        break;
+      case T_FLOAT:
+        mirror()->float_field_put(fd->offset(), fd->float_initial_value());
+        break;
+      case T_DOUBLE:
+        mirror()->double_field_put(fd->offset(), fd->double_initial_value());
+        break;
+      case T_LONG:
+        mirror()->long_field_put(fd->offset(), fd->long_initial_value());
+        break;
+      case T_OBJECT:
+        {
+          #ifdef ASSERT
+          TempNewSymbol sym = SymbolTable::new_symbol("Ljava/lang/String;", CHECK);
+          assert(fd->signature() == sym, "just checking");
+          #endif
+          oop string = fd->string_initial_value(CHECK);
+          mirror()->obj_field_put(fd->offset(), string);
+        }
+        break;
+      default:
+        THROW_MSG(vmSymbols::java_lang_ClassFormatError(),
+                  "Illegal ConstantValue attribute in class file");
+    }
+  }
+}
+
+
+// During bootstrap, java.lang.Class wasn't loaded so static field
+// offsets were computed without the size added it.  Go back and
+// update all the static field offsets to included the size.
+static void fixup_static_field(fieldDescriptor* fd, TRAPS) {
+  if (fd->is_static()) {
+    int real_offset = fd->offset() + instanceMirrorKlass::offset_of_static_fields();
+    typeArrayOop fields = instanceKlass::cast(fd->field_holder())->fields();
+    fields->short_at_put(fd->index() + instanceKlass::low_offset,  extract_low_short_from_int(real_offset));
+    fields->short_at_put(fd->index() + instanceKlass::high_offset, extract_high_short_from_int(real_offset));
+  }
+}
+
+void java_lang_Class::fixup_mirror(KlassHandle k, TRAPS) {
+  assert(instanceMirrorKlass::offset_of_static_fields() != 0, "must have been computed already");
+
+  if (k->oop_is_instance()) {
+    // Fixup the offsets
+    instanceKlass::cast(k())->do_local_static_fields(&fixup_static_field, CHECK);
+  }
+  create_mirror(k, CHECK);
+}
 
 oop java_lang_Class::create_mirror(KlassHandle k, TRAPS) {
   assert(k->java_mirror() == NULL, "should only assign mirror once");
@@ -381,12 +473,17 @@
   // class is put into the system dictionary.
   int computed_modifiers = k->compute_modifier_flags(CHECK_0);
   k->set_modifier_flags(computed_modifiers);
-  if (SystemDictionary::Class_klass_loaded()) {
+  if (SystemDictionary::Class_klass_loaded() && (k->oop_is_instance() || k->oop_is_javaArray())) {
     // Allocate mirror (java.lang.Class instance)
-    Handle mirror = instanceKlass::cast(SystemDictionary::Class_klass())->allocate_permanent_instance(CHECK_0);
+    Handle mirror = instanceMirrorKlass::cast(SystemDictionary::Class_klass())->allocate_instance(k, CHECK_0);
     // Setup indirections
     mirror->obj_field_put(klass_offset,  k());
     k->set_java_mirror(mirror());
+
+    instanceMirrorKlass* mk = instanceMirrorKlass::cast(mirror->klass());
+    java_lang_Class::set_oop_size(mirror(), mk->instance_size(k));
+    java_lang_Class::set_static_oop_field_count(mirror(), mk->compute_static_oop_field_count(mirror()));
+
     // It might also have a component mirror.  This mirror must already exist.
     if (k->oop_is_javaArray()) {
       Handle comp_mirror;
@@ -409,6 +506,9 @@
         arrayKlass::cast(k->as_klassOop())->set_component_mirror(comp_mirror());
         set_array_klass(comp_mirror(), k->as_klassOop());
       }
+    } else if (k->oop_is_instance()) {
+      // Initialize static fields
+      instanceKlass::cast(k())->do_local_static_fields(&initialize_static_field, CHECK_NULL);
     }
     return mirror();
   } else {
@@ -417,21 +517,46 @@
 }
 
 
+
+int  java_lang_Class::oop_size(oop java_class) {
+  assert(oop_size_offset != 0, "must be set");
+  return java_class->int_field(oop_size_offset);
+}
+void java_lang_Class::set_oop_size(oop java_class, int size) {
+  assert(oop_size_offset != 0, "must be set");
+  java_class->int_field_put(oop_size_offset, size);
+}
+int  java_lang_Class::static_oop_field_count(oop java_class) {
+  assert(static_oop_field_count_offset != 0, "must be set");
+  return java_class->int_field(static_oop_field_count_offset);
+}
+void java_lang_Class::set_static_oop_field_count(oop java_class, int size) {
+  assert(static_oop_field_count_offset != 0, "must be set");
+  java_class->int_field_put(static_oop_field_count_offset, size);
+}
+
+
+
+
 oop java_lang_Class::create_basic_type_mirror(const char* basic_type_name, BasicType type, TRAPS) {
   // This should be improved by adding a field at the Java level or by
   // introducing a new VM klass (see comment in ClassFileParser)
-  oop java_class = instanceKlass::cast(SystemDictionary::Class_klass())->allocate_permanent_instance(CHECK_0);
+  oop java_class = instanceMirrorKlass::cast(SystemDictionary::Class_klass())->allocate_instance((oop)NULL, CHECK_0);
   if (type != T_VOID) {
     klassOop aklass = Universe::typeArrayKlassObj(type);
     assert(aklass != NULL, "correct bootstrap");
     set_array_klass(java_class, aklass);
   }
+  instanceMirrorKlass* mk = instanceMirrorKlass::cast(SystemDictionary::Class_klass());
+  java_lang_Class::set_oop_size(java_class, mk->instance_size(oop(NULL)));
+  java_lang_Class::set_static_oop_field_count(java_class, 0);
   return java_class;
 }
 
 
 klassOop java_lang_Class::as_klassOop(oop java_class) {
   //%note memory_2
+  assert(java_lang_Class::is_instance(java_class), "must be a Class object");
   klassOop k = klassOop(java_class->obj_field(klass_offset));
   assert(k == NULL || k->is_klass(), "type check");
   return k;
@@ -2133,7 +2258,7 @@
 // Support for java_lang_ref_Reference
 oop java_lang_ref_Reference::pending_list_lock() {
   instanceKlass* ik = instanceKlass::cast(SystemDictionary::Reference_klass());
-  char *addr = (((char *)ik->start_of_static_fields()) + static_lock_offset);
+  address addr = ik->static_field_addr(static_lock_offset);
   if (UseCompressedOops) {
     return oopDesc::load_decode_heap_oop((narrowOop *)addr);
   } else {
@@ -2143,7 +2268,7 @@
 
 HeapWord *java_lang_ref_Reference::pending_list_addr() {
   instanceKlass* ik = instanceKlass::cast(SystemDictionary::Reference_klass());
-  char *addr = (((char *)ik->start_of_static_fields()) + static_pending_offset);
+  address addr = ik->static_field_addr(static_pending_offset);
   // XXX This might not be HeapWord aligned, almost rather be char *.
   return (HeapWord*)addr;
 }
@@ -2166,54 +2291,54 @@
 
 jlong java_lang_ref_SoftReference::clock() {
   instanceKlass* ik = instanceKlass::cast(SystemDictionary::SoftReference_klass());
-  int offset = ik->offset_of_static_fields() + static_clock_offset;
-
-  return SystemDictionary::SoftReference_klass()->long_field(offset);
+  jlong* offset = (jlong*)ik->static_field_addr(static_clock_offset);
+  return *offset;
 }
 
 void java_lang_ref_SoftReference::set_clock(jlong value) {
   instanceKlass* ik = instanceKlass::cast(SystemDictionary::SoftReference_klass());
-  int offset = ik->offset_of_static_fields() + static_clock_offset;
-
-  SystemDictionary::SoftReference_klass()->long_field_put(offset, value);
+  jlong* offset = (jlong*)ik->static_field_addr(static_clock_offset);
+  *offset = value;
 }
 
 
-// Support for java_dyn_MethodHandle
-
-int java_dyn_MethodHandle::_type_offset;
-int java_dyn_MethodHandle::_vmtarget_offset;
-int java_dyn_MethodHandle::_vmentry_offset;
-int java_dyn_MethodHandle::_vmslots_offset;
-
-int sun_dyn_MemberName::_clazz_offset;
-int sun_dyn_MemberName::_name_offset;
-int sun_dyn_MemberName::_type_offset;
-int sun_dyn_MemberName::_flags_offset;
-int sun_dyn_MemberName::_vmtarget_offset;
-int sun_dyn_MemberName::_vmindex_offset;
-
-int sun_dyn_DirectMethodHandle::_vmindex_offset;
-
-int sun_dyn_BoundMethodHandle::_argument_offset;
-int sun_dyn_BoundMethodHandle::_vmargslot_offset;
-
-int sun_dyn_AdapterMethodHandle::_conversion_offset;
-
-void java_dyn_MethodHandle::compute_offsets() {
+// Support for java_lang_invoke_MethodHandle
+
+int java_lang_invoke_MethodHandle::_type_offset;
+int java_lang_invoke_MethodHandle::_vmtarget_offset;
+int java_lang_invoke_MethodHandle::_vmentry_offset;
+int java_lang_invoke_MethodHandle::_vmslots_offset;
+
+int java_lang_invoke_MemberName::_clazz_offset;
+int java_lang_invoke_MemberName::_name_offset;
+int java_lang_invoke_MemberName::_type_offset;
+int java_lang_invoke_MemberName::_flags_offset;
+int java_lang_invoke_MemberName::_vmtarget_offset;
+int java_lang_invoke_MemberName::_vmindex_offset;
+
+int java_lang_invoke_DirectMethodHandle::_vmindex_offset;
+
+int java_lang_invoke_BoundMethodHandle::_argument_offset;
+int java_lang_invoke_BoundMethodHandle::_vmargslot_offset;
+
+int java_lang_invoke_AdapterMethodHandle::_conversion_offset;
+
+void java_lang_invoke_MethodHandle::compute_offsets() {
   klassOop k = SystemDictionary::MethodHandle_klass();
   if (k != NULL && EnableMethodHandles) {
-    compute_offset(_type_offset,      k, vmSymbols::type_name(),      vmSymbols::java_dyn_MethodType_signature(), true);
-    compute_offset(_vmtarget_offset,  k, vmSymbols::vmtarget_name(),  vmSymbols::object_signature(), true);
-    compute_offset(_vmentry_offset,   k, vmSymbols::vmentry_name(),   vmSymbols::machine_word_signature(), true);
+    bool allow_super = false;
+    if (AllowTransitionalJSR292)  allow_super = true;  // temporary, to access java.dyn.MethodHandleImpl
+    compute_offset(_type_offset,      k, vmSymbols::type_name(),      vmSymbols::java_lang_invoke_MethodType_signature(), allow_super);
+    compute_offset(_vmtarget_offset,  k, vmSymbols::vmtarget_name(),  vmSymbols::object_signature(),                      allow_super);
+    compute_offset(_vmentry_offset,   k, vmSymbols::vmentry_name(),   vmSymbols::machine_word_signature(),                allow_super);
 
     // Note:  MH.vmslots (if it is present) is a hoisted copy of MH.type.form.vmslots.
     // It is optional pending experiments to keep or toss.
-    compute_optional_offset(_vmslots_offset, k, vmSymbols::vmslots_name(), vmSymbols::int_signature(), true);
+    compute_optional_offset(_vmslots_offset, k, vmSymbols::vmslots_name(), vmSymbols::int_signature(), allow_super);
   }
 }
 
-void sun_dyn_MemberName::compute_offsets() {
+void java_lang_invoke_MemberName::compute_offsets() {
   klassOop k = SystemDictionary::MemberName_klass();
   if (k != NULL && EnableMethodHandles) {
     compute_offset(_clazz_offset,     k, vmSymbols::clazz_name(),     vmSymbols::class_signature());
@@ -2225,14 +2350,14 @@
   }
 }
 
-void sun_dyn_DirectMethodHandle::compute_offsets() {
+void java_lang_invoke_DirectMethodHandle::compute_offsets() {
   klassOop k = SystemDictionary::DirectMethodHandle_klass();
   if (k != NULL && EnableMethodHandles) {
     compute_offset(_vmindex_offset,   k, vmSymbols::vmindex_name(),   vmSymbols::int_signature(),    true);
   }
 }
 
-void sun_dyn_BoundMethodHandle::compute_offsets() {
+void java_lang_invoke_BoundMethodHandle::compute_offsets() {
   klassOop k = SystemDictionary::BoundMethodHandle_klass();
   if (k != NULL && EnableMethodHandles) {
     compute_offset(_vmargslot_offset, k, vmSymbols::vmargslot_name(), vmSymbols::int_signature(),    true);
@@ -2240,22 +2365,22 @@
   }
 }
 
-void sun_dyn_AdapterMethodHandle::compute_offsets() {
+void java_lang_invoke_AdapterMethodHandle::compute_offsets() {
   klassOop k = SystemDictionary::AdapterMethodHandle_klass();
   if (k != NULL && EnableMethodHandles) {
     compute_offset(_conversion_offset, k, vmSymbols::conversion_name(), vmSymbols::int_signature(), true);
   }
 }
 
-oop java_dyn_MethodHandle::type(oop mh) {
+oop java_lang_invoke_MethodHandle::type(oop mh) {
   return mh->obj_field(_type_offset);
 }
 
-void java_dyn_MethodHandle::set_type(oop mh, oop mtype) {
+void java_lang_invoke_MethodHandle::set_type(oop mh, oop mtype) {
   mh->obj_field_put(_type_offset, mtype);
 }
 
-int java_dyn_MethodHandle::vmslots(oop mh) {
+int java_lang_invoke_MethodHandle::vmslots(oop mh) {
   int vmslots_offset = _vmslots_offset;
   if (vmslots_offset != 0) {
 #ifdef ASSERT
@@ -2270,7 +2395,7 @@
 }
 
 // if MH.vmslots exists, hoist into it the value of type.form.vmslots
-void java_dyn_MethodHandle::init_vmslots(oop mh) {
+void java_lang_invoke_MethodHandle::init_vmslots(oop mh) {
   int vmslots_offset = _vmslots_offset;
   if (vmslots_offset != 0) {
     mh->int_field_put(vmslots_offset, compute_vmslots(mh));
@@ -2279,20 +2404,20 @@
 
 // fetch type.form.vmslots, which is the number of JVM stack slots
 // required to carry the arguments of this MH
-int java_dyn_MethodHandle::compute_vmslots(oop mh) {
+int java_lang_invoke_MethodHandle::compute_vmslots(oop mh) {
   oop mtype = type(mh);
   if (mtype == NULL)  return 0;  // Java code would get NPE
-  oop form = java_dyn_MethodType::form(mtype);
+  oop form = java_lang_invoke_MethodType::form(mtype);
   if (form == NULL)   return 0;  // Java code would get NPE
-  return java_dyn_MethodTypeForm::vmslots(form);
+  return java_lang_invoke_MethodTypeForm::vmslots(form);
 }
 
 // fetch the low-level entry point for this mh
-MethodHandleEntry* java_dyn_MethodHandle::vmentry(oop mh) {
+MethodHandleEntry* java_lang_invoke_MethodHandle::vmentry(oop mh) {
   return (MethodHandleEntry*) mh->address_field(_vmentry_offset);
 }
 
-void java_dyn_MethodHandle::set_vmentry(oop mh, MethodHandleEntry* me) {
+void java_lang_invoke_MethodHandle::set_vmentry(oop mh, MethodHandleEntry* me) {
   assert(_vmentry_offset != 0, "must be present");
 
   // This is always the final step that initializes a valid method handle:
@@ -2306,123 +2431,123 @@
 
 /// MemberName accessors
 
-oop sun_dyn_MemberName::clazz(oop mname) {
+oop java_lang_invoke_MemberName::clazz(oop mname) {
   assert(is_instance(mname), "wrong type");
   return mname->obj_field(_clazz_offset);
 }
 
-void sun_dyn_MemberName::set_clazz(oop mname, oop clazz) {
+void java_lang_invoke_MemberName::set_clazz(oop mname, oop clazz) {
   assert(is_instance(mname), "wrong type");
   mname->obj_field_put(_clazz_offset, clazz);
 }
 
-oop sun_dyn_MemberName::name(oop mname) {
+oop java_lang_invoke_MemberName::name(oop mname) {
   assert(is_instance(mname), "wrong type");
   return mname->obj_field(_name_offset);
 }
 
-void sun_dyn_MemberName::set_name(oop mname, oop name) {
+void java_lang_invoke_MemberName::set_name(oop mname, oop name) {
   assert(is_instance(mname), "wrong type");
   mname->obj_field_put(_name_offset, name);
 }
 
-oop sun_dyn_MemberName::type(oop mname) {
+oop java_lang_invoke_MemberName::type(oop mname) {
   assert(is_instance(mname), "wrong type");
   return mname->obj_field(_type_offset);
 }
 
-void sun_dyn_MemberName::set_type(oop mname, oop type) {
+void java_lang_invoke_MemberName::set_type(oop mname, oop type) {
   assert(is_instance(mname), "wrong type");
   mname->obj_field_put(_type_offset, type);
 }
 
-int sun_dyn_MemberName::flags(oop mname) {
+int java_lang_invoke_MemberName::flags(oop mname) {
   assert(is_instance(mname), "wrong type");
   return mname->int_field(_flags_offset);
 }
 
-void sun_dyn_MemberName::set_flags(oop mname, int flags) {
+void java_lang_invoke_MemberName::set_flags(oop mname, int flags) {
   assert(is_instance(mname), "wrong type");
   mname->int_field_put(_flags_offset, flags);
 }
 
-oop sun_dyn_MemberName::vmtarget(oop mname) {
+oop java_lang_invoke_MemberName::vmtarget(oop mname) {
   assert(is_instance(mname), "wrong type");
   return mname->obj_field(_vmtarget_offset);
 }
 
-void sun_dyn_MemberName::set_vmtarget(oop mname, oop ref) {
+void java_lang_invoke_MemberName::set_vmtarget(oop mname, oop ref) {
   assert(is_instance(mname), "wrong type");
   mname->obj_field_put(_vmtarget_offset, ref);
 }
 
-int sun_dyn_MemberName::vmindex(oop mname) {
+int java_lang_invoke_MemberName::vmindex(oop mname) {
   assert(is_instance(mname), "wrong type");
   return mname->int_field(_vmindex_offset);
 }
 
-void sun_dyn_MemberName::set_vmindex(oop mname, int index) {
+void java_lang_invoke_MemberName::set_vmindex(oop mname, int index) {
   assert(is_instance(mname), "wrong type");
   mname->int_field_put(_vmindex_offset, index);
 }
 
-oop java_dyn_MethodHandle::vmtarget(oop mh) {
+oop java_lang_invoke_MethodHandle::vmtarget(oop mh) {
   assert(is_instance(mh), "MH only");
   return mh->obj_field(_vmtarget_offset);
 }
 
-void java_dyn_MethodHandle::set_vmtarget(oop mh, oop ref) {
+void java_lang_invoke_MethodHandle::set_vmtarget(oop mh, oop ref) {
   assert(is_instance(mh), "MH only");
   mh->obj_field_put(_vmtarget_offset, ref);
 }
 
-int sun_dyn_DirectMethodHandle::vmindex(oop mh) {
+int java_lang_invoke_DirectMethodHandle::vmindex(oop mh) {
   assert(is_instance(mh), "DMH only");
   return mh->int_field(_vmindex_offset);
 }
 
-void sun_dyn_DirectMethodHandle::set_vmindex(oop mh, int index) {
+void java_lang_invoke_DirectMethodHandle::set_vmindex(oop mh, int index) {
   assert(is_instance(mh), "DMH only");
   mh->int_field_put(_vmindex_offset, index);
 }
 
-int sun_dyn_BoundMethodHandle::vmargslot(oop mh) {
+int java_lang_invoke_BoundMethodHandle::vmargslot(oop mh) {
   assert(is_instance(mh), "BMH only");
   return mh->int_field(_vmargslot_offset);
 }
 
-oop sun_dyn_BoundMethodHandle::argument(oop mh) {
+oop java_lang_invoke_BoundMethodHandle::argument(oop mh) {
   assert(is_instance(mh), "BMH only");
   return mh->obj_field(_argument_offset);
 }
 
-int sun_dyn_AdapterMethodHandle::conversion(oop mh) {
+int java_lang_invoke_AdapterMethodHandle::conversion(oop mh) {
   assert(is_instance(mh), "AMH only");
   return mh->int_field(_conversion_offset);
 }
 
-void sun_dyn_AdapterMethodHandle::set_conversion(oop mh, int conv) {
+void java_lang_invoke_AdapterMethodHandle::set_conversion(oop mh, int conv) {
   assert(is_instance(mh), "AMH only");
   mh->int_field_put(_conversion_offset, conv);
 }
 
 
-// Support for java_dyn_MethodType
-
-int java_dyn_MethodType::_rtype_offset;
-int java_dyn_MethodType::_ptypes_offset;
-int java_dyn_MethodType::_form_offset;
-
-void java_dyn_MethodType::compute_offsets() {
+// Support for java_lang_invoke_MethodType
+
+int java_lang_invoke_MethodType::_rtype_offset;
+int java_lang_invoke_MethodType::_ptypes_offset;
+int java_lang_invoke_MethodType::_form_offset;
+
+void java_lang_invoke_MethodType::compute_offsets() {
   klassOop k = SystemDictionary::MethodType_klass();
   if (k != NULL) {
     compute_offset(_rtype_offset,  k, vmSymbols::rtype_name(),  vmSymbols::class_signature());
     compute_offset(_ptypes_offset, k, vmSymbols::ptypes_name(), vmSymbols::class_array_signature());
-    compute_offset(_form_offset,   k, vmSymbols::form_name(),   vmSymbols::java_dyn_MethodTypeForm_signature());
+    compute_offset(_form_offset,   k, vmSymbols::form_name(),   vmSymbols::java_lang_invoke_MethodTypeForm_signature());
   }
 }
 
-void java_dyn_MethodType::print_signature(oop mt, outputStream* st) {
+void java_lang_invoke_MethodType::print_signature(oop mt, outputStream* st) {
   st->print("(");
   objArrayOop pts = ptypes(mt);
   for (int i = 0, limit = pts->length(); i < limit; i++) {
@@ -2432,7 +2557,7 @@
   java_lang_Class::print_signature(rtype(mt), st);
 }
 
-Symbol* java_dyn_MethodType::as_signature(oop mt, bool intern_if_not_found, TRAPS) {
+Symbol* java_lang_invoke_MethodType::as_signature(oop mt, bool intern_if_not_found, TRAPS) {
   ResourceMark rm;
   stringStream buffer(128);
   print_signature(mt, &buffer);
@@ -2447,103 +2572,83 @@
   return name;
 }
 
-oop java_dyn_MethodType::rtype(oop mt) {
+oop java_lang_invoke_MethodType::rtype(oop mt) {
   assert(is_instance(mt), "must be a MethodType");
   return mt->obj_field(_rtype_offset);
 }
 
-objArrayOop java_dyn_MethodType::ptypes(oop mt) {
+objArrayOop java_lang_invoke_MethodType::ptypes(oop mt) {
   assert(is_instance(mt), "must be a MethodType");
   return (objArrayOop) mt->obj_field(_ptypes_offset);
 }
 
-oop java_dyn_MethodType::form(oop mt) {
+oop java_lang_invoke_MethodType::form(oop mt) {
   assert(is_instance(mt), "must be a MethodType");
   return mt->obj_field(_form_offset);
 }
 
-oop java_dyn_MethodType::ptype(oop mt, int idx) {
+oop java_lang_invoke_MethodType::ptype(oop mt, int idx) {
   return ptypes(mt)->obj_at(idx);
 }
 
-int java_dyn_MethodType::ptype_count(oop mt) {
+int java_lang_invoke_MethodType::ptype_count(oop mt) {
   return ptypes(mt)->length();
 }
 
 
 
-// Support for java_dyn_MethodTypeForm
-
-int java_dyn_MethodTypeForm::_vmslots_offset;
-int java_dyn_MethodTypeForm::_erasedType_offset;
-int java_dyn_MethodTypeForm::_genericInvoker_offset;
-
-void java_dyn_MethodTypeForm::compute_offsets() {
+// Support for java_lang_invoke_MethodTypeForm
+
+int java_lang_invoke_MethodTypeForm::_vmslots_offset;
+int java_lang_invoke_MethodTypeForm::_erasedType_offset;
+int java_lang_invoke_MethodTypeForm::_genericInvoker_offset;
+
+void java_lang_invoke_MethodTypeForm::compute_offsets() {
   klassOop k = SystemDictionary::MethodTypeForm_klass();
   if (k != NULL) {
     compute_optional_offset(_vmslots_offset,    k, vmSymbols::vmslots_name(),    vmSymbols::int_signature(), true);
-    compute_optional_offset(_erasedType_offset, k, vmSymbols::erasedType_name(), vmSymbols::java_dyn_MethodType_signature(), true);
-    compute_optional_offset(_genericInvoker_offset, k, vmSymbols::genericInvoker_name(), vmSymbols::java_dyn_MethodHandle_signature(), true);
+    compute_optional_offset(_erasedType_offset, k, vmSymbols::erasedType_name(), vmSymbols::java_lang_invoke_MethodType_signature(), true);
+    compute_optional_offset(_genericInvoker_offset, k, vmSymbols::genericInvoker_name(), vmSymbols::java_lang_invoke_MethodHandle_signature(), true);
     if (_genericInvoker_offset == 0)  _genericInvoker_offset = -1;  // set to explicit "empty" value
   }
 }
 
-int java_dyn_MethodTypeForm::vmslots(oop mtform) {
+int java_lang_invoke_MethodTypeForm::vmslots(oop mtform) {
   assert(mtform->klass() == SystemDictionary::MethodTypeForm_klass(), "MTForm only");
   return mtform->int_field(_vmslots_offset);
 }
 
-oop java_dyn_MethodTypeForm::erasedType(oop mtform) {
+oop java_lang_invoke_MethodTypeForm::erasedType(oop mtform) {
   assert(mtform->klass() == SystemDictionary::MethodTypeForm_klass(), "MTForm only");
   return mtform->obj_field(_erasedType_offset);
 }
 
-oop java_dyn_MethodTypeForm::genericInvoker(oop mtform) {
+oop java_lang_invoke_MethodTypeForm::genericInvoker(oop mtform) {
   assert(mtform->klass() == SystemDictionary::MethodTypeForm_klass(), "MTForm only");
   return mtform->obj_field(_genericInvoker_offset);
 }
 
 
-// Support for java_dyn_CallSite
-
-int java_dyn_CallSite::_target_offset;
-int java_dyn_CallSite::_caller_method_offset;
-int java_dyn_CallSite::_caller_bci_offset;
-
-void java_dyn_CallSite::compute_offsets() {
+// Support for java_lang_invoke_CallSite
+
+int java_lang_invoke_CallSite::_target_offset;
+
+void java_lang_invoke_CallSite::compute_offsets() {
   if (!EnableInvokeDynamic)  return;
   klassOop k = SystemDictionary::CallSite_klass();
   if (k != NULL) {
-    compute_offset(_target_offset, k, vmSymbols::target_name(), vmSymbols::java_dyn_MethodHandle_signature());
-    compute_offset(_caller_method_offset, k, vmSymbols::vmmethod_name(), vmSymbols::sun_dyn_MemberName_signature());
-    compute_offset(_caller_bci_offset, k, vmSymbols::vmindex_name(), vmSymbols::int_signature());
+    compute_offset(_target_offset, k, vmSymbols::target_name(), vmSymbols::java_lang_invoke_MethodHandle_signature());
   }
 }
 
-oop java_dyn_CallSite::target(oop site) {
+oop java_lang_invoke_CallSite::target(oop site) {
   return site->obj_field(_target_offset);
 }
 
-void java_dyn_CallSite::set_target(oop site, oop target) {
+void java_lang_invoke_CallSite::set_target(oop site, oop target) {
   site->obj_field_put(_target_offset, target);
 }
 
-oop java_dyn_CallSite::caller_method(oop site) {
-  return site->obj_field(_caller_method_offset);
-}
-
-void java_dyn_CallSite::set_caller_method(oop site, oop ref) {
-  site->obj_field_put(_caller_method_offset, ref);
-}
-
-jint java_dyn_CallSite::caller_bci(oop site) {
-  return site->int_field(_caller_bci_offset);
-}
-
-void java_dyn_CallSite::set_caller_bci(oop site, jint bci) {
-  site->int_field_put(_caller_bci_offset, bci);
-}
-
 
 // Support for java_security_AccessControlContext
 
@@ -2624,26 +2729,18 @@
 
 
 // Support for java_lang_System
-
-void java_lang_System::compute_offsets() {
-  assert(offset_of_static_fields == 0, "offsets should be initialized only once");
-
-  instanceKlass* ik = instanceKlass::cast(SystemDictionary::System_klass());
-  offset_of_static_fields = ik->offset_of_static_fields();
+int java_lang_System::in_offset_in_bytes() {
+  return (instanceMirrorKlass::offset_of_static_fields() + static_in_offset);
 }
 
-int java_lang_System::in_offset_in_bytes() {
-  return (offset_of_static_fields + static_in_offset);
+
+int java_lang_System::out_offset_in_bytes() {
+  return (instanceMirrorKlass::offset_of_static_fields() + static_out_offset);
 }
 
 
-int java_lang_System::out_offset_in_bytes() {
-  return (offset_of_static_fields + static_out_offset);
-}
-
-
 int java_lang_System::err_offset_in_bytes() {
-  return (offset_of_static_fields + static_err_offset);
+  return (instanceMirrorKlass::offset_of_static_fields() + static_err_offset);
 }
 
 
@@ -2656,6 +2753,8 @@
 int java_lang_Class::array_klass_offset;
 int java_lang_Class::resolved_constructor_offset;
 int java_lang_Class::number_of_fake_oop_fields;
+int java_lang_Class::oop_size_offset;
+int java_lang_Class::static_oop_field_count_offset;
 int java_lang_Throwable::backtrace_offset;
 int java_lang_Throwable::detailMessage_offset;
 int java_lang_Throwable::cause_offset;
@@ -2699,7 +2798,6 @@
 int java_lang_ref_SoftReference::timestamp_offset;
 int java_lang_ref_SoftReference::static_clock_offset;
 int java_lang_ClassLoader::parent_offset;
-int java_lang_System::offset_of_static_fields;
 int java_lang_System::static_in_offset;
 int java_lang_System::static_out_offset;
 int java_lang_System::static_err_offset;
@@ -2816,10 +2914,19 @@
   java_lang_String::count_offset  = java_lang_String::offset_offset + sizeof (jint);
   java_lang_String::hash_offset   = java_lang_String::count_offset + sizeof (jint);
 
-  // Do the Class Class
-  java_lang_Class::klass_offset = java_lang_Class::hc_klass_offset * x + header;
-  java_lang_Class::array_klass_offset = java_lang_Class::hc_array_klass_offset * x + header;
-  java_lang_Class::resolved_constructor_offset = java_lang_Class::hc_resolved_constructor_offset * x + header;
+  {
+    // Do the Class Class
+    int offset = header;
+    java_lang_Class::oop_size_offset = header;
+    offset += BytesPerInt;
+    java_lang_Class::static_oop_field_count_offset = offset;
+    offset = align_size_up(offset + BytesPerInt, x);
+    java_lang_Class::klass_offset = offset;
+    offset += x;
+    java_lang_Class::array_klass_offset = offset;
+    offset += x;
+    java_lang_Class::resolved_constructor_offset = offset;
+  }
 
   // This is NOT an offset
   java_lang_Class::number_of_fake_oop_fields = java_lang_Class::hc_number_of_fake_oop_fields;
@@ -2876,20 +2983,19 @@
 void JavaClasses::compute_offsets() {
 
   java_lang_Class::compute_offsets();
-  java_lang_System::compute_offsets();
   java_lang_Thread::compute_offsets();
   java_lang_ThreadGroup::compute_offsets();
   if (EnableMethodHandles) {
-    java_dyn_MethodHandle::compute_offsets();
-    sun_dyn_MemberName::compute_offsets();
-    sun_dyn_DirectMethodHandle::compute_offsets();
-    sun_dyn_BoundMethodHandle::compute_offsets();
-    sun_dyn_AdapterMethodHandle::compute_offsets();
-    java_dyn_MethodType::compute_offsets();
-    java_dyn_MethodTypeForm::compute_offsets();
+    java_lang_invoke_MethodHandle::compute_offsets();
+    java_lang_invoke_MemberName::compute_offsets();
+    java_lang_invoke_DirectMethodHandle::compute_offsets();
+    java_lang_invoke_BoundMethodHandle::compute_offsets();
+    java_lang_invoke_AdapterMethodHandle::compute_offsets();
+    java_lang_invoke_MethodType::compute_offsets();
+    java_lang_invoke_MethodTypeForm::compute_offsets();
   }
   if (EnableInvokeDynamic) {
-    java_dyn_CallSite::compute_offsets();
+    java_lang_invoke_CallSite::compute_offsets();
   }
   java_security_AccessControlContext::compute_offsets();
   // Initialize reflection classes. The layouts of these classes
@@ -2960,10 +3066,10 @@
     tty->print_cr("Static field %s.%s appears to be nonstatic", klass_name, field_name);
     return false;
   }
-  if (fd.offset() == hardcoded_offset + h_klass->offset_of_static_fields()) {
+  if (fd.offset() == hardcoded_offset + instanceMirrorKlass::offset_of_static_fields()) {
     return true;
   } else {
-    tty->print_cr("Offset of static field %s.%s is hardcoded as %d but should really be %d.", klass_name, field_name, hardcoded_offset, fd.offset() - h_klass->offset_of_static_fields());
+    tty->print_cr("Offset of static field %s.%s is hardcoded as %d but should really be %d.", klass_name, field_name, hardcoded_offset, fd.offset() - instanceMirrorKlass::offset_of_static_fields());
     return false;
   }
 }
--- a/src/share/vm/classfile/javaClasses.hpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/classfile/javaClasses.hpp	Mon Apr 04 19:23:29 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -138,10 +138,8 @@
   // The fake offsets are added by the class loader when java.lang.Class is loaded
 
   enum {
-    hc_klass_offset                = 0,
-    hc_array_klass_offset          = 1,
-    hc_resolved_constructor_offset = 2,
-    hc_number_of_fake_oop_fields   = 3
+    hc_number_of_fake_oop_fields   = 3,
+    hc_number_of_fake_int_fields   = 2
   };
 
   static int klass_offset;
@@ -149,6 +147,9 @@
   static int array_klass_offset;
   static int number_of_fake_oop_fields;
 
+  static int oop_size_offset;
+  static int static_oop_field_count_offset;
+
   static void compute_offsets();
   static bool offsets_computed;
   static int classRedefinedCount_offset;
@@ -157,6 +158,7 @@
  public:
   // Instance creation
   static oop  create_mirror(KlassHandle k, TRAPS);
+  static void fixup_mirror(KlassHandle k, TRAPS);
   static oop  create_basic_type_mirror(const char* basic_type_name, BasicType type, TRAPS);
   // Conversion
   static klassOop as_klassOop(oop java_class);
@@ -191,6 +193,12 @@
   static void set_classRedefinedCount(oop the_class_mirror, int value);
   // Support for parallelCapable field
   static bool parallelCapable(oop the_class_mirror);
+
+  static int oop_size(oop java_class);
+  static void set_oop_size(oop java_class, int size);
+  static int static_oop_field_count(oop java_class);
+  static void set_static_oop_field_count(oop java_class, int size);
+
   // Debugging
   friend class JavaClasses;
   friend class instanceKlass;   // verification code accesses offsets
@@ -794,11 +802,11 @@
 };
 
 
-// Interface to java.dyn.MethodHandle objects
+// Interface to java.lang.invoke.MethodHandle objects
 
 class MethodHandleEntry;
 
-class java_dyn_MethodHandle: AllStatic {
+class java_lang_invoke_MethodHandle: AllStatic {
   friend class JavaClasses;
 
  private:
@@ -839,7 +847,7 @@
   static int vmslots_offset_in_bytes()          { return _vmslots_offset; }
 };
 
-class sun_dyn_DirectMethodHandle: public java_dyn_MethodHandle {
+class java_lang_invoke_DirectMethodHandle: public java_lang_invoke_MethodHandle {
   friend class JavaClasses;
 
  private:
@@ -864,7 +872,7 @@
   static int vmindex_offset_in_bytes()          { return _vmindex_offset; }
 };
 
-class sun_dyn_BoundMethodHandle: public java_dyn_MethodHandle {
+class java_lang_invoke_BoundMethodHandle: public java_lang_invoke_MethodHandle {
   friend class JavaClasses;
 
  private:
@@ -891,7 +899,7 @@
   static int vmargslot_offset_in_bytes()        { return _vmargslot_offset; }
 };
 
-class sun_dyn_AdapterMethodHandle: public sun_dyn_BoundMethodHandle {
+class java_lang_invoke_AdapterMethodHandle: public java_lang_invoke_BoundMethodHandle {
   friend class JavaClasses;
 
  private:
@@ -942,14 +950,14 @@
 };
 
 
-// Interface to sun.dyn.MemberName objects
+// Interface to java.lang.invoke.MemberName objects
 // (These are a private interface for Java code to query the class hierarchy.)
 
-class sun_dyn_MemberName: AllStatic {
+class java_lang_invoke_MemberName: AllStatic {
   friend class JavaClasses;
 
  private:
-  // From java.dyn.MemberName:
+  // From java.lang.invoke.MemberName:
   //    private Class<?>   clazz;       // class in which the method is defined
   //    private String     name;        // may be null if not yet materialized
   //    private Object     type;        // may be null if not yet materialized
@@ -1018,9 +1026,9 @@
 };
 
 
-// Interface to java.dyn.MethodType objects
+// Interface to java.lang.invoke.MethodType objects
 
-class java_dyn_MethodType: AllStatic {
+class java_lang_invoke_MethodType: AllStatic {
   friend class JavaClasses;
 
  private:
@@ -1052,7 +1060,7 @@
   static int form_offset_in_bytes()             { return _form_offset; }
 };
 
-class java_dyn_MethodTypeForm: AllStatic {
+class java_lang_invoke_MethodTypeForm: AllStatic {
   friend class JavaClasses;
 
  private:
@@ -1075,9 +1083,9 @@
 };
 
 
-// Interface to java.dyn.CallSite objects
+// Interface to java.lang.invoke.CallSite objects
 
-class java_dyn_CallSite: AllStatic {
+class java_lang_invoke_CallSite: AllStatic {
   friend class JavaClasses;
 
 private:
@@ -1165,13 +1173,10 @@
    hc_static_err_offset = 2
   };
 
-  static int offset_of_static_fields;
   static int  static_in_offset;
   static int static_out_offset;
   static int static_err_offset;
 
-  static void compute_offsets();
-
  public:
   static int  in_offset_in_bytes();
   static int out_offset_in_bytes();
--- a/src/share/vm/classfile/stackMapFrame.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/classfile/stackMapFrame.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -170,6 +170,44 @@
   return true;
 }
 
+bool StackMapFrame::has_flag_match_exception(
+    const StackMapFrame* target) const {
+  // We allow flags of {UninitThis} to assign to {} if-and-only-if the
+  // target frame does not depend upon the current type.
+  // This is slightly too strict, as we need only enforce that the
+  // slots that were initialized by the <init> (the things that were
+  // UninitializedThis before initialize_object() converted them) are unused.
+  // However we didn't save that information so we'll enforce this upon
+  // anything that might have been initialized.  This is a rare situation
+  // and javac never generates code that would end up here, but some profilers
+  // (such as NetBeans) might, when adding exception handlers in <init>
+  // methods to cover the invokespecial instruction.  See 7020118.
+
+  assert(max_locals() == target->max_locals() &&
+         stack_size() == target->stack_size(), "StackMap sizes must match");
+
+  VerificationType top = VerificationType::top_type();
+  VerificationType this_type = verifier()->current_type();
+
+  if (!flag_this_uninit() || target->flags() != 0) {
+    return false;
+  }
+
+  for (int i = 0; i < target->locals_size(); ++i) {
+    if (locals()[i] == this_type && target->locals()[i] != top) {
+      return false;
+    }
+  }
+
+  for (int i = 0; i < target->stack_size(); ++i) {
+    if (stack()[i] == this_type && target->stack()[i] != top) {
+      return false;
+    }
+  }
+
+  return true;
+}
+
 bool StackMapFrame::is_assignable_to(const StackMapFrame* target, TRAPS) const {
   if (_max_locals != target->max_locals() || _stack_size != target->stack_size()) {
     return false;
@@ -182,7 +220,9 @@
   bool match_stack = is_assignable_to(
     _stack, target->stack(), _stack_size, CHECK_false);
   bool match_flags = (_flags | target->flags()) == target->flags();
-  return (match_locals && match_stack && match_flags);
+
+  return match_locals && match_stack &&
+    (match_flags || has_flag_match_exception(target));
 }
 
 VerificationType StackMapFrame::pop_stack_ex(VerificationType type, TRAPS) {
--- a/src/share/vm/classfile/stackMapFrame.hpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/classfile/stackMapFrame.hpp	Mon Apr 04 19:23:29 2011 -0700
@@ -228,6 +228,8 @@
   bool is_assignable_to(
     VerificationType* src, VerificationType* target, int32_t len, TRAPS) const;
 
+  bool has_flag_match_exception(const StackMapFrame* target) const;
+
   // Debugging
   void print() const PRODUCT_RETURN;
 };
--- a/src/share/vm/classfile/symbolTable.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/classfile/symbolTable.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -88,7 +88,7 @@
 void SymbolTable::unlink() {
   int removed = 0;
   int total = 0;
-  int memory_total = 0;
+  size_t memory_total = 0;
   for (int i = 0; i < the_table()->table_size(); ++i) {
     for (HashtableEntry<Symbol*>** p = the_table()->bucket_addr(i); *p != NULL; ) {
       HashtableEntry<Symbol*>* entry = *p;
@@ -112,8 +112,10 @@
   }
   symbols_removed += removed;
   symbols_counted += total;
-  if (PrintGCDetails) {
-    gclog_or_tty->print(" [Symbols=%d size=%dK] ", total,
+  // Exclude printing for normal PrintGCDetails because people parse
+  // this output.
+  if (PrintGCDetails && Verbose && WizardMode) {
+    gclog_or_tty->print(" [Symbols=%d size=" SIZE_FORMAT "K] ", total,
                         (memory_total*HeapWordSize)/1024);
   }
 }
@@ -528,7 +530,7 @@
 
   Handle string;
   // try to reuse the string if possible
-  if (!string_or_null.is_null() && string_or_null()->is_perm()) {
+  if (!string_or_null.is_null() && (!JavaObjectsInPerm || string_or_null()->is_perm())) {
     string = string_or_null;
   } else {
     string = java_lang_String::create_tenured_from_unicode(name, len, CHECK_NULL);
@@ -660,7 +662,7 @@
     for ( ; p != NULL; p = p->next()) {
       oop s = p->literal();
       guarantee(s != NULL, "interned string is NULL");
-      guarantee(s->is_perm(), "interned string not in permspace");
+      guarantee(s->is_perm() || !JavaObjectsInPerm, "interned string not in permspace");
 
       int length;
       jchar* chars = java_lang_String::as_unicode_string(s, length);
--- a/src/share/vm/classfile/symbolTable.hpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/classfile/symbolTable.hpp	Mon Apr 04 19:23:29 2011 -0700
@@ -216,18 +216,14 @@
   oop basic_add(int index, Handle string_or_null, jchar* name, int len,
                 unsigned int hashValue, TRAPS);
 
-  // Table size
-  enum {
-    string_table_size = 1009
-  };
-
   oop lookup(int index, jchar* chars, int length, unsigned int hashValue);
 
-  StringTable() : Hashtable<oop>(string_table_size, sizeof (HashtableEntry<oop>)) {}
+  StringTable() : Hashtable<oop>((int)StringTableSize,
+                                 sizeof (HashtableEntry<oop>)) {}
 
   StringTable(HashtableBucket* t, int number_of_entries)
-    : Hashtable<oop>(string_table_size, sizeof (HashtableEntry<oop>), t,
-                number_of_entries) {}
+    : Hashtable<oop>((int)StringTableSize, sizeof (HashtableEntry<oop>), t,
+                     number_of_entries) {}
 
 public:
   // The string table
@@ -241,7 +237,7 @@
   static void create_table(HashtableBucket* t, int length,
                            int number_of_entries) {
     assert(_the_table == NULL, "One string table allowed.");
-    assert(length == string_table_size * sizeof(HashtableBucket),
+    assert((size_t)length == StringTableSize * sizeof(HashtableBucket),
            "bad shared string size.");
     _the_table = new StringTable(t, number_of_entries);
   }
--- a/src/share/vm/classfile/systemDictionary.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/classfile/systemDictionary.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -1887,27 +1887,99 @@
   0
 };
 
+Symbol* SystemDictionary::find_backup_symbol(Symbol* symbol,
+                                             const char* from_prefix,
+                                             const char* to_prefix) {
+  assert(AllowTransitionalJSR292, "");  // delete this subroutine
+  Symbol* backup_symbol = NULL;
+  size_t from_len = strlen(from_prefix);
+  if (strncmp((const char*) symbol->base(), from_prefix, from_len) != 0)
+    return NULL;
+  char buf[100];
+  size_t to_len = strlen(to_prefix);
+  size_t tail_len = symbol->utf8_length() - from_len;
+  size_t new_len = to_len + tail_len;
+  guarantee(new_len < sizeof(buf), "buf too small");
+  memcpy(buf, to_prefix, to_len);
+  memcpy(buf + to_len, symbol->base() + from_len, tail_len);
+  buf[new_len] = '\0';
+  vmSymbols::SID backup_sid = vmSymbols::find_sid(buf);
+  if (backup_sid != vmSymbols::NO_SID) {
+    backup_symbol = vmSymbols::symbol_at(backup_sid);
+  }
+  return backup_symbol;
+}
+
+Symbol* SystemDictionary::find_backup_class_name(Symbol* symbol) {
+  assert(AllowTransitionalJSR292, "");  // delete this subroutine
+  if (symbol == NULL)  return NULL;
+  Symbol* backup_symbol = find_backup_symbol(symbol, "java/lang/invoke/", "java/dyn/");  // AllowTransitionalJSR292 ONLY
+  if (backup_symbol == NULL)
+    backup_symbol = find_backup_symbol(symbol, "java/dyn/", "sun/dyn/");  // AllowTransitionalJSR292 ONLY
+  return backup_symbol;
+}
+
+Symbol* SystemDictionary::find_backup_signature(Symbol* symbol) {
+  assert(AllowTransitionalJSR292, "");  // delete this subroutine
+  if (symbol == NULL)  return NULL;
+  return find_backup_symbol(symbol, "Ljava/lang/invoke/", "Ljava/dyn/");
+}
+
 bool SystemDictionary::initialize_wk_klass(WKID id, int init_opt, TRAPS) {
   assert(id >= (int)FIRST_WKID && id < (int)WKID_LIMIT, "oob");
   int  info = wk_init_info[id - FIRST_WKID];
   int  sid  = (info >> CEIL_LG_OPTION_LIMIT);
   Symbol* symbol = vmSymbols::symbol_at((vmSymbols::SID)sid);
   klassOop*    klassp = &_well_known_klasses[id];
-  bool must_load = (init_opt < SystemDictionary::Opt);
-  bool try_load  = true;
+  bool pre_load = (init_opt < SystemDictionary::Opt);
+  bool try_load = true;
   if (init_opt == SystemDictionary::Opt_Kernel) {
 #ifndef KERNEL
     try_load = false;
 #endif //KERNEL
   }
-  if ((*klassp) == NULL && try_load) {
+  Symbol* backup_symbol = NULL;  // symbol to try if the current symbol fails
+  if (init_opt == SystemDictionary::Pre_JSR292) {
+    if (!EnableMethodHandles)  try_load = false;  // do not bother to load such classes
+    if (AllowTransitionalJSR292) {
+      backup_symbol = find_backup_class_name(symbol);
+      if (try_load && PreferTransitionalJSR292) {
+        while (backup_symbol != NULL) {
+          (*klassp) = resolve_or_null(backup_symbol, CHECK_0); // try backup early
+          if (TraceMethodHandles) {
+            ResourceMark rm;
+            tty->print_cr("MethodHandles: try backup first for %s => %s (%s)",
+                          symbol->as_C_string(), backup_symbol->as_C_string(),
+                          ((*klassp) == NULL) ? "no such class" : "backup load succeeded");
+          }
+          if ((*klassp) != NULL)  return true;
+          backup_symbol = find_backup_class_name(backup_symbol);  // find next backup
+        }
+      }
+    }
+  }
+  if ((*klassp) != NULL)  return true;
+  if (!try_load)          return false;
+  while (symbol != NULL) {
+    bool must_load = (pre_load && (backup_symbol == NULL));
     if (must_load) {
       (*klassp) = resolve_or_fail(symbol, true, CHECK_0); // load required class
     } else {
       (*klassp) = resolve_or_null(symbol,       CHECK_0); // load optional klass
     }
+    if ((*klassp) != NULL)  return true;
+    // Go around again.  Example of long backup sequence:
+    // java.lang.invoke.MemberName, java.dyn.MemberName, sun.dyn.MemberName, ONLY if AllowTransitionalJSR292
+    if (TraceMethodHandles && (backup_symbol != NULL)) {
+      ResourceMark rm;
+      tty->print_cr("MethodHandles: backup for %s => %s",
+                    symbol->as_C_string(), backup_symbol->as_C_string());
+    }
+    symbol = backup_symbol;
+    if (AllowTransitionalJSR292)
+      backup_symbol = find_backup_class_name(symbol);
   }
-  return ((*klassp) != NULL);
+  return false;
 }
 
 void SystemDictionary::initialize_wk_klasses_until(WKID limit_id, WKID &start_id, TRAPS) {
@@ -2348,6 +2420,8 @@
     if (THREAD->is_Compiler_thread())
       return NULL;              // do not attempt from within compiler
     bool for_invokeGeneric = (name_id == vmSymbols::VM_SYMBOL_ENUM_NAME(invokeGeneric_name));
+    if (AllowInvokeForInvokeGeneric && name_id == vmSymbols::VM_SYMBOL_ENUM_NAME(invoke_name))
+      for_invokeGeneric = true;
     bool found_on_bcp = false;
     Handle mt = find_method_handle_type(signature, accessing_klass,
                                         for_invokeGeneric,
@@ -2376,7 +2450,7 @@
   }
 }
 
-// Ask Java code to find or construct a java.dyn.MethodType for the given
+// Ask Java code to find or construct a java.lang.invoke.MethodType for the given
 // signature, as interpreted relative to the given class loader.
 // Because of class loader constraints, all method handle usage must be
 // consistent with this loader.
@@ -2430,25 +2504,33 @@
   }
   assert(arg == npts, "");
 
-  // call sun.dyn.MethodHandleNatives::findMethodType(Class rt, Class[] pts) -> MethodType
+  // call java.lang.invoke.MethodHandleNatives::findMethodType(Class rt, Class[] pts) -> MethodType
   JavaCallArguments args(Handle(THREAD, rt()));
   args.push_oop(pts());
   JavaValue result(T_OBJECT);
+  Symbol* findMethodHandleType_signature = vmSymbols::findMethodHandleType_signature();
+  if (AllowTransitionalJSR292 && SystemDictionaryHandles::MethodType_klass()->name() == vmSymbols::java_dyn_MethodType()) {
+    findMethodHandleType_signature = vmSymbols::findMethodHandleType_TRANS_signature();
+  }
   JavaCalls::call_static(&result,
                          SystemDictionary::MethodHandleNatives_klass(),
                          vmSymbols::findMethodHandleType_name(),
-                         vmSymbols::findMethodHandleType_signature(),
+                         findMethodHandleType_signature,
                          &args, CHECK_(empty));
   Handle method_type(THREAD, (oop) result.get_jobject());
 
   if (for_invokeGeneric) {
-    // call sun.dyn.MethodHandleNatives::notifyGenericMethodType(MethodType) -> void
+    // call java.lang.invoke.MethodHandleNatives::notifyGenericMethodType(MethodType) -> void
     JavaCallArguments args(Handle(THREAD, method_type()));
     JavaValue no_result(T_VOID);
+    Symbol* notifyGenericMethodType_signature = vmSymbols::notifyGenericMethodType_signature();
+    if (AllowTransitionalJSR292 && SystemDictionaryHandles::MethodType_klass()->name() == vmSymbols::java_dyn_MethodType()) {
+      notifyGenericMethodType_signature = vmSymbols::notifyGenericMethodType_TRANS_signature();
+    }
     JavaCalls::call_static(&no_result,
                            SystemDictionary::MethodHandleNatives_klass(),
                            vmSymbols::notifyGenericMethodType_name(),
-                           vmSymbols::notifyGenericMethodType_signature(),
+                           notifyGenericMethodType_signature,
                            &args, THREAD);
     if (HAS_PENDING_EXCEPTION) {
       // If the notification fails, just kill it.
@@ -2489,7 +2571,7 @@
     THROW_MSG_(vmSymbols::java_lang_LinkageError(), "bad signature", empty);
   }
 
-  // call sun.dyn.MethodHandleNatives::linkMethodHandleConstant(Class caller, int refKind, Class callee, String name, Object type) -> MethodHandle
+  // call java.lang.invoke.MethodHandleNatives::linkMethodHandleConstant(Class caller, int refKind, Class callee, String name, Object type) -> MethodHandle
   JavaCallArguments args;
   args.push_oop(caller->java_mirror());  // the referring class
   args.push_int(ref_kind);
@@ -2497,15 +2579,19 @@
   args.push_oop(name());
   args.push_oop(type());
   JavaValue result(T_OBJECT);
+  Symbol* linkMethodHandleConstant_signature = vmSymbols::linkMethodHandleConstant_signature();
+  if (AllowTransitionalJSR292 && SystemDictionaryHandles::MethodHandle_klass()->name() == vmSymbols::java_dyn_MethodHandle()) {
+    linkMethodHandleConstant_signature = vmSymbols::linkMethodHandleConstant_TRANS_signature();
+  }
   JavaCalls::call_static(&result,
                          SystemDictionary::MethodHandleNatives_klass(),
                          vmSymbols::linkMethodHandleConstant_name(),
-                         vmSymbols::linkMethodHandleConstant_signature(),
+                         linkMethodHandleConstant_signature,
                          &args, CHECK_(empty));
   return Handle(THREAD, (oop) result.get_jobject());
 }
 
-// Ask Java code to find or construct a java.dyn.CallSite for the given
+// Ask Java code to find or construct a java.lang.invoke.CallSite for the given
 // name and signature, as interpreted relative to the given class loader.
 Handle SystemDictionary::make_dynamic_call_site(Handle bootstrap_method,
                                                 Symbol* name,
@@ -2516,13 +2602,13 @@
                                                 TRAPS) {
   Handle empty;
   guarantee(bootstrap_method.not_null() &&
-            java_dyn_MethodHandle::is_instance(bootstrap_method()),
+            java_lang_invoke_MethodHandle::is_instance(bootstrap_method()),
             "caller must supply a valid BSM");
 
   Handle caller_mname = MethodHandles::new_MemberName(CHECK_(empty));
   MethodHandles::init_MemberName(caller_mname(), caller_method());
 
-  // call sun.dyn.MethodHandleNatives::makeDynamicCallSite(bootm, name, mtype, info, caller_mname, caller_pos)
+  // call java.lang.invoke.MethodHandleNatives::makeDynamicCallSite(bootm, name, mtype, info, caller_mname, caller_pos)
   oop name_str_oop = StringTable::intern(name, CHECK_(empty)); // not a handle!
   JavaCallArguments args(Handle(THREAD, bootstrap_method()));
   args.push_oop(name_str_oop);
@@ -2531,14 +2617,21 @@
   args.push_oop(caller_mname());
   args.push_int(caller_bci);
   JavaValue result(T_OBJECT);
+  Symbol* makeDynamicCallSite_signature = vmSymbols::makeDynamicCallSite_signature();
+  if (AllowTransitionalJSR292 && SystemDictionaryHandles::MethodHandleNatives_klass()->name() == vmSymbols::sun_dyn_MethodHandleNatives()) {
+    makeDynamicCallSite_signature = vmSymbols::makeDynamicCallSite_TRANS_signature();
+  }
+  if (AllowTransitionalJSR292 && SystemDictionaryHandles::MethodHandleNatives_klass()->name() == vmSymbols::java_dyn_MethodHandleNatives()) {
+    makeDynamicCallSite_signature = vmSymbols::makeDynamicCallSite_TRANS2_signature();
+  }
   JavaCalls::call_static(&result,
                          SystemDictionary::MethodHandleNatives_klass(),
                          vmSymbols::makeDynamicCallSite_name(),
-                         vmSymbols::makeDynamicCallSite_signature(),
+                         makeDynamicCallSite_signature,
                          &args, CHECK_(empty));
   oop call_site_oop = (oop) result.get_jobject();
   assert(call_site_oop->is_oop()
-         /*&& java_dyn_CallSite::is_instance(call_site_oop)*/, "must be sane");
+         /*&& java_lang_invoke_CallSite::is_instance(call_site_oop)*/, "must be sane");
   if (TraceMethodHandles) {
 #ifndef PRODUCT
     tty->print_cr("Linked invokedynamic bci=%d site="INTPTR_FORMAT":", caller_bci, call_site_oop);
--- a/src/share/vm/classfile/systemDictionary.hpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/classfile/systemDictionary.hpp	Mon Apr 04 19:23:29 2011 -0700
@@ -144,18 +144,18 @@
   template(reflect_UnsafeStaticFieldAccessorImpl_klass, sun_reflect_UnsafeStaticFieldAccessorImpl, Opt_Only_JDK15) \
                                                                               \
   /* support for dynamic typing; it's OK if these are NULL in earlier JDKs */ \
-  template(MethodHandle_klass,           java_dyn_MethodHandle,          Opt) \
-  template(MemberName_klass,             sun_dyn_MemberName,             Opt) \
-  template(MethodHandleImpl_klass,       sun_dyn_MethodHandleImpl,       Opt) \
-  template(MethodHandleNatives_klass,    sun_dyn_MethodHandleNatives,    Opt) \
-  template(AdapterMethodHandle_klass,    sun_dyn_AdapterMethodHandle,    Opt) \
-  template(BoundMethodHandle_klass,      sun_dyn_BoundMethodHandle,      Opt) \
-  template(DirectMethodHandle_klass,     sun_dyn_DirectMethodHandle,     Opt) \
-  template(MethodType_klass,             java_dyn_MethodType,            Opt) \
-  template(MethodTypeForm_klass,         java_dyn_MethodTypeForm,        Opt) \
-  template(WrongMethodTypeException_klass, java_dyn_WrongMethodTypeException, Opt) \
-  template(Linkage_klass,                java_dyn_Linkage,               Opt) \
-  template(CallSite_klass,               java_dyn_CallSite,              Opt) \
+  template(MethodHandle_klass,           java_lang_invoke_MethodHandle,     Pre_JSR292) \
+  template(MemberName_klass,             java_lang_invoke_MemberName,       Pre_JSR292) \
+  template(MethodHandleImpl_klass,       sun_dyn_MethodHandleImpl,          Opt) /* AllowTransitionalJSR292 ONLY */ \
+  template(MethodHandleNatives_klass,    java_lang_invoke_MethodHandleNatives, Pre_JSR292) \
+  template(AdapterMethodHandle_klass,    java_lang_invoke_AdapterMethodHandle, Pre_JSR292) \
+  template(BoundMethodHandle_klass,      java_lang_invoke_BoundMethodHandle, Pre_JSR292) \
+  template(DirectMethodHandle_klass,     java_lang_invoke_DirectMethodHandle, Pre_JSR292) \
+  template(MethodType_klass,             java_lang_invoke_MethodType,       Pre_JSR292) \
+  template(MethodTypeForm_klass,         java_lang_invoke_MethodTypeForm,   Pre_JSR292) \
+  template(WrongMethodTypeException_klass, java_lang_invoke_WrongMethodTypeException, Pre_JSR292) \
+  template(Linkage_klass,                java_lang_invoke_Linkage,          Opt) /* AllowTransitionalJSR292 ONLY */ \
+  template(CallSite_klass,               java_lang_invoke_CallSite,         Pre_JSR292) \
   /* Note: MethodHandle must be first, and CallSite last in group */          \
                                                                               \
   template(StringBuffer_klass,           java_lang_StringBuffer,         Pre) \
@@ -207,6 +207,7 @@
 
   enum InitOption {
     Pre,                        // preloaded; error if not present
+    Pre_JSR292,                 // preloaded if EnableMethodHandles
 
     // Order is significant.  Options before this point require resolve_or_fail.
     // Options after this point will use resolve_or_null instead.
@@ -401,6 +402,7 @@
   }
 
   static klassOop check_klass_Pre(klassOop k) { return check_klass(k); }
+  static klassOop check_klass_Pre_JSR292(klassOop k) { return EnableInvokeDynamic ? check_klass(k) : k; }
   static klassOop check_klass_Opt(klassOop k) { return k; }
   static klassOop check_klass_Opt_Kernel(klassOop k) { return k; } //== Opt
   static klassOop check_klass_Opt_Only_JDK15(klassOop k) {
@@ -420,6 +422,8 @@
     initialize_wk_klasses_until((WKID) limit, start_id, THREAD);
   }
 
+  static Symbol* find_backup_symbol(Symbol* symbol, const char* from_prefix, const char* to_prefix);
+
 public:
   #define WK_KLASS_DECLARE(name, ignore_symbol, option) \
     static klassOop name() { return check_klass_##option(_well_known_klasses[WK_KLASS_ENUM_NAME(name)]); }
@@ -441,6 +445,9 @@
 
   static void load_abstract_ownable_synchronizer_klass(TRAPS);
 
+  static Symbol* find_backup_class_name(Symbol* class_name_symbol);
+  static Symbol* find_backup_signature(Symbol* signature_symbol);
+
 private:
   // Tells whether ClassLoader.loadClassInternal is present
   static bool has_loadClassInternal()       { return _has_loadClassInternal; }
@@ -475,18 +482,18 @@
                                        Handle loader2, bool is_method, TRAPS);
 
   // JSR 292
-  // find the java.dyn.MethodHandles::invoke method for a given signature
+  // find the java.lang.invoke.MethodHandles::invoke method for a given signature
   static methodOop find_method_handle_invoke(Symbol* name,
                                              Symbol* signature,
                                              KlassHandle accessing_klass,
                                              TRAPS);
-  // ask Java to compute a java.dyn.MethodType object for a given signature
+  // ask Java to compute a java.lang.invoke.MethodType object for a given signature
   static Handle    find_method_handle_type(Symbol* signature,
                                            KlassHandle accessing_klass,
                                            bool for_invokeGeneric,
                                            bool& return_bcp_flag,
                                            TRAPS);
-  // ask Java to compute a java.dyn.MethodHandle object for a given CP entry
+  // ask Java to compute a java.lang.invoke.MethodHandle object for a given CP entry
   static Handle    link_method_handle_constant(KlassHandle caller,
                                                int ref_kind, //e.g., JVM_REF_invokeVirtual
                                                KlassHandle callee,
--- a/src/share/vm/classfile/verificationType.hpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/classfile/verificationType.hpp	Mon Apr 04 19:23:29 2011 -0700
@@ -128,6 +128,7 @@
 
   // Create verification types
   static VerificationType bogus_type() { return VerificationType(Bogus); }
+  static VerificationType top_type() { return bogus_type(); } // alias
   static VerificationType null_type() { return VerificationType(Null); }
   static VerificationType integer_type() { return VerificationType(Integer); }
   static VerificationType float_type() { return VerificationType(Float); }
--- a/src/share/vm/classfile/verifier.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/classfile/verifier.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -1671,13 +1671,19 @@
       VerificationType::long_type(),
       VerificationType::long2_type(), CHECK_VERIFY(this));
   } else if (tag.is_method_handle()) {
+    Symbol* methodHandle_name = vmSymbols::java_lang_invoke_MethodHandle();
+    if (AllowTransitionalJSR292 && !Universe::is_bootstrapping())
+      methodHandle_name = SystemDictionaryHandles::MethodHandle_klass()->name();
     current_frame->push_stack(
       VerificationType::reference_type(
-        vmSymbols::java_dyn_MethodHandle()), CHECK_VERIFY(this));
+        methodHandle_name), CHECK_VERIFY(this));
   } else if (tag.is_method_type()) {
+    Symbol* methodType_name = vmSymbols::java_lang_invoke_MethodType();
+    if (AllowTransitionalJSR292 && !Universe::is_bootstrapping())
+      methodType_name = SystemDictionaryHandles::MethodType_klass()->name();
     current_frame->push_stack(
       VerificationType::reference_type(
-        vmSymbols::java_dyn_MethodType()), CHECK_VERIFY(this));
+        methodType_name), CHECK_VERIFY(this));
   } else {
     verify_error(bci, "Invalid index in ldc");
     return;
--- a/src/share/vm/classfile/vmSymbols.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/classfile/vmSymbols.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -277,6 +277,12 @@
   return sid;
 }
 
+vmSymbols::SID vmSymbols::find_sid(const char* symbol_name) {
+  Symbol* symbol = SymbolTable::probe(symbol_name, (int) strlen(symbol_name));
+  if (symbol == NULL)  return NO_SID;
+  return find_sid(symbol);
+}
+
 static vmIntrinsics::ID wrapper_intrinsic(BasicType type, bool unboxing) {
 #define TYPE2(type, unboxing) ((int)(type)*2 + ((unboxing) ? 1 : 0))
   switch (TYPE2(type, unboxing)) {
--- a/src/share/vm/classfile/vmSymbols.hpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/classfile/vmSymbols.hpp	Mon Apr 04 19:23:29 2011 -0700
@@ -229,33 +229,60 @@
   template(base_name,                                 "base")                                     \
                                                                                                   \
   /* Support for JSR 292 & invokedynamic (JDK 1.7 and above) */                                   \
-  template(java_dyn_InvokeDynamic,                    "java/dyn/InvokeDynamic")                   \
-  template(java_dyn_Linkage,                          "java/dyn/Linkage")                         \
-  template(java_dyn_CallSite,                         "java/dyn/CallSite")                        \
-  template(java_dyn_MethodHandle,                     "java/dyn/MethodHandle")                    \
-  template(java_dyn_MethodType,                       "java/dyn/MethodType")                      \
-  template(java_dyn_WrongMethodTypeException,         "java/dyn/WrongMethodTypeException")        \
-  template(java_dyn_MethodType_signature,             "Ljava/dyn/MethodType;")                    \
-  template(java_dyn_MethodHandle_signature,           "Ljava/dyn/MethodHandle;")                  \
+  template(java_lang_invoke_InvokeDynamic,            "java/lang/invoke/InvokeDynamic")           \
+  template(java_lang_invoke_Linkage,                  "java/lang/invoke/Linkage")                 \
+  template(java_lang_invoke_CallSite,                 "java/lang/invoke/CallSite")                \
+  template(java_lang_invoke_MethodHandle,             "java/lang/invoke/MethodHandle")            \
+  template(java_lang_invoke_MethodType,               "java/lang/invoke/MethodType")              \
+  template(java_lang_invoke_WrongMethodTypeException, "java/lang/invoke/WrongMethodTypeException") \
+  template(java_lang_invoke_MethodType_signature,     "Ljava/lang/invoke/MethodType;")            \
+  template(java_lang_invoke_MethodHandle_signature,   "Ljava/lang/invoke/MethodHandle;")          \
   /* internal classes known only to the JVM: */                                                   \
-  template(java_dyn_MethodTypeForm,                   "java/dyn/MethodTypeForm")                  \
-  template(java_dyn_MethodTypeForm_signature,         "Ljava/dyn/MethodTypeForm;")                \
-  template(sun_dyn_MemberName,                        "sun/dyn/MemberName")                       \
-  template(sun_dyn_MemberName_signature,              "Lsun/dyn/MemberName;")                     \
-  template(sun_dyn_MethodHandleImpl,                  "sun/dyn/MethodHandleImpl")                 \
-  template(sun_dyn_MethodHandleNatives,               "sun/dyn/MethodHandleNatives")              \
-  template(sun_dyn_AdapterMethodHandle,               "sun/dyn/AdapterMethodHandle")              \
-  template(sun_dyn_BoundMethodHandle,                 "sun/dyn/BoundMethodHandle")                \
-  template(sun_dyn_DirectMethodHandle,                "sun/dyn/DirectMethodHandle")               \
-  /* internal up-calls made only by the JVM, via class sun.dyn.MethodHandleNatives: */            \
+  template(java_lang_invoke_MethodTypeForm,           "java/lang/invoke/MethodTypeForm")          \
+  template(java_lang_invoke_MethodTypeForm_signature, "Ljava/lang/invoke/MethodTypeForm;")        \
+  template(java_lang_invoke_MemberName,               "java/lang/invoke/MemberName")              \
+  template(java_lang_invoke_MethodHandleNatives,      "java/lang/invoke/MethodHandleNatives")     \
+  template(java_lang_invoke_AdapterMethodHandle,      "java/lang/invoke/AdapterMethodHandle")     \
+  template(java_lang_invoke_BoundMethodHandle,        "java/lang/invoke/BoundMethodHandle")       \
+  template(java_lang_invoke_DirectMethodHandle,       "java/lang/invoke/DirectMethodHandle")      \
+  /* temporary transitional public names from 6839872: */                                         \
+  template(java_dyn_InvokeDynamic,                    "java/dyn/InvokeDynamic")         /* AllowTransitionalJSR292 ONLY */ \
+  template(java_dyn_Linkage,                          "java/dyn/Linkage")               /* AllowTransitionalJSR292 ONLY */ \
+  template(java_dyn_CallSite,                         "java/dyn/CallSite")              /* AllowTransitionalJSR292 ONLY */ \
+  template(java_dyn_MethodHandle,                     "java/dyn/MethodHandle")          /* AllowTransitionalJSR292 ONLY */ \
+  template(java_dyn_MethodType,                       "java/dyn/MethodType")            /* AllowTransitionalJSR292 ONLY */ \
+  template(java_dyn_WrongMethodTypeException,         "java/dyn/WrongMethodTypeException") /* AllowTransitionalJSR292 ONLY */ \
+  template(java_dyn_MethodType_signature,             "Ljava/dyn/MethodType;")          /* AllowTransitionalJSR292 ONLY */ \
+  template(java_dyn_MethodHandle_signature,           "Ljava/dyn/MethodHandle;")        /* AllowTransitionalJSR292 ONLY */ \
+  /* temporary transitional internal names from 6839872: */                                       \
+  template(java_dyn_MethodTypeForm,                   "java/dyn/MethodTypeForm")        /* AllowTransitionalJSR292 ONLY */ \
+  template(java_dyn_MethodTypeForm_signature,         "Ljava/dyn/MethodTypeForm;")      /* AllowTransitionalJSR292 ONLY */ \
+  template(java_dyn_MemberName,                       "java/dyn/MemberName")            /* AllowTransitionalJSR292 ONLY */ \
+  template(java_dyn_MethodHandleNatives,              "java/dyn/MethodHandleNatives")   /* AllowTransitionalJSR292 ONLY */ \
+  template(java_dyn_AdapterMethodHandle,              "java/dyn/AdapterMethodHandle")   /* AllowTransitionalJSR292 ONLY */ \
+  template(java_dyn_BoundMethodHandle,                "java/dyn/BoundMethodHandle")     /* AllowTransitionalJSR292 ONLY */ \
+  template(java_dyn_DirectMethodHandle,               "java/dyn/DirectMethodHandle")    /* AllowTransitionalJSR292 ONLY */ \
+  /* temporary transitional internal names from EDR: */                                           \
+  template(sun_dyn_MemberName,                        "sun/dyn/MemberName")             /* AllowTransitionalJSR292 ONLY */ \
+  template(sun_dyn_MethodHandleImpl,                  "sun/dyn/MethodHandleImpl")       /* AllowTransitionalJSR292 ONLY */ \
+  template(sun_dyn_MethodHandleNatives,               "sun/dyn/MethodHandleNatives")    /* AllowTransitionalJSR292 ONLY */ \
+  template(sun_dyn_AdapterMethodHandle,               "sun/dyn/AdapterMethodHandle")    /* AllowTransitionalJSR292 ONLY */ \
+  template(sun_dyn_BoundMethodHandle,                 "sun/dyn/BoundMethodHandle")      /* AllowTransitionalJSR292 ONLY */ \
+  template(sun_dyn_DirectMethodHandle,                "sun/dyn/DirectMethodHandle")     /* AllowTransitionalJSR292 ONLY */ \
+  /* internal up-calls made only by the JVM, via class sun.invoke.MethodHandleNatives: */         \
   template(findMethodHandleType_name,                 "findMethodHandleType")                     \
-  template(findMethodHandleType_signature, "(Ljava/lang/Class;[Ljava/lang/Class;)Ljava/dyn/MethodType;") \
+  template(findMethodHandleType_signature,       "(Ljava/lang/Class;[Ljava/lang/Class;)Ljava/lang/invoke/MethodType;") \
+  template(findMethodHandleType_TRANS_signature, "(Ljava/lang/Class;[Ljava/lang/Class;)Ljava/dyn/MethodType;") /* AllowTransitionalJSR292 ONLY */ \
   template(notifyGenericMethodType_name,              "notifyGenericMethodType")                  \
-  template(notifyGenericMethodType_signature,         "(Ljava/dyn/MethodType;)V")                 \
+  template(notifyGenericMethodType_signature,         "(Ljava/lang/invoke/MethodType;)V")         \
+  template(notifyGenericMethodType_TRANS_signature,   "(Ljava/dyn/MethodType;)V")       /* AllowTransitionalJSR292 ONLY */ \
   template(linkMethodHandleConstant_name,             "linkMethodHandleConstant")                 \
-  template(linkMethodHandleConstant_signature, "(Ljava/lang/Class;ILjava/lang/Class;Ljava/lang/String;Ljava/lang/Object;)Ljava/dyn/MethodHandle;") \
+  template(linkMethodHandleConstant_signature, "(Ljava/lang/Class;ILjava/lang/Class;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/invoke/MethodHandle;") \
+  template(linkMethodHandleConstant_TRANS_signature, "(Ljava/lang/Class;ILjava/lang/Class;Ljava/lang/String;Ljava/lang/Object;)Ljava/dyn/MethodHandle;") /* AllowTransitionalJSR292 ONLY */ \
   template(makeDynamicCallSite_name,                  "makeDynamicCallSite")                      \
-  template(makeDynamicCallSite_signature, "(Ljava/dyn/MethodHandle;Ljava/lang/String;Ljava/dyn/MethodType;Ljava/lang/Object;Lsun/dyn/MemberName;I)Ljava/dyn/CallSite;") \
+  template(makeDynamicCallSite_signature, "(Ljava/lang/invoke/MethodHandle;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/Object;Ljava/lang/invoke/MemberName;I)Ljava/lang/invoke/CallSite;") \
+  template(makeDynamicCallSite_TRANS_signature, "(Ljava/dyn/MethodHandle;Ljava/lang/String;Ljava/dyn/MethodType;Ljava/lang/Object;Lsun/dyn/MemberName;I)Ljava/dyn/CallSite;") /* AllowTransitionalJSR292 ONLY */ \
+  template(makeDynamicCallSite_TRANS2_signature, "(Ljava/dyn/MethodHandle;Ljava/lang/String;Ljava/dyn/MethodType;Ljava/lang/Object;Ljava/dyn/MemberName;I)Ljava/dyn/CallSite;") /* AllowTransitionalJSR292 ONLY */ \
   NOT_LP64(  do_alias(machine_word_signature,         int_signature)  )                           \
   LP64_ONLY( do_alias(machine_word_signature,         long_signature) )                           \
                                                                                                   \
@@ -882,13 +909,15 @@
                                                                                                                           \
   do_intrinsic(_invoke,                   java_lang_reflect_Method, invoke_name, object_object_array_object_signature, F_R) \
   /*   (symbols invoke_name and invoke_signature defined above) */                                                      \
-  do_intrinsic(_checkSpreadArgument,      sun_dyn_MethodHandleImpl, checkSpreadArgument_name, checkSpreadArgument_signature, F_S) \
+  do_intrinsic(_checkSpreadArgument,      java_lang_invoke_MethodHandleNatives, checkSpreadArgument_name, checkSpreadArgument_signature, F_S) \
+  do_intrinsic(_checkSpreadArgument_TRANS,sun_dyn_MethodHandleImpl, checkSpreadArgument_name, checkSpreadArgument_signature, F_S) /* AllowTransitionalJSR292 ONLY */ \
+  do_intrinsic(_checkSpreadArgument_TRANS2,java_dyn_MethodHandleNatives, checkSpreadArgument_name, checkSpreadArgument_signature, F_S) /* AllowTransitionalJSR292 ONLY */ \
    do_name(    checkSpreadArgument_name,       "checkSpreadArgument")                                                   \
    do_name(    checkSpreadArgument_signature,  "(Ljava/lang/Object;I)V")                                                \
-  do_intrinsic(_invokeExact,              java_dyn_MethodHandle, invokeExact_name,   object_array_object_signature, F_RN) \
-  do_intrinsic(_invokeGeneric,            java_dyn_MethodHandle, invokeGeneric_name, object_array_object_signature, F_RN) \
-  do_intrinsic(_invokeVarargs,            java_dyn_MethodHandle, invokeVarargs_name, object_array_object_signature, F_R)  \
-  do_intrinsic(_invokeDynamic,            java_dyn_InvokeDynamic, star_name,         object_array_object_signature, F_SN) \
+  do_intrinsic(_invokeExact,              java_lang_invoke_MethodHandle, invokeExact_name,   object_array_object_signature, F_RN) \
+  do_intrinsic(_invokeGeneric,            java_lang_invoke_MethodHandle, invokeGeneric_name, object_array_object_signature, F_RN) \
+  do_intrinsic(_invokeVarargs,            java_lang_invoke_MethodHandle, invokeVarargs_name, object_array_object_signature, F_R)  \
+  do_intrinsic(_invokeDynamic,            java_lang_invoke_InvokeDynamic, star_name,         object_array_object_signature, F_SN) \
                                                                                                                         \
   /* unboxing methods: */                                                                                               \
   do_intrinsic(_booleanValue,             java_lang_Boolean,      booleanValue_name, void_boolean_signature, F_R)       \
@@ -995,6 +1024,7 @@
 
   // Returns symbol's SID if one is assigned, else NO_SID.
   static SID find_sid(Symbol* symbol);
+  static SID find_sid(const char* symbol_name);
 
 #ifndef PRODUCT
   // No need for this in the product:
--- a/src/share/vm/code/codeCache.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/code/codeCache.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -337,7 +337,6 @@
     if (is_live) {
       // Perform cur->oops_do(f), maybe just once per nmethod.
       f->do_code_blob(cur);
-      cur->fix_oop_relocations();
     }
   }
 
@@ -552,6 +551,19 @@
 }
 
 
+void CodeCache::verify_oops() {
+  MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
+  VerifyOopClosure voc;
+  FOR_ALL_ALIVE_BLOBS(cb) {
+    if (cb->is_nmethod()) {
+      nmethod *nm = (nmethod*)cb;
+      nm->oops_do(&voc);
+      nm->verify_oop_relocations();
+    }
+  }
+}
+
+
 address CodeCache::first_address() {
   assert_locked_or_safepoint(CodeCache_lock);
   return (address)_heap->begin();
@@ -939,9 +951,16 @@
                _heap->high(),
                _heap->high_boundary());
   st->print_cr(" total_blobs=" UINT32_FORMAT " nmethods=" UINT32_FORMAT
-               " adapters=" UINT32_FORMAT " free_code_cache=" SIZE_FORMAT
+               " adapters=" UINT32_FORMAT " free_code_cache=" SIZE_FORMAT "Kb"
                " largest_free_block=" SIZE_FORMAT,
-               CodeCache::nof_blobs(), CodeCache::nof_nmethods(),
-               CodeCache::nof_adapters(), CodeCache::unallocated_capacity(),
-               CodeCache::largest_free_block());
+               nof_blobs(), nof_nmethods(), nof_adapters(),
+               unallocated_capacity()/K, largest_free_block());
 }
+
+void CodeCache::log_state(outputStream* st) {
+  st->print(" total_blobs='" UINT32_FORMAT "' nmethods='" UINT32_FORMAT "'"
+            " adapters='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'"
+            " largest_free_block='" SIZE_FORMAT "'",
+            nof_blobs(), nof_nmethods(), nof_adapters(),
+            unallocated_capacity(), largest_free_block());
+}
--- a/src/share/vm/code/codeCache.hpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/code/codeCache.hpp	Mon Apr 04 19:23:29 2011 -0700
@@ -122,6 +122,7 @@
   // GC support
   static void gc_epilogue();
   static void gc_prologue();
+  static void verify_oops();
   // If "unloading_occurred" is true, then unloads (i.e., breaks root links
   // to) any unmarked codeBlobs in the cache.  Sets "marked_for_unloading"
   // to "true" iff some code got unloaded.
@@ -147,6 +148,7 @@
   static void verify();                          // verifies the code cache
   static void print_trace(const char* event, CodeBlob* cb, int size = 0) PRODUCT_RETURN;
   static void print_bounds(outputStream* st);    // Prints a summary of the bounds of the code cache
+  static void log_state(outputStream* st);
 
   // The full limits of the codeCache
   static address  low_bound()                    { return (address) _heap->low_boundary(); }
@@ -159,7 +161,7 @@
   static size_t  max_capacity()                  { return _heap->max_capacity(); }
   static size_t  unallocated_capacity()          { return _heap->unallocated_capacity(); }
   static size_t  largest_free_block()            { return _heap->largest_free_block(); }
-  static bool    needs_flushing()                { return unallocated_capacity() < CodeCacheFlushingMinimumFreeSpace; }
+  static bool    needs_flushing()                { return largest_free_block() < CodeCacheFlushingMinimumFreeSpace; }
 
   static bool needs_cache_clean()                { return _needs_cache_clean; }
   static void set_needs_cache_clean(bool v)      { _needs_cache_clean = v;    }
--- a/src/share/vm/code/nmethod.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/code/nmethod.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -170,7 +170,7 @@
   int pc_desc_resets;   // number of resets (= number of caches)
   int pc_desc_queries;  // queries to nmethod::find_pc_desc
   int pc_desc_approx;   // number of those which have approximate true
-  int pc_desc_repeats;  // number of _last_pc_desc hits
+  int pc_desc_repeats;  // number of _pc_descs[0] hits
   int pc_desc_hits;     // number of LRU cache hits
   int pc_desc_tests;    // total number of PcDesc examinations
   int pc_desc_searches; // total number of quasi-binary search steps
@@ -190,15 +190,10 @@
 } nmethod_stats;
 #endif //PRODUCT
 
+
 //---------------------------------------------------------------------------------
 
 
-// The _unwind_handler is a special marker address, which says that
-// for given exception oop and address, the frame should be removed
-// as the tuple cannot be caught in the nmethod
-address ExceptionCache::_unwind_handler = (address) -1;
-
-
 ExceptionCache::ExceptionCache(Handle exception, address pc, address handler) {
   assert(pc != NULL, "Must be non null");
   assert(exception.not_null(), "Must be non null");
@@ -283,40 +278,44 @@
 
 void PcDescCache::reset_to(PcDesc* initial_pc_desc) {
   if (initial_pc_desc == NULL) {
-    _last_pc_desc = NULL;  // native method
+    _pc_descs[0] = NULL; // native method; no PcDescs at all
     return;
   }
   NOT_PRODUCT(++nmethod_stats.pc_desc_resets);
   // reset the cache by filling it with benign (non-null) values
   assert(initial_pc_desc->pc_offset() < 0, "must be sentinel");
-  _last_pc_desc = initial_pc_desc + 1;  // first valid one is after sentinel
   for (int i = 0; i < cache_size; i++)
     _pc_descs[i] = initial_pc_desc;
 }
 
 PcDesc* PcDescCache::find_pc_desc(int pc_offset, bool approximate) {
   NOT_PRODUCT(++nmethod_stats.pc_desc_queries);
-  NOT_PRODUCT(if (approximate)  ++nmethod_stats.pc_desc_approx);
+  NOT_PRODUCT(if (approximate) ++nmethod_stats.pc_desc_approx);
+
+  // Note: one might think that caching the most recently
+  // read value separately would be a win, but one would be
+  // wrong.  When many threads are updating it, the cache
+  // line it's in would bounce between caches, negating
+  // any benefit.
 
   // In order to prevent race conditions do not load cache elements
   // repeatedly, but use a local copy:
   PcDesc* res;
 
-  // Step one:  Check the most recently returned value.
-  res = _last_pc_desc;
-  if (res == NULL)  return NULL;  // native method; no PcDescs at all
+  // Step one:  Check the most recently added value.
+  res = _pc_descs[0];
+  if (res == NULL) return NULL;  // native method; no PcDescs at all
   if (match_desc(res, pc_offset, approximate)) {
     NOT_PRODUCT(++nmethod_stats.pc_desc_repeats);
     return res;
   }
 
-  // Step two:  Check the LRU cache.
-  for (int i = 0; i < cache_size; i++) {
+  // Step two:  Check the rest of the LRU cache.
+  for (int i = 1; i < cache_size; ++i) {
     res = _pc_descs[i];
-    if (res->pc_offset() < 0)  break;  // optimization: skip empty cache
+    if (res->pc_offset() < 0) break;  // optimization: skip empty cache
     if (match_desc(res, pc_offset, approximate)) {
       NOT_PRODUCT(++nmethod_stats.pc_desc_hits);
-      _last_pc_desc = res;  // record this cache hit in case of repeat
       return res;
     }
   }
@@ -327,24 +326,23 @@
 
 void PcDescCache::add_pc_desc(PcDesc* pc_desc) {
   NOT_PRODUCT(++nmethod_stats.pc_desc_adds);
-  // Update the LRU cache by shifting pc_desc forward:
+  // Update the LRU cache by shifting pc_desc forward.
   for (int i = 0; i < cache_size; i++)  {
     PcDesc* next = _pc_descs[i];
     _pc_descs[i] = pc_desc;
     pc_desc = next;
   }
-  // Note:  Do not update _last_pc_desc.  It fronts for the LRU cache.
 }
 
 // adjust pcs_size so that it is a multiple of both oopSize and
 // sizeof(PcDesc) (assumes that if sizeof(PcDesc) is not a multiple
 // of oopSize, then 2*sizeof(PcDesc) is)
-static int  adjust_pcs_size(int pcs_size) {
+static int adjust_pcs_size(int pcs_size) {
   int nsize = round_to(pcs_size,   oopSize);
   if ((nsize % sizeof(PcDesc)) != 0) {
     nsize = pcs_size + sizeof(PcDesc);
   }
-  assert((nsize %  oopSize) == 0, "correct alignment");
+  assert((nsize % oopSize) == 0, "correct alignment");
   return nsize;
 }
 
@@ -655,6 +653,9 @@
     _pc_desc_cache.reset_to(NULL);
 
     code_buffer->copy_oops_to(this);
+    if (ScavengeRootsInCode && detect_scavenge_root_oops()) {
+      CodeCache::add_scavenge_root_nmethod(this);
+    }
     debug_only(verify_scavenge_root_oops());
     CodeCache::commit(this);
   }
@@ -767,7 +768,7 @@
 
 void* nmethod::operator new(size_t size, int nmethod_size) {
   // Always leave some room in the CodeCache for I2C/C2I adapters
-  if (CodeCache::unallocated_capacity() < CodeCacheMinimumFreeSpace) return NULL;
+  if (CodeCache::largest_free_block() < CodeCacheMinimumFreeSpace) return NULL;
   return CodeCache::allocate(nmethod_size);
 }
 
@@ -1107,6 +1108,20 @@
 }
 
 
+void nmethod::verify_oop_relocations() {
+  // Ensure sure that the code matches the current oop values
+  RelocIterator iter(this, NULL, NULL);
+  while (iter.next()) {
+    if (iter.type() == relocInfo::oop_type) {
+      oop_Relocation* reloc = iter.oop_reloc();
+      if (!reloc->oop_is_immediate()) {
+        reloc->verify_oop_relocation();
+      }
+    }
+  }
+}
+
+
 ScopeDesc* nmethod::scope_desc_at(address pc) {
   PcDesc* pd = pc_desc_at(pc);
   guarantee(pd != NULL, "scope must be present");
@@ -1185,14 +1200,17 @@
   set_stack_traversal_mark(NMethodSweeper::traversal_count());
 }
 
-// Tell if a non-entrant method can be converted to a zombie (i.e., there is no activations on the stack)
+// Tell if a non-entrant method can be converted to a zombie (i.e.,
+// there are no activations on the stack, not in use by the VM,
+// and not in use by the ServiceThread)
 bool nmethod::can_not_entrant_be_converted() {
   assert(is_not_entrant(), "must be a non-entrant method");
 
   // Since the nmethod sweeper only does partial sweep the sweeper's traversal
   // count can be greater than the stack traversal count before it hits the
   // nmethod for the second time.
-  return stack_traversal_mark()+1 < NMethodSweeper::traversal_count();
+  return stack_traversal_mark()+1 < NMethodSweeper::traversal_count() &&
+         !is_locked_by_vm();
 }
 
 void nmethod::inc_decompile_count() {
@@ -1299,6 +1317,7 @@
 // Common functionality for both make_not_entrant and make_zombie
 bool nmethod::make_not_entrant_or_zombie(unsigned int state) {
   assert(state == zombie || state == not_entrant, "must be zombie or not_entrant");
+  assert(!is_zombie(), "should not already be a zombie");
 
   // Make sure neither the nmethod nor the method is flushed in case of a safepoint in code below.
   nmethodLocker nml(this);
@@ -1306,11 +1325,6 @@
   No_Safepoint_Verifier nsv;
 
   {
-    // If the method is already zombie there is nothing to do
-    if (is_zombie()) {
-      return false;
-    }
-
     // invalidate osr nmethod before acquiring the patching lock since
     // they both acquire leaf locks and we don't want a deadlock.
     // This logic is equivalent to the logic below for patching the
@@ -1380,13 +1394,12 @@
       flush_dependencies(NULL);
     }
 
-    {
-      // zombie only - if a JVMTI agent has enabled the CompiledMethodUnload event
-      // and it hasn't already been reported for this nmethod then report it now.
-      // (the event may have been reported earilier if the GC marked it for unloading).
-      Pause_No_Safepoint_Verifier pnsv(&nsv);
-      post_compiled_method_unload();
-    }
+    // zombie only - if a JVMTI agent has enabled the CompiledMethodUnload
+    // event and it hasn't already been reported for this nmethod then
+    // report it now. The event may have been reported earilier if the GC
+    // marked it for unloading). JvmtiDeferredEventQueue support means
+    // we no longer go to a safepoint here.
+    post_compiled_method_unload();
 
 #ifdef ASSERT
     // It's no longer safe to access the oops section since zombie
@@ -1571,7 +1584,7 @@
   if (_jmethod_id != NULL && JvmtiExport::should_post_compiled_method_unload()) {
     assert(!unload_reported(), "already unloaded");
     JvmtiDeferredEvent event =
-      JvmtiDeferredEvent::compiled_method_unload_event(
+      JvmtiDeferredEvent::compiled_method_unload_event(this,
           _jmethod_id, insts_begin());
     if (SafepointSynchronize::is_at_safepoint()) {
       // Don't want to take the queueing lock. Add it as pending and
@@ -1827,6 +1840,7 @@
     assert(cur != NULL, "not NULL-terminated");
     nmethod* next = cur->_oops_do_mark_link;
     cur->_oops_do_mark_link = NULL;
+    cur->fix_oop_relocations();
     NOT_PRODUCT(if (TraceScavenge)  cur->print_on(tty, "oops_do, unmark\n"));
     cur = next;
   }
@@ -1886,7 +1900,7 @@
 
 
 oop nmethod::embeddedOop_at(u_char* p) {
-  RelocIterator iter(this, p, p + oopSize);
+  RelocIterator iter(this, p, p + 1);
   while (iter.next())
     if (iter.type() == relocInfo::oop_type) {
       return iter.oop_reloc()->oop_value();
@@ -2176,10 +2190,12 @@
   lock_nmethod(_nm);
 }
 
-void nmethodLocker::lock_nmethod(nmethod* nm) {
+// Only JvmtiDeferredEvent::compiled_method_unload_event()
+// should pass zombie_ok == true.
+void nmethodLocker::lock_nmethod(nmethod* nm, bool zombie_ok) {
   if (nm == NULL)  return;
   Atomic::inc(&nm->_lock_count);
-  guarantee(!nm->is_zombie(), "cannot lock a zombie method");
+  guarantee(zombie_ok || !nm->is_zombie(), "cannot lock a zombie method");
 }
 
 void nmethodLocker::unlock_nmethod(nmethod* nm) {
--- a/src/share/vm/code/nmethod.hpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/code/nmethod.hpp	Mon Apr 04 19:23:29 2011 -0700
@@ -34,7 +34,6 @@
 class ExceptionCache : public CHeapObj {
   friend class VMStructs;
  private:
-  static address _unwind_handler;
   enum { cache_size = 16 };
   klassOop _exception_type;
   address  _pc[cache_size];
@@ -62,8 +61,6 @@
   bool    match_exception_with_space(Handle exception) ;
   address test_address(address addr);
   bool    add_address_and_handler(address addr, address handler) ;
-
-  static address unwind_handler() { return _unwind_handler; }
 };
 
 
@@ -72,14 +69,13 @@
   friend class VMStructs;
  private:
   enum { cache_size = 4 };
-  PcDesc* _last_pc_desc;         // most recent pc_desc found
   PcDesc* _pc_descs[cache_size]; // last cache_size pc_descs found
  public:
-  PcDescCache() { debug_only(_last_pc_desc = NULL); }
+  PcDescCache() { debug_only(_pc_descs[0] = NULL); }
   void    reset_to(PcDesc* initial_pc_desc);
   PcDesc* find_pc_desc(int pc_offset, bool approximate);
   void    add_pc_desc(PcDesc* pc_desc);
-  PcDesc* last_pc_desc() { return _last_pc_desc; }
+  PcDesc* last_pc_desc() { return _pc_descs[0]; }
 };
 
 
@@ -181,7 +177,7 @@
   unsigned int _has_method_handle_invokes:1; // Has this method MethodHandle invokes?
 
   // Protected by Patching_lock
-  unsigned char _state;                      // {alive, not_entrant, zombie, unloaded)
+  unsigned char _state;                      // {alive, not_entrant, zombie, unloaded}
 
 #ifdef ASSERT
   bool _oops_are_stale;  // indicates that it's no longer safe to access oops section
@@ -197,7 +193,10 @@
 
   NOT_PRODUCT(bool _has_debug_info; )
 
-  // Nmethod Flushing lock (if non-zero, then the nmethod is not removed)
+  // Nmethod Flushing lock. If non-zero, then the nmethod is not removed
+  // and is not made into a zombie. However, once the nmethod is made into
+  // a zombie, it will be locked one final time if CompiledMethodUnload
+  // event processing needs to be done.
   jint  _lock_count;
 
   // not_entrant method removal. Each mark_sweep pass will update
@@ -460,6 +459,7 @@
 public:
   void fix_oop_relocations(address begin, address end) { fix_oop_relocations(begin, end, false); }
   void fix_oop_relocations()                           { fix_oop_relocations(NULL, NULL, false); }
+  void verify_oop_relocations();
 
   bool is_at_poll_return(address pc);
   bool is_at_poll_or_poll_return(address pc);
@@ -525,8 +525,9 @@
   void flush();
 
  public:
-  // If returning true, it is unsafe to remove this nmethod even though it is a zombie
-  // nmethod, since the VM might have a reference to it. Should only be called from a  safepoint.
+  // When true is returned, it is unsafe to remove this nmethod even if
+  // it is a zombie, since the VM or the ServiceThread might still be
+  // using it.
   bool is_locked_by_vm() const                    { return _lock_count >0; }
 
   // See comment at definition of _last_seen_on_stack
@@ -692,13 +693,20 @@
 
 };
 
-// Locks an nmethod so its code will not get removed, even if it is a zombie/not_entrant method
+// Locks an nmethod so its code will not get removed and it will not
+// be made into a zombie, even if it is a not_entrant method. After the
+// nmethod becomes a zombie, if CompiledMethodUnload event processing
+// needs to be done, then lock_nmethod() is used directly to keep the
+// generated code from being reused too early.
 class nmethodLocker : public StackObj {
   nmethod* _nm;
 
  public:
 
-  static void lock_nmethod(nmethod* nm);   // note: nm can be NULL
+  // note: nm can be NULL
+  // Only JvmtiDeferredEvent::compiled_method_unload_event()
+  // should pass zombie_ok == true.
+  static void lock_nmethod(nmethod* nm, bool zombie_ok = false);
   static void unlock_nmethod(nmethod* nm); // (ditto)
 
   nmethodLocker(address pc); // derive nm from pc
--- a/src/share/vm/code/relocInfo.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/code/relocInfo.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -798,6 +798,14 @@
 }
 
 
+void oop_Relocation::verify_oop_relocation() {
+  if (!oop_is_immediate()) {
+    // get the oop from the pool, and re-insert it into the instruction:
+    verify_value(value());
+  }
+}
+
+
 RelocIterator virtual_call_Relocation::parse_ic(nmethod* &nm, address &ic_call, address &first_oop,
                                                 oop* &oop_addr, bool *is_optimized) {
   assert(ic_call != NULL, "ic_call address must be set");
--- a/src/share/vm/code/relocInfo.hpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/code/relocInfo.hpp	Mon Apr 04 19:23:29 2011 -0700
@@ -765,7 +765,8 @@
 
  protected:
   // platform-dependent utilities for decoding and patching instructions
-  void       pd_set_data_value       (address x, intptr_t off); // a set or mem-ref
+  void       pd_set_data_value       (address x, intptr_t off, bool verify_only = false); // a set or mem-ref
+  void       pd_verify_data_value    (address x, intptr_t off) { pd_set_data_value(x, off, true); }
   address    pd_call_destination     (address orig_addr = NULL);
   void       pd_set_call_destination (address x);
   void       pd_swap_in_breakpoint   (address x, short* instrs, int instrlen);
@@ -880,6 +881,12 @@
     else
       pd_set_data_value(x, o);
   }
+  void        verify_value(address x) {
+    if (addr_in_const())
+      assert(*(address*)addr() == x, "must agree");
+    else
+      pd_verify_data_value(x, offset());
+  }
 
   // The "o" (displacement) argument is relevant only to split relocations
   // on RISC machines.  In some CPUs (SPARC), the set-hi and set-lo ins'ns
@@ -950,6 +957,8 @@
 
   void fix_oop_relocation();        // reasserts oop value
 
+  void verify_oop_relocation();
+
   address value()  { return (address) *oop_addr(); }
 
   bool oop_is_immediate()  { return oop_index() == 0; }
--- a/src/share/vm/compiler/compileBroker.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/compiler/compileBroker.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -1364,7 +1364,7 @@
       // We need this HandleMark to avoid leaking VM handles.
       HandleMark hm(thread);
 
-      if (CodeCache::unallocated_capacity() < CodeCacheMinimumFreeSpace) {
+      if (CodeCache::largest_free_block() < CodeCacheMinimumFreeSpace) {
         // the code cache is really full
         handle_full_code_cache();
       } else if (UseCodeCacheFlushing && CodeCache::needs_flushing()) {
@@ -1645,11 +1645,13 @@
   if (UseCompiler || AlwaysCompileLoopMethods ) {
     if (xtty != NULL) {
       xtty->begin_elem("code_cache_full");
+      CodeCache::log_state(xtty);
       xtty->stamp();
       xtty->end_elem();
     }
     warning("CodeCache is full. Compiler has been disabled.");
     warning("Try increasing the code cache size using -XX:ReservedCodeCacheSize=");
+    CodeCache::print_bounds(tty);
 #ifndef PRODUCT
     if (CompileTheWorld || ExitOnFullCodeCache) {
       before_exit(JavaThread::current());
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -292,13 +292,15 @@
 void CMSCollector::ref_processor_init() {
   if (_ref_processor == NULL) {
     // Allocate and initialize a reference processor
-    _ref_processor = ReferenceProcessor::create_ref_processor(
-        _span,                               // span
-        _cmsGen->refs_discovery_is_atomic(), // atomic_discovery
-        _cmsGen->refs_discovery_is_mt(),     // mt_discovery
-        &_is_alive_closure,
-        ParallelGCThreads,
-        ParallelRefProcEnabled);
+    _ref_processor =
+      new ReferenceProcessor(_span,                               // span
+                             (ParallelGCThreads > 1) && ParallelRefProcEnabled, // mt processing
+                             (int) ParallelGCThreads,             // mt processing degree
+                             _cmsGen->refs_discovery_is_mt(),     // mt discovery
+                             (int) MAX2(ConcGCThreads, ParallelGCThreads), // mt discovery degree
+                             _cmsGen->refs_discovery_is_atomic(), // discovery is not atomic
+                             &_is_alive_closure,                  // closure for liveness info
+                             false);                              // next field updates do not need write barrier
     // Initialize the _ref_processor field of CMSGen
     _cmsGen->set_ref_processor(_ref_processor);
 
@@ -641,7 +643,7 @@
   }
 
   // Support for multi-threaded concurrent phases
-  if (CollectedHeap::use_parallel_gc_threads() && CMSConcurrentMTEnabled) {
+  if (CMSConcurrentMTEnabled) {
     if (FLAG_IS_DEFAULT(ConcGCThreads)) {
       // just for now
       FLAG_SET_DEFAULT(ConcGCThreads, (ParallelGCThreads + 3)/4);
@@ -1689,6 +1691,8 @@
     MutexLockerEx y(CGC_lock, Mutex::_no_safepoint_check_flag);
     _full_gc_requested = true;
     CGC_lock->notify();   // nudge CMS thread
+  } else {
+    assert(gc_count > full_gc_count, "Error: causal loop");
   }
 }
 
@@ -1988,17 +1992,16 @@
   // Temporarily widen the span of the weak reference processing to
   // the entire heap.
   MemRegion new_span(GenCollectedHeap::heap()->reserved_region());
-  ReferenceProcessorSpanMutator x(ref_processor(), new_span);
-
+  ReferenceProcessorSpanMutator rp_mut_span(ref_processor(), new_span);
   // Temporarily, clear the "is_alive_non_header" field of the
   // reference processor.
-  ReferenceProcessorIsAliveMutator y(ref_processor(), NULL);
-
+  ReferenceProcessorIsAliveMutator rp_mut_closure(ref_processor(), NULL);
   // Temporarily make reference _processing_ single threaded (non-MT).
-  ReferenceProcessorMTProcMutator z(ref_processor(), false);
-
+  ReferenceProcessorMTProcMutator rp_mut_mt_processing(ref_processor(), false);
   // Temporarily make refs discovery atomic
-  ReferenceProcessorAtomicMutator w(ref_processor(), true);
+  ReferenceProcessorAtomicMutator rp_mut_atomic(ref_processor(), true);
+  // Temporarily make reference _discovery_ single threaded (non-MT)
+  ReferenceProcessorMTDiscoveryMutator rp_mut_discovery(ref_processor(), false);
 
   ref_processor()->set_enqueuing_is_done(false);
   ref_processor()->enable_discovery();
@@ -4263,9 +4266,7 @@
 
   // Refs discovery is already non-atomic.
   assert(!ref_processor()->discovery_is_atomic(), "Should be non-atomic");
-  // Mutate the Refs discovery so it is MT during the
-  // multi-threaded marking phase.
-  ReferenceProcessorMTMutator mt(ref_processor(), num_workers > 1);
+  assert(ref_processor()->discovery_is_mt(), "Discovery should be MT");
   DEBUG_ONLY(RememberKlassesChecker cmx(should_unload_classes());)
   conc_workers()->start_task(&tsk);
   while (tsk.yielded()) {
@@ -4318,6 +4319,8 @@
   ResourceMark rm;
   HandleMark   hm;
 
+  // Temporarily make refs discovery single threaded (non-MT)
+  ReferenceProcessorMTDiscoveryMutator rp_mut_discovery(ref_processor(), false);
   MarkFromRootsClosure markFromRootsClosure(this, _span, &_markBitMap,
     &_markStack, &_revisitStack, CMSYield && asynch);
   // the last argument to iterate indicates whether the iteration
@@ -4356,10 +4359,6 @@
   verify_overflow_empty();
   _abort_preclean = false;
   if (CMSPrecleaningEnabled) {
-    // Precleaning is currently not MT but the reference processor
-    // may be set for MT.  Disable it temporarily here.
-    ReferenceProcessor* rp = ref_processor();
-    ReferenceProcessorMTProcMutator z(rp, false);
     _eden_chunk_index = 0;
     size_t used = get_eden_used();
     size_t capacity = get_eden_capacity();
@@ -4502,11 +4501,16 @@
          _collectorState == AbortablePreclean, "incorrect state");
   ResourceMark rm;
   HandleMark   hm;
+
+  // Precleaning is currently not MT but the reference processor
+  // may be set for MT.  Disable it temporarily here.
+  ReferenceProcessor* rp = ref_processor();
+  ReferenceProcessorMTDiscoveryMutator rp_mut_discovery(rp, false);
+
   // Do one pass of scrubbing the discovered reference lists
   // to remove any reference objects with strongly-reachable
   // referents.
   if (clean_refs) {
-    ReferenceProcessor* rp = ref_processor();
     CMSPrecleanRefsYieldClosure yield_cl(this);
     assert(rp->span().equals(_span), "Spans should be equal");
     CMSKeepAliveClosure keep_alive(this, _span, &_markBitMap,
@@ -5576,8 +5580,10 @@
   // in the multi-threaded case, but we special-case n=1 here to get
   // repeatable measurements of the 1-thread overhead of the parallel code.
   if (n_workers > 1) {
-    // Make refs discovery MT-safe
-    ReferenceProcessorMTMutator mt(ref_processor(), true);
+    // Make refs discovery MT-safe, if it isn't already: it may not
+    // necessarily be so, since it's possible that we are doing
+    // ST marking.
+    ReferenceProcessorMTDiscoveryMutator mt(ref_processor(), true);
     GenCollectedHeap::StrongRootsScope srs(gch);
     workers->run_task(&tsk);
   } else {
@@ -5703,14 +5709,19 @@
                       CMSBitMap*       mark_bit_map,
                       AbstractWorkGang* workers,
                       OopTaskQueueSet* task_queues):
+    // XXX Should superclass AGTWOQ also know about AWG since it knows
+    // about the task_queues used by the AWG? Then it could initialize
+    // the terminator() object. See 6984287. The set_for_termination()
+    // below is a temporary band-aid for the regression in 6984287.
     AbstractGangTaskWOopQueues("Process referents by policy in parallel",
       task_queues),
     _task(task),
     _collector(collector), _span(span), _mark_bit_map(mark_bit_map)
-    {
-      assert(_collector->_span.equals(_span) && !_span.is_empty(),
-             "Inconsistency in _span");
-    }
+  {
+    assert(_collector->_span.equals(_span) && !_span.is_empty(),
+           "Inconsistency in _span");
+    set_for_termination(workers->active_workers());
+  }
 
   OopTaskQueueSet* task_queues() { return queues(); }
 
@@ -5872,8 +5883,7 @@
       // That is OK as long as the Reference lists are balanced (see
       // balance_all_queues() and balance_queues()).
 
-
-      rp->set_mt_degree(ParallelGCThreads);
+      rp->set_active_mt_degree(ParallelGCThreads);
       CMSRefProcTaskExecutor task_executor(*this);
       rp->process_discovered_references(&_is_alive_closure,
                                         &cmsKeepAliveClosure,
@@ -5920,14 +5930,18 @@
     }
 
     {
-      TraceTime t("scrub symbol & string tables", PrintGCDetails, false, gclog_or_tty);
-      // Now clean up stale oops in StringTable
-      StringTable::unlink(&_is_alive_closure);
+      TraceTime t("scrub symbol table", PrintGCDetails, false, gclog_or_tty);
       // Clean up unreferenced symbols in symbol table.
       SymbolTable::unlink();
     }
   }
 
+  if (should_unload_classes() || !JavaObjectsInPerm) {
+    TraceTime t("scrub string table", PrintGCDetails, false, gclog_or_tty);
+    // Now clean up stale oops in StringTable
+    StringTable::unlink(&_is_alive_closure);
+  }
+
   verify_work_stacks_empty();
   // Restore any preserved marks as a result of mark stack or
   // work queue overflow
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp	Mon Apr 04 19:23:29 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -1133,7 +1133,7 @@
     // rare that the cost of the CAS's involved is in the
     // noise. That's a measurement that should be done, and
     // the code simplified if that turns out to be the case.
-    return false;
+    return ConcGCThreads > 1;
   }
 
   // Override
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -51,7 +51,7 @@
 volatile jint ConcurrentMarkSweepThread::_pending_yields      = 0;
 volatile jint ConcurrentMarkSweepThread::_pending_decrements  = 0;
 
-volatile bool ConcurrentMarkSweepThread::_icms_enabled   = false;
+volatile jint ConcurrentMarkSweepThread::_icms_disabled   = 0;
 volatile bool ConcurrentMarkSweepThread::_should_run     = false;
 // When icms is enabled, the icms thread is stopped until explicitly
 // started.
@@ -84,7 +84,7 @@
     }
   }
   _sltMonitor = SLT_lock;
-  set_icms_enabled(CMSIncrementalMode);
+  assert(!CMSIncrementalMode || icms_is_enabled(), "Error");
 }
 
 void ConcurrentMarkSweepThread::run() {
@@ -341,11 +341,11 @@
 
 void ConcurrentMarkSweepThread::icms_wait() {
   assert(UseConcMarkSweepGC && CMSIncrementalMode, "just checking");
-  if (_should_stop && icms_enabled()) {
+  if (_should_stop && icms_is_enabled()) {
     MutexLockerEx x(iCMS_lock, Mutex::_no_safepoint_check_flag);
     trace_state("pause_icms");
     _collector->stats().stop_cms_timer();
-    while(!_should_run && icms_enabled()) {
+    while(!_should_run && icms_is_enabled()) {
       iCMS_lock->wait(Mutex::_no_safepoint_check_flag);
     }
     _collector->stats().start_cms_timer();
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp	Mon Apr 04 19:23:29 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -43,7 +43,7 @@
 class ConcurrentMarkSweepGeneration;
 class CMSCollector;
 
-// The Concurrent Mark Sweep GC Thread (could be several in the future).
+// The Concurrent Mark Sweep GC Thread
 class ConcurrentMarkSweepThread: public ConcurrentGCThread {
   friend class VMStructs;
   friend class ConcurrentMarkSweepGeneration;   // XXX should remove friendship
@@ -58,8 +58,6 @@
   static SurrogateLockerThread::SLT_msg_type _sltBuffer;
   static Monitor*                       _sltMonitor;
 
-  ConcurrentMarkSweepThread*            _next;
-
   static bool _should_terminate;
 
   enum CMS_flag_type {
@@ -87,7 +85,7 @@
   // Tracing messages, enabled by CMSTraceThreadState.
   static inline void trace_state(const char* desc);
 
-  static volatile bool _icms_enabled;   // iCMS enabled?
+  static volatile int _icms_disabled;   // a counter to track #iCMS disable & enable
   static volatile bool _should_run;     // iCMS may run
   static volatile bool _should_stop;    // iCMS should stop
 
@@ -217,10 +215,25 @@
 
   // Incremental mode is enabled globally by the flag CMSIncrementalMode.  It
   // must also be enabled/disabled dynamically to allow foreground collections.
-  static inline void enable_icms()              { _icms_enabled = true; }
-  static inline void disable_icms()             { _icms_enabled = false; }
-  static inline void set_icms_enabled(bool val) { _icms_enabled = val; }
-  static inline bool icms_enabled()             { return _icms_enabled; }
+#define ICMS_ENABLING_ASSERT                                                      \
+          assert((CMSIncrementalMode  && _icms_disabled >= 0) ||                  \
+                 (!CMSIncrementalMode && _icms_disabled <= 0), "Error")
+
+  static inline void enable_icms() {
+    ICMS_ENABLING_ASSERT;
+    Atomic::dec(&_icms_disabled);
+  }
+  static inline void disable_icms() {
+   ICMS_ENABLING_ASSERT;
+   Atomic::inc(&_icms_disabled);
+  }
+  static inline bool icms_is_disabled() {
+   ICMS_ENABLING_ASSERT;
+   return _icms_disabled > 0;
+  }
+  static inline bool icms_is_enabled() {
+   return !icms_is_disabled();
+  }
 };
 
 inline void ConcurrentMarkSweepThread::trace_state(const char* desc) {
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -192,14 +192,18 @@
          "total_collections() should be monotonically increasing");
 
   MutexLockerEx x(FullGCCount_lock, Mutex::_no_safepoint_check_flag);
+  assert(_full_gc_count_before <= gch->total_full_collections(), "Error");
   if (gch->total_full_collections() == _full_gc_count_before) {
-    // Disable iCMS until the full collection is done.
+    // Disable iCMS until the full collection is done, and
+    // remember that we did so.
     CMSCollector::disable_icms();
+    _disabled_icms = true;
     // In case CMS thread was in icms_wait(), wake it up.
     CMSCollector::start_icms();
     // Nudge the CMS thread to start a concurrent collection.
     CMSCollector::request_full_gc(_full_gc_count_before);
   } else {
+    assert(_full_gc_count_before < gch->total_full_collections(), "Error");
     FullGCCount_lock->notify_all();  // Inform the Java thread its work is done
   }
 }
@@ -259,6 +263,8 @@
       FullGCCount_lock->wait(Mutex::_no_safepoint_check_flag);
     }
   }
-  // Enable iCMS back.
-  CMSCollector::enable_icms();
+  // Enable iCMS back if we disabled it earlier.
+  if (_disabled_icms) {
+    CMSCollector::enable_icms();
+  }
 }
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.hpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.hpp	Mon Apr 04 19:23:29 2011 -0700
@@ -128,11 +128,14 @@
 // VM operation to invoke a concurrent collection of the heap as a
 // GenCollectedHeap heap.
 class VM_GenCollectFullConcurrent: public VM_GC_Operation {
+  bool _disabled_icms;
  public:
   VM_GenCollectFullConcurrent(unsigned int gc_count_before,
                               unsigned int full_gc_count_before,
                               GCCause::Cause gc_cause)
-    : VM_GC_Operation(gc_count_before, gc_cause, full_gc_count_before, true /* full */) {
+    : VM_GC_Operation(gc_count_before, gc_cause, full_gc_count_before, true /* full */),
+      _disabled_icms(false)
+  {
     assert(FullGCCount_lock != NULL, "Error");
     assert(UseAsyncConcMarkSweepGC, "Else will hang caller");
   }
--- a/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -373,7 +373,7 @@
             // RSet updating while within an evacuation pause.
             // In this case worker_i should be the id of a GC worker thread
             assert(SafepointSynchronize::is_at_safepoint(), "not during an evacuation pause");
-            assert(worker_i < (int) DirtyCardQueueSet::num_par_ids(), "incorrect worker id");
+            assert(worker_i < (int) (ParallelGCThreads == 0 ? 1 : ParallelGCThreads), "incorrect worker id");
             into_cset_dcq->enqueue(entry);
           }
         }
--- a/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -1828,7 +1828,7 @@
   G1CollectedHeap* g1h = G1CollectedHeap::heap();
 
   _cleanup_list.verify_optional();
-  FreeRegionList local_free_list("Local Cleanup List");
+  FreeRegionList tmp_free_list("Tmp Free List");
 
   if (G1ConcRegionFreeingVerbose) {
     gclog_or_tty->print_cr("G1ConcRegionFreeing [complete cleanup] : "
@@ -1842,7 +1842,7 @@
     HeapRegion* hr = _cleanup_list.remove_head();
     assert(hr != NULL, "the list was not empty");
     hr->rem_set()->clear();
-    local_free_list.add_as_tail(hr);
+    tmp_free_list.add_as_tail(hr);
 
     // Instead of adding one region at a time to the secondary_free_list,
     // we accumulate them in the local list and move them a few at a
@@ -1850,20 +1850,20 @@
     // we do during this process. We'll also append the local list when
     // _cleanup_list is empty (which means we just removed the last
     // region from the _cleanup_list).
-    if ((local_free_list.length() % G1SecondaryFreeListAppendLength == 0) ||
+    if ((tmp_free_list.length() % G1SecondaryFreeListAppendLength == 0) ||
         _cleanup_list.is_empty()) {
       if (G1ConcRegionFreeingVerbose) {
         gclog_or_tty->print_cr("G1ConcRegionFreeing [complete cleanup] : "
                                "appending "SIZE_FORMAT" entries to the "
                                "secondary_free_list, clean list still has "
                                SIZE_FORMAT" entries",
-                               local_free_list.length(),
+                               tmp_free_list.length(),
                                _cleanup_list.length());
       }
 
       {
         MutexLockerEx x(SecondaryFreeList_lock, Mutex::_no_safepoint_check_flag);
-        g1h->secondary_free_list_add_as_tail(&local_free_list);
+        g1h->secondary_free_list_add_as_tail(&tmp_free_list);
         SecondaryFreeList_lock->notify_all();
       }
 
@@ -1874,7 +1874,7 @@
       }
     }
   }
-  assert(local_free_list.is_empty(), "post-condition");
+  assert(tmp_free_list.is_empty(), "post-condition");
 }
 
 // Support closures for reference procssing in G1
@@ -2141,21 +2141,22 @@
   G1CMKeepAliveClosure g1_keep_alive(g1h, this, nextMarkBitMap());
   G1CMDrainMarkingStackClosure
     g1_drain_mark_stack(nextMarkBitMap(), &_markStack, &g1_keep_alive);
-
   // We use the work gang from the G1CollectedHeap and we utilize all
   // the worker threads.
-  int active_workers = MAX2(MIN2(g1h->workers()->total_workers(), (int)_max_task_num), 1);
+  int active_workers = g1h->workers() ? g1h->workers()->total_workers() : 1;
+  active_workers = MAX2(MIN2(active_workers, (int)_max_task_num), 1);
 
   G1RefProcTaskExecutor par_task_executor(g1h, this, nextMarkBitMap(),
                                           g1h->workers(), active_workers);
 
+
   if (rp->processing_is_mt()) {
     // Set the degree of MT here.  If the discovery is done MT, there
     // may have been a different number of threads doing the discovery
     // and a different number of discovered lists may have Ref objects.
     // That is OK as long as the Reference lists are balanced (see
     // balance_all_queues() and balance_queues()).
-    rp->set_mt_degree(active_workers);
+    rp->set_active_mt_degree(active_workers);
 
     rp->process_discovered_references(&g1_is_alive,
                                       &g1_keep_alive,
@@ -3182,7 +3183,7 @@
 
   template <class T> void do_oop_work(T* p) {
     assert( _g1h->is_in_g1_reserved((HeapWord*) p), "invariant");
-    assert(!_g1h->is_on_free_list(
+    assert(!_g1h->is_on_master_free_list(
                     _g1h->heap_region_containing((HeapWord*) p)), "invariant");
 
     oop obj = oopDesc::load_decode_heap_oop(p);
@@ -3403,7 +3404,7 @@
 void CMTask::push(oop obj) {
   HeapWord* objAddr = (HeapWord*) obj;
   assert(_g1h->is_in_g1_reserved(objAddr), "invariant");
-  assert(!_g1h->is_on_free_list(
+  assert(!_g1h->is_on_master_free_list(
               _g1h->heap_region_containing((HeapWord*) objAddr)), "invariant");
   assert(!_g1h->is_obj_ill(obj), "invariant");
   assert(_nextMarkBitMap->isMarked(objAddr), "invariant");
@@ -3649,7 +3650,7 @@
                                (void*) obj);
 
       assert(_g1h->is_in_g1_reserved((HeapWord*) obj), "invariant" );
-      assert(!_g1h->is_on_free_list(
+      assert(!_g1h->is_on_master_free_list(
                   _g1h->heap_region_containing((HeapWord*) obj)), "invariant");
 
       scan_object(obj);
--- a/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -237,9 +237,9 @@
         // The following will finish freeing up any regions that we
         // found to be empty during cleanup. We'll do this part
         // without joining the suspendible set. If an evacuation pause
-        // takes places, then we would carry on freeing regions in
+        // takes place, then we would carry on freeing regions in
         // case they are needed by the pause. If a Full GC takes
-        // places, it would wait for us to process the regions
+        // place, it would wait for us to process the regions
         // reclaimed by cleanup.
 
         double cleanup_start_sec = os::elapsedTime();
--- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -479,7 +479,7 @@
 // Private methods.
 
 HeapRegion*
-G1CollectedHeap::new_region_try_secondary_free_list(size_t word_size) {
+G1CollectedHeap::new_region_try_secondary_free_list() {
   MutexLockerEx x(SecondaryFreeList_lock, Mutex::_no_safepoint_check_flag);
   while (!_secondary_free_list.is_empty() || free_regions_coming()) {
     if (!_secondary_free_list.is_empty()) {
@@ -531,7 +531,7 @@
         gclog_or_tty->print_cr("G1ConcRegionFreeing [region alloc] : "
                                "forced to look at the secondary_free_list");
       }
-      res = new_region_try_secondary_free_list(word_size);
+      res = new_region_try_secondary_free_list();
       if (res != NULL) {
         return res;
       }
@@ -543,7 +543,7 @@
       gclog_or_tty->print_cr("G1ConcRegionFreeing [region alloc] : "
                              "res == NULL, trying the secondary_free_list");
     }
-    res = new_region_try_secondary_free_list(word_size);
+    res = new_region_try_secondary_free_list();
   }
   if (res == NULL && do_expand) {
     if (expand(word_size * HeapWordSize)) {
@@ -579,6 +579,9 @@
 
 int G1CollectedHeap::humongous_obj_allocate_find_first(size_t num_regions,
                                                        size_t word_size) {
+  assert(isHumongous(word_size), "word_size should be humongous");
+  assert(num_regions * HeapRegion::GrainWords >= word_size, "pre-condition");
+
   int first = -1;
   if (num_regions == 1) {
     // Only one region to allocate, no need to go through the slower
@@ -600,7 +603,7 @@
     // request. If we are only allocating one region we use the common
     // region allocation code (see above).
     wait_while_free_regions_coming();
-    append_secondary_free_list_if_not_empty();
+    append_secondary_free_list_if_not_empty_with_lock();
 
     if (free_regions() >= num_regions) {
       first = _hrs->find_contiguous(num_regions);
@@ -608,7 +611,7 @@
         for (int i = first; i < first + (int) num_regions; ++i) {
           HeapRegion* hr = _hrs->at(i);
           assert(hr->is_empty(), "sanity");
-          assert(is_on_free_list(hr), "sanity");
+          assert(is_on_master_free_list(hr), "sanity");
           hr->set_pending_removal(true);
         }
         _free_list.remove_all_pending(num_regions);
@@ -618,6 +621,126 @@
   return first;
 }
 
+HeapWord*
+G1CollectedHeap::humongous_obj_allocate_initialize_regions(int first,
+                                                           size_t num_regions,
+                                                           size_t word_size) {
+  assert(first != -1, "pre-condition");
+  assert(isHumongous(word_size), "word_size should be humongous");
+  assert(num_regions * HeapRegion::GrainWords >= word_size, "pre-condition");
+
+  // Index of last region in the series + 1.
+  int last = first + (int) num_regions;
+
+  // We need to initialize the region(s) we just discovered. This is
+  // a bit tricky given that it can happen concurrently with
+  // refinement threads refining cards on these regions and
+  // potentially wanting to refine the BOT as they are scanning
+  // those cards (this can happen shortly after a cleanup; see CR
+  // 6991377). So we have to set up the region(s) carefully and in
+  // a specific order.
+
+  // The word size sum of all the regions we will allocate.
+  size_t word_size_sum = num_regions * HeapRegion::GrainWords;
+  assert(word_size <= word_size_sum, "sanity");
+
+  // This will be the "starts humongous" region.
+  HeapRegion* first_hr = _hrs->at(first);
+  // The header of the new object will be placed at the bottom of
+  // the first region.
+  HeapWord* new_obj = first_hr->bottom();
+  // This will be the new end of the first region in the series that
+  // should also match the end of the last region in the seriers.
+  HeapWord* new_end = new_obj + word_size_sum;
+  // This will be the new top of the first region that will reflect
+  // this allocation.
+  HeapWord* new_top = new_obj + word_size;
+
+  // First, we need to zero the header of the space that we will be
+  // allocating. When we update top further down, some refinement
+  // threads might try to scan the region. By zeroing the header we
+  // ensure that any thread that will try to scan the region will
+  // come across the zero klass word and bail out.
+  //
+  // NOTE: It would not have been correct to have used
+  // CollectedHeap::fill_with_object() and make the space look like
+  // an int array. The thread that is doing the allocation will
+  // later update the object header to a potentially different array
+  // type and, for a very short period of time, the klass and length
+  // fields will be inconsistent. This could cause a refinement
+  // thread to calculate the object size incorrectly.
+  Copy::fill_to_words(new_obj, oopDesc::header_size(), 0);
+
+  // We will set up the first region as "starts humongous". This
+  // will also update the BOT covering all the regions to reflect
+  // that there is a single object that starts at the bottom of the
+  // first region.
+  first_hr->set_startsHumongous(new_top, new_end);
+
+  // Then, if there are any, we will set up the "continues
+  // humongous" regions.
+  HeapRegion* hr = NULL;
+  for (int i = first + 1; i < last; ++i) {
+    hr = _hrs->at(i);
+    hr->set_continuesHumongous(first_hr);
+  }
+  // If we have "continues humongous" regions (hr != NULL), then the
+  // end of the last one should match new_end.
+  assert(hr == NULL || hr->end() == new_end, "sanity");
+
+  // Up to this point no concurrent thread would have been able to
+  // do any scanning on any region in this series. All the top
+  // fields still point to bottom, so the intersection between
+  // [bottom,top] and [card_start,card_end] will be empty. Before we
+  // update the top fields, we'll do a storestore to make sure that
+  // no thread sees the update to top before the zeroing of the
+  // object header and the BOT initialization.
+  OrderAccess::storestore();
+
+  // Now that the BOT and the object header have been initialized,
+  // we can update top of the "starts humongous" region.
+  assert(first_hr->bottom() < new_top && new_top <= first_hr->end(),
+         "new_top should be in this region");
+  first_hr->set_top(new_top);
+
+  // Now, we will update the top fields of the "continues humongous"
+  // regions. The reason we need to do this is that, otherwise,
+  // these regions would look empty and this will confuse parts of
+  // G1. For example, the code that looks for a consecutive number
+  // of empty regions will consider them empty and try to
+  // re-allocate them. We can extend is_empty() to also include
+  // !continuesHumongous(), but it is easier to just update the top
+  // fields here. The way we set top for all regions (i.e., top ==
+  // end for all regions but the last one, top == new_top for the
+  // last one) is actually used when we will free up the humongous
+  // region in free_humongous_region().
+  hr = NULL;
+  for (int i = first + 1; i < last; ++i) {
+    hr = _hrs->at(i);
+    if ((i + 1) == last) {
+      // last continues humongous region
+      assert(hr->bottom() < new_top && new_top <= hr->end(),
+             "new_top should fall on this region");
+      hr->set_top(new_top);
+    } else {
+      // not last one
+      assert(new_top > hr->end(), "new_top should be above this region");
+      hr->set_top(hr->end());
+    }
+  }
+  // If we have continues humongous regions (hr != NULL), then the
+  // end of the last one should match new_end and its top should
+  // match new_top.
+  assert(hr == NULL ||
+         (hr->end() == new_end && hr->top() == new_top), "sanity");
+
+  assert(first_hr->used() == word_size * HeapWordSize, "invariant");
+  _summary_bytes_used += first_hr->used();
+  _humongous_set.add(first_hr);
+
+  return new_obj;
+}
+
 // If could fit into free regions w/o expansion, try.
 // Otherwise, if can expand, do so.
 // Otherwise, if using ex regions might help, try with ex given back.
@@ -653,121 +776,16 @@
     }
   }
 
+  HeapWord* result = NULL;
   if (first != -1) {
-    // Index of last region in the series + 1.
-    int last = first + (int) num_regions;
-
-    // We need to initialize the region(s) we just discovered. This is
-    // a bit tricky given that it can happen concurrently with
-    // refinement threads refining cards on these regions and
-    // potentially wanting to refine the BOT as they are scanning
-    // those cards (this can happen shortly after a cleanup; see CR
-    // 6991377). So we have to set up the region(s) carefully and in
-    // a specific order.
-
-    // The word size sum of all the regions we will allocate.
-    size_t word_size_sum = num_regions * HeapRegion::GrainWords;
-    assert(word_size <= word_size_sum, "sanity");
-
-    // This will be the "starts humongous" region.
-    HeapRegion* first_hr = _hrs->at(first);
-    // The header of the new object will be placed at the bottom of
-    // the first region.
-    HeapWord* new_obj = first_hr->bottom();
-    // This will be the new end of the first region in the series that
-    // should also match the end of the last region in the seriers.
-    HeapWord* new_end = new_obj + word_size_sum;
-    // This will be the new top of the first region that will reflect
-    // this allocation.
-    HeapWord* new_top = new_obj + word_size;
-
-    // First, we need to zero the header of the space that we will be
-    // allocating. When we update top further down, some refinement
-    // threads might try to scan the region. By zeroing the header we
-    // ensure that any thread that will try to scan the region will
-    // come across the zero klass word and bail out.
-    //
-    // NOTE: It would not have been correct to have used
-    // CollectedHeap::fill_with_object() and make the space look like
-    // an int array. The thread that is doing the allocation will
-    // later update the object header to a potentially different array
-    // type and, for a very short period of time, the klass and length
-    // fields will be inconsistent. This could cause a refinement
-    // thread to calculate the object size incorrectly.
-    Copy::fill_to_words(new_obj, oopDesc::header_size(), 0);
-
-    // We will set up the first region as "starts humongous". This
-    // will also update the BOT covering all the regions to reflect
-    // that there is a single object that starts at the bottom of the
-    // first region.
-    first_hr->set_startsHumongous(new_top, new_end);
-
-    // Then, if there are any, we will set up the "continues
-    // humongous" regions.
-    HeapRegion* hr = NULL;
-    for (int i = first + 1; i < last; ++i) {
-      hr = _hrs->at(i);
-      hr->set_continuesHumongous(first_hr);
-    }
-    // If we have "continues humongous" regions (hr != NULL), then the
-    // end of the last one should match new_end.
-    assert(hr == NULL || hr->end() == new_end, "sanity");
-
-    // Up to this point no concurrent thread would have been able to
-    // do any scanning on any region in this series. All the top
-    // fields still point to bottom, so the intersection between
-    // [bottom,top] and [card_start,card_end] will be empty. Before we
-    // update the top fields, we'll do a storestore to make sure that
-    // no thread sees the update to top before the zeroing of the
-    // object header and the BOT initialization.
-    OrderAccess::storestore();
-
-    // Now that the BOT and the object header have been initialized,
-    // we can update top of the "starts humongous" region.
-    assert(first_hr->bottom() < new_top && new_top <= first_hr->end(),
-           "new_top should be in this region");
-    first_hr->set_top(new_top);
-
-    // Now, we will update the top fields of the "continues humongous"
-    // regions. The reason we need to do this is that, otherwise,
-    // these regions would look empty and this will confuse parts of
-    // G1. For example, the code that looks for a consecutive number
-    // of empty regions will consider them empty and try to
-    // re-allocate them. We can extend is_empty() to also include
-    // !continuesHumongous(), but it is easier to just update the top
-    // fields here. The way we set top for all regions (i.e., top ==
-    // end for all regions but the last one, top == new_top for the
-    // last one) is actually used when we will free up the humongous
-    // region in free_humongous_region().
-    hr = NULL;
-    for (int i = first + 1; i < last; ++i) {
-      hr = _hrs->at(i);
-      if ((i + 1) == last) {
-        // last continues humongous region
-        assert(hr->bottom() < new_top && new_top <= hr->end(),
-               "new_top should fall on this region");
-        hr->set_top(new_top);
-      } else {
-        // not last one
-        assert(new_top > hr->end(), "new_top should be above this region");
-        hr->set_top(hr->end());
-      }
-    }
-    // If we have continues humongous regions (hr != NULL), then the
-    // end of the last one should match new_end and its top should
-    // match new_top.
-    assert(hr == NULL ||
-           (hr->end() == new_end && hr->top() == new_top), "sanity");
-
-    assert(first_hr->used() == word_size * HeapWordSize, "invariant");
-    _summary_bytes_used += first_hr->used();
-    _humongous_set.add(first_hr);
-
-    return new_obj;
+    result =
+      humongous_obj_allocate_initialize_regions(first, num_regions, word_size);
+    assert(result != NULL, "it should always return a valid result");
   }
 
   verify_region_sets_optional();
-  return NULL;
+
+  return result;
 }
 
 void
@@ -1389,7 +1407,7 @@
     g1_policy()->record_full_collection_start();
 
     wait_while_free_regions_coming();
-    append_secondary_free_list_if_not_empty();
+    append_secondary_free_list_if_not_empty_with_lock();
 
     gc_prologue(true);
     increment_total_collections(true /* full gc */);
@@ -1444,7 +1462,7 @@
     // how reference processing currently works in G1.
 
     // Temporarily make reference _discovery_ single threaded (non-MT).
-    ReferenceProcessorMTMutator rp_disc_ser(ref_processor(), false);
+    ReferenceProcessorMTDiscoveryMutator rp_disc_ser(ref_processor(), false);
 
     // Temporarily make refs discovery atomic
     ReferenceProcessorAtomicMutator rp_disc_atomic(ref_processor(), true);
@@ -2201,16 +2219,16 @@
 
   SharedHeap::ref_processing_init();
   MemRegion mr = reserved_region();
-  _ref_processor = ReferenceProcessor::create_ref_processor(
-                                         mr,    // span
-                                         false, // Reference discovery is not atomic
-                                         true,  // mt_discovery
-                                         &_is_alive_closure, // is alive closure
-                                                             // for efficiency
-                                         ParallelGCThreads,
-                                         ParallelRefProcEnabled,
-                                         true); // Setting next fields of discovered
-                                                // lists requires a barrier.
+  _ref_processor =
+    new ReferenceProcessor(mr,    // span
+                           ParallelRefProcEnabled && (ParallelGCThreads > 1),    // mt processing
+                           (int) ParallelGCThreads,   // degree of mt processing
+                           ParallelGCThreads > 1 || ConcGCThreads > 1,  // mt discovery
+                           (int) MAX2(ParallelGCThreads, ConcGCThreads), // degree of mt discovery
+                           false,                     // Reference discovery is not atomic
+                           &_is_alive_closure,        // is alive closure for efficiency
+                           true);                     // Setting next fields of discovered
+                                                      // lists requires a barrier.
 }
 
 size_t G1CollectedHeap::capacity() const {
@@ -3377,15 +3395,14 @@
 
     TraceMemoryManagerStats tms(false /* fullGC */);
 
-    // If there are any free regions available on the secondary_free_list
-    // make sure we append them to the free_list. However, we don't
-    // have to wait for the rest of the cleanup operation to
-    // finish. If it's still going on that's OK. If we run out of
-    // regions, the region allocation code will check the
-    // secondary_free_list and potentially wait if more free regions
-    // are coming (see new_region_try_secondary_free_list()).
+    // If the secondary_free_list is not empty, append it to the
+    // free_list. No need to wait for the cleanup operation to finish;
+    // the region allocation code will check the secondary_free_list
+    // and wait if necessary. If the G1StressConcRegionFreeing flag is
+    // set, skip this step so that the region allocation code has to
+    // get entries from the secondary_free_list.
     if (!G1StressConcRegionFreeing) {
-      append_secondary_free_list_if_not_empty();
+      append_secondary_free_list_if_not_empty_with_lock();
     }
 
     increment_gc_time_stamp();
@@ -5199,7 +5216,7 @@
   size_t rs_lengths = 0;
 
   while (cur != NULL) {
-    assert(!is_on_free_list(cur), "sanity");
+    assert(!is_on_master_free_list(cur), "sanity");
 
     if (non_young) {
       if (cur->is_young()) {
@@ -5474,8 +5491,6 @@
   _refine_cte_cl->set_concurrent(concurrent);
 }
 
-#ifdef ASSERT
-
 bool G1CollectedHeap::is_in_closed_subset(const void* p) const {
   HeapRegion* hr = heap_region_containing(p);
   if (hr == NULL) {
@@ -5484,7 +5499,6 @@
     return hr->is_in(p);
   }
 }
-#endif // ASSERT
 
 class VerifyRegionListsClosure : public HeapRegionClosure {
 private:
@@ -5546,13 +5560,10 @@
     return;
   }
 
-  {
-    MutexLockerEx x(SecondaryFreeList_lock, Mutex::_no_safepoint_check_flag);
-    // Make sure we append the secondary_free_list on the free_list so
-    // that all free regions we will come across can be safely
-    // attributed to the free_list.
-    append_secondary_free_list();
-  }
+  // Make sure we append the secondary_free_list on the free_list so
+  // that all free regions we will come across can be safely
+  // attributed to the free_list.
+  append_secondary_free_list_if_not_empty_with_lock();
 
   // Finally, make sure that the region accounting in the lists is
   // consistent with what we see in the heap.
--- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Mon Apr 04 19:23:29 2011 -0700
@@ -56,7 +56,6 @@
 class ConcurrentMark;
 class ConcurrentMarkThread;
 class ConcurrentG1Refine;
-class ConcurrentZFThread;
 
 typedef OverflowTaskQueue<StarTask>         RefToScanQueue;
 typedef GenericTaskQueueSet<RefToScanQueue> RefToScanQueueSet;
@@ -64,12 +63,6 @@
 typedef int RegionIdx_t;   // needs to hold [ 0..max_regions() )
 typedef int CardIdx_t;     // needs to hold [ 0..CardsPerRegion )
 
-enum G1GCThreadGroups {
-  G1CRGroup = 0,
-  G1ZFGroup = 1,
-  G1CMGroup = 2
-};
-
 enum GCAllocPurpose {
   GCAllocForTenured,
   GCAllocForSurvived,
@@ -294,9 +287,9 @@
   // These are macros so that, if the assert fires, we get the correct
   // line number, file, etc.
 
-#define heap_locking_asserts_err_msg(__extra_message)                         \
+#define heap_locking_asserts_err_msg(_extra_message_)                         \
   err_msg("%s : Heap_lock locked: %s, at safepoint: %s, is VM thread: %s",    \
-          (__extra_message),                                                  \
+          (_extra_message_),                                                  \
           BOOL_TO_STR(Heap_lock->owned_by_self()),                            \
           BOOL_TO_STR(SafepointSynchronize::is_at_safepoint()),               \
           BOOL_TO_STR(Thread::current()->is_VM_thread()))
@@ -307,11 +300,11 @@
            heap_locking_asserts_err_msg("should be holding the Heap_lock"));  \
   } while (0)
 
-#define assert_heap_locked_or_at_safepoint(__should_be_vm_thread)             \
+#define assert_heap_locked_or_at_safepoint(_should_be_vm_thread_)             \
   do {                                                                        \
     assert(Heap_lock->owned_by_self() ||                                      \
            (SafepointSynchronize::is_at_safepoint() &&                        \
-             ((__should_be_vm_thread) == Thread::current()->is_VM_thread())), \
+             ((_should_be_vm_thread_) == Thread::current()->is_VM_thread())), \
            heap_locking_asserts_err_msg("should be holding the Heap_lock or " \
                                         "should be at a safepoint"));         \
   } while (0)
@@ -338,10 +331,10 @@
                                    "should not be at a safepoint"));          \
   } while (0)
 
-#define assert_at_safepoint(__should_be_vm_thread)                            \
+#define assert_at_safepoint(_should_be_vm_thread_)                            \
   do {                                                                        \
     assert(SafepointSynchronize::is_at_safepoint() &&                         \
-              ((__should_be_vm_thread) == Thread::current()->is_VM_thread()), \
+              ((_should_be_vm_thread_) == Thread::current()->is_VM_thread()), \
            heap_locking_asserts_err_msg("should be at a safepoint"));         \
   } while (0)
 
@@ -371,35 +364,40 @@
   // will check whether there's anything available in the
   // secondary_free_list and/or wait for more regions to appear in that
   // list, if _free_regions_coming is set.
-  HeapRegion* new_region_try_secondary_free_list(size_t word_size);
+  HeapRegion* new_region_try_secondary_free_list();
 
-  // It will try to allocate a single non-humongous HeapRegion
-  // sufficient for an allocation of the given word_size.  If
-  // do_expand is true, it will attempt to expand the heap if
-  // necessary to satisfy the allocation request. Note that word_size
-  // is only used to make sure that we expand sufficiently but, given
-  // that the allocation request is assumed not to be humongous,
-  // having word_size is not strictly necessary (expanding by a single
-  // region will always be sufficient). But let's keep that parameter
-  // in case we need it in the future.
+  // Try to allocate a single non-humongous HeapRegion sufficient for
+  // an allocation of the given word_size. If do_expand is true,
+  // attempt to expand the heap if necessary to satisfy the allocation
+  // request.
   HeapRegion* new_region_work(size_t word_size, bool do_expand);
 
-  // It will try to allocate a new region to be used for allocation by
-  // mutator threads. It will not try to expand the heap if not region
-  // is available.
+  // Try to allocate a new region to be used for allocation by a
+  // mutator thread. Attempt to expand the heap if no region is
+  // available.
   HeapRegion* new_alloc_region(size_t word_size) {
     return new_region_work(word_size, false /* do_expand */);
   }
 
-  // It will try to allocate a new region to be used for allocation by
-  // a GC thread. It will try to expand the heap if no region is
-  // available.
+  // Try to allocate a new region to be used for allocation by a GC
+  // thread. Attempt to expand the heap if no region is available.
   HeapRegion* new_gc_alloc_region(int purpose, size_t word_size);
 
+  // Attempt to satisfy a humongous allocation request of the given
+  // size by finding a contiguous set of free regions of num_regions
+  // length and remove them from the master free list. Return the
+  // index of the first region or -1 if the search was unsuccessful.
   int humongous_obj_allocate_find_first(size_t num_regions, size_t word_size);
 
-  // Attempt to allocate an object of the given (very large) "word_size".
-  // Returns "NULL" on failure.
+  // Initialize a contiguous set of free regions of length num_regions
+  // and starting at index first so that they appear as a single
+  // humongous region.
+  HeapWord* humongous_obj_allocate_initialize_regions(int first,
+                                                      size_t num_regions,
+                                                      size_t word_size);
+
+  // Attempt to allocate a humongous object of the given size. Return
+  // NULL if unsuccessful.
   HeapWord* humongous_obj_allocate(size_t word_size);
 
   // The following two methods, allocate_new_tlab() and
@@ -776,7 +774,7 @@
   // Invoke "save_marks" on all heap regions.
   void save_marks();
 
-  // It frees a non-humongous region by initializing its contents and
+  // Frees a non-humongous region by initializing its contents and
   // adding it to the free list that's passed as a parameter (this is
   // usually a local list which will be appended to the master free
   // list later). The used bytes of freed regions are accumulated in
@@ -787,13 +785,13 @@
                    FreeRegionList* free_list,
                    bool par);
 
-  // It frees a humongous region by collapsing it into individual
-  // regions and calling free_region() for each of them. The freed
-  // regions will be added to the free list that's passed as a parameter
-  // (this is usually a local list which will be appended to the
-  // master free list later). The used bytes of freed regions are
-  // accumulated in pre_used. If par is true, the region's RSet will
-  // not be freed up. The assumption is that this will be done later.
+  // Frees a humongous region by collapsing it into individual regions
+  // and calling free_region() for each of them. The freed regions
+  // will be added to the free list that's passed as a parameter (this
+  // is usually a local list which will be appended to the master free
+  // list later). The used bytes of freed regions are accumulated in
+  // pre_used. If par is true, the region's RSet will not be freed
+  // up. The assumption is that this will be done later.
   void free_humongous_region(HeapRegion* hr,
                              size_t* pre_used,
                              FreeRegionList* free_list,
@@ -1046,13 +1044,13 @@
 #endif // HEAP_REGION_SET_FORCE_VERIFY
 
 #ifdef ASSERT
-  bool is_on_free_list(HeapRegion* hr) {
+  bool is_on_master_free_list(HeapRegion* hr) {
     return hr->containing_set() == &_free_list;
   }
 
-  bool is_on_humongous_set(HeapRegion* hr) {
+  bool is_in_humongous_set(HeapRegion* hr) {
     return hr->containing_set() == &_humongous_set;
-}
+  }
 #endif // ASSERT
 
   // Wrapper for the region list operations that can be called from
@@ -1066,7 +1064,9 @@
     _free_list.add_as_tail(&_secondary_free_list);
   }
 
-  void append_secondary_free_list_if_not_empty() {
+  void append_secondary_free_list_if_not_empty_with_lock() {
+    // If the secondary free list looks empty there's no reason to
+    // take the lock and then try to append it.
     if (!_secondary_free_list.is_empty()) {
       MutexLockerEx x(SecondaryFreeList_lock, Mutex::_no_safepoint_check_flag);
       append_secondary_free_list();
@@ -1134,7 +1134,7 @@
     return _g1_committed;
   }
 
-  NOT_PRODUCT(bool is_in_closed_subset(const void* p) const;)
+  virtual bool is_in_closed_subset(const void* p) const;
 
   // Dirty card table entries covering a list of young regions.
   void dirtyCardsForYoungRegions(CardTableModRefBS* ct_bs, HeapRegion* list);
--- a/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -81,6 +81,57 @@
 
 // </NEW PREDICTION>
 
+// Help class for avoiding interleaved logging
+class LineBuffer: public StackObj {
+
+private:
+  static const int BUFFER_LEN = 1024;
+  static const int INDENT_CHARS = 3;
+  char _buffer[BUFFER_LEN];
+  int _indent_level;
+  int _cur;
+
+  void vappend(const char* format, va_list ap) {
+    int res = vsnprintf(&_buffer[_cur], BUFFER_LEN - _cur, format, ap);
+    if (res != -1) {
+      _cur += res;
+    } else {
+      DEBUG_ONLY(warning("buffer too small in LineBuffer");)
+      _buffer[BUFFER_LEN -1] = 0;
+      _cur = BUFFER_LEN; // vsnprintf above should not add to _buffer if we are called again
+    }
+  }
+
+public:
+  explicit LineBuffer(int indent_level): _indent_level(indent_level), _cur(0) {
+    for (; (_cur < BUFFER_LEN && _cur < (_indent_level * INDENT_CHARS)); _cur++) {
+      _buffer[_cur] = ' ';
+    }
+  }
+
+#ifndef PRODUCT
+  ~LineBuffer() {
+    assert(_cur == _indent_level * INDENT_CHARS, "pending data in buffer - append_and_print_cr() not called?");
+  }
+#endif
+
+  void append(const char* format, ...) {
+    va_list ap;
+    va_start(ap, format);
+    vappend(format, ap);
+    va_end(ap);
+  }
+
+  void append_and_print_cr(const char* format, ...) {
+    va_list ap;
+    va_start(ap, format);
+    vappend(format, ap);
+    va_end(ap);
+    gclog_or_tty->print_cr("%s", _buffer);
+    _cur = _indent_level * INDENT_CHARS;
+  }
+};
+
 G1CollectorPolicy::G1CollectorPolicy() :
   _parallel_gc_threads(G1CollectedHeap::use_parallel_gc_threads()
     ? ParallelGCThreads : 1),
@@ -1016,10 +1067,8 @@
                                          bool summary) {
   double min = data[0], max = data[0];
   double total = 0.0;
-  int j;
-  for (j = 0; j < level; ++j)
-    gclog_or_tty->print("   ");
-  gclog_or_tty->print("[%s (ms):", str);
+  LineBuffer buf(level);
+  buf.append("[%s (ms):", str);
   for (uint i = 0; i < ParallelGCThreads; ++i) {
     double val = data[i];
     if (val < min)
@@ -1027,18 +1076,16 @@
     if (val > max)
       max = val;
     total += val;
-    gclog_or_tty->print("  %3.1lf", val);
+    buf.append("  %3.1lf", val);
   }
   if (summary) {
-    gclog_or_tty->print_cr("");
+    buf.append_and_print_cr("");
     double avg = total / (double) ParallelGCThreads;
-    gclog_or_tty->print(" ");
-    for (j = 0; j < level; ++j)
-      gclog_or_tty->print("   ");
-    gclog_or_tty->print("Avg: %5.1lf, Min: %5.1lf, Max: %5.1lf",
+    buf.append(" ");
+    buf.append("Avg: %5.1lf, Min: %5.1lf, Max: %5.1lf",
                         avg, min, max);
   }
-  gclog_or_tty->print_cr("]");
+  buf.append_and_print_cr("]");
 }
 
 void G1CollectorPolicy::print_par_sizes(int level,
@@ -1047,10 +1094,8 @@
                                         bool summary) {
   double min = data[0], max = data[0];
   double total = 0.0;
-  int j;
-  for (j = 0; j < level; ++j)
-    gclog_or_tty->print("   ");
-  gclog_or_tty->print("[%s :", str);
+  LineBuffer buf(level);
+  buf.append("[%s :", str);
   for (uint i = 0; i < ParallelGCThreads; ++i) {
     double val = data[i];
     if (val < min)
@@ -1058,34 +1103,28 @@
     if (val > max)
       max = val;
     total += val;
-    gclog_or_tty->print(" %d", (int) val);
+    buf.append(" %d", (int) val);
   }
   if (summary) {
-    gclog_or_tty->print_cr("");
+    buf.append_and_print_cr("");
     double avg = total / (double) ParallelGCThreads;
-    gclog_or_tty->print(" ");
-    for (j = 0; j < level; ++j)
-      gclog_or_tty->print("   ");
-    gclog_or_tty->print("Sum: %d, Avg: %d, Min: %d, Max: %d",
+    buf.append(" ");
+    buf.append("Sum: %d, Avg: %d, Min: %d, Max: %d",
                (int)total, (int)avg, (int)min, (int)max);
   }
-  gclog_or_tty->print_cr("]");
+  buf.append_and_print_cr("]");
 }
 
 void G1CollectorPolicy::print_stats (int level,
                                      const char* str,
                                      double value) {
-  for (int j = 0; j < level; ++j)
-    gclog_or_tty->print("   ");
-  gclog_or_tty->print_cr("[%s: %5.1lf ms]", str, value);
+  LineBuffer(level).append_and_print_cr("[%s: %5.1lf ms]", str, value);
 }
 
 void G1CollectorPolicy::print_stats (int level,
                                      const char* str,
                                      int value) {
-  for (int j = 0; j < level; ++j)
-    gclog_or_tty->print("   ");
-  gclog_or_tty->print_cr("[%s: %d]", str, value);
+  LineBuffer(level).append_and_print_cr("[%s: %d]", str, value);
 }
 
 double G1CollectorPolicy::avg_value (double* data) {
@@ -2060,17 +2099,11 @@
   _g1->collection_set_iterate(&cs_closure);
 }
 
-static void print_indent(int level) {
-  for (int j = 0; j < level+1; ++j)
-    gclog_or_tty->print("   ");
-}
-
 void G1CollectorPolicy::print_summary (int level,
                                        const char* str,
                                        NumberSeq* seq) const {
   double sum = seq->sum();
-  print_indent(level);
-  gclog_or_tty->print_cr("%-24s = %8.2lf s (avg = %8.2lf ms)",
+  LineBuffer(level + 1).append_and_print_cr("%-24s = %8.2lf s (avg = %8.2lf ms)",
                 str, sum / 1000.0, seq->avg());
 }
 
@@ -2078,8 +2111,7 @@
                                           const char* str,
                                           NumberSeq* seq) const {
   print_summary(level, str, seq);
-  print_indent(level + 5);
-  gclog_or_tty->print_cr("(num = %5d, std dev = %8.2lf ms, max = %8.2lf ms)",
+  LineBuffer(level + 6).append_and_print_cr("(num = %5d, std dev = %8.2lf ms, max = %8.2lf ms)",
                 seq->num(), seq->sd(), seq->maximum());
 }
 
@@ -2087,6 +2119,7 @@
                                         NumberSeq* other_times_ms,
                                         NumberSeq* calc_other_times_ms) const {
   bool should_print = false;
+  LineBuffer buf(level + 2);
 
   double max_sum = MAX2(fabs(other_times_ms->sum()),
                         fabs(calc_other_times_ms->sum()));
@@ -2095,8 +2128,7 @@
   double sum_ratio = max_sum / min_sum;
   if (sum_ratio > 1.1) {
     should_print = true;
-    print_indent(level + 1);
-    gclog_or_tty->print_cr("## CALCULATED OTHER SUM DOESN'T MATCH RECORDED ###");
+    buf.append_and_print_cr("## CALCULATED OTHER SUM DOESN'T MATCH RECORDED ###");
   }
 
   double max_avg = MAX2(fabs(other_times_ms->avg()),
@@ -2106,30 +2138,25 @@
   double avg_ratio = max_avg / min_avg;
   if (avg_ratio > 1.1) {
     should_print = true;
-    print_indent(level + 1);
-    gclog_or_tty->print_cr("## CALCULATED OTHER AVG DOESN'T MATCH RECORDED ###");
+    buf.append_and_print_cr("## CALCULATED OTHER AVG DOESN'T MATCH RECORDED ###");
   }
 
   if (other_times_ms->sum() < -0.01) {
-    print_indent(level + 1);
-    gclog_or_tty->print_cr("## RECORDED OTHER SUM IS NEGATIVE ###");
+    buf.append_and_print_cr("## RECORDED OTHER SUM IS NEGATIVE ###");
   }
 
   if (other_times_ms->avg() < -0.01) {
-    print_indent(level + 1);
-    gclog_or_tty->print_cr("## RECORDED OTHER AVG IS NEGATIVE ###");
+    buf.append_and_print_cr("## RECORDED OTHER AVG IS NEGATIVE ###");
   }
 
   if (calc_other_times_ms->sum() < -0.01) {
     should_print = true;
-    print_indent(level + 1);
-    gclog_or_tty->print_cr("## CALCULATED OTHER SUM IS NEGATIVE ###");
+    buf.append_and_print_cr("## CALCULATED OTHER SUM IS NEGATIVE ###");
   }
 
   if (calc_other_times_ms->avg() < -0.01) {
     should_print = true;
-    print_indent(level + 1);
-    gclog_or_tty->print_cr("## CALCULATED OTHER AVG IS NEGATIVE ###");
+    buf.append_and_print_cr("## CALCULATED OTHER AVG IS NEGATIVE ###");
   }
 
   if (should_print)
@@ -2210,10 +2237,9 @@
       }
     }
   } else {
-    print_indent(0);
-    gclog_or_tty->print_cr("none");
+    LineBuffer(1).append_and_print_cr("none");
   }
-  gclog_or_tty->print_cr("");
+  LineBuffer(0).append_and_print_cr("");
 }
 
 void G1CollectorPolicy::print_tracing_info() const {
@@ -2532,7 +2558,7 @@
     jint regions_added = parKnownGarbageCl.marked_regions_added();
     _hrSorted->incNumMarkedHeapRegions(regions_added);
     if (G1PrintParCleanupStats) {
-      gclog_or_tty->print("     Thread %d called %d times, added %d regions to list.\n",
+      gclog_or_tty->print_cr("     Thread %d called %d times, added %d regions to list.",
                  i, parKnownGarbageCl.invokes(), regions_added);
     }
   }
--- a/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -185,22 +185,22 @@
   G1CollectedHeap* _g1h;
   ModRefBarrierSet* _mrbs;
   CompactPoint _cp;
-  size_t _pre_used;
-  FreeRegionList _free_list;
   HumongousRegionSet _humongous_proxy_set;
 
   void free_humongous_region(HeapRegion* hr) {
     HeapWord* end = hr->end();
+    size_t dummy_pre_used;
+    FreeRegionList dummy_free_list("Dummy Free List for G1MarkSweep");
+
     assert(hr->startsHumongous(),
            "Only the start of a humongous region should be freed.");
-    _g1h->free_humongous_region(hr, &_pre_used, &_free_list,
+    _g1h->free_humongous_region(hr, &dummy_pre_used, &dummy_free_list,
                                 &_humongous_proxy_set, false /* par */);
-    // Do we also need to do this for the continues humongous regions
-    // we just collapsed?
     hr->prepare_for_compaction(&_cp);
     // Also clear the part of the card table that will be unused after
     // compaction.
     _mrbs->clear(MemRegion(hr->compaction_top(), end));
+    dummy_free_list.remove_all();
   }
 
 public:
@@ -208,8 +208,6 @@
   : _g1h(G1CollectedHeap::heap()),
     _mrbs(G1CollectedHeap::heap()->mr_bs()),
     _cp(NULL, cs, cs->initialize_threshold()),
-    _pre_used(0),
-    _free_list("Local Free List for G1MarkSweep"),
     _humongous_proxy_set("G1MarkSweep Humongous Proxy Set") { }
 
   void update_sets() {
@@ -219,7 +217,6 @@
                                             NULL, /* free_list */
                                             &_humongous_proxy_set,
                                             false /* par */);
-    _free_list.remove_all();
   }
 
   bool doHeapRegion(HeapRegion* hr) {
--- a/src/share/vm/gc_implementation/g1/g1RemSet.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/gc_implementation/g1/g1RemSet.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -86,28 +86,6 @@
   bool idempotent() { return true; }
 };
 
-class IntoCSRegionClosure: public HeapRegionClosure {
-  IntoCSOopClosure _blk;
-  G1CollectedHeap* _g1;
-public:
-  IntoCSRegionClosure(G1CollectedHeap* g1, OopsInHeapRegionClosure* blk) :
-    _g1(g1), _blk(g1, blk) {}
-  bool doHeapRegion(HeapRegion* r) {
-    if (!r->in_collection_set()) {
-      _blk.set_region(r);
-      if (r->isHumongous()) {
-        if (r->startsHumongous()) {
-          oop obj = oop(r->bottom());
-          obj->oop_iterate(&_blk);
-        }
-      } else {
-        r->oop_before_save_marks_iterate(&_blk);
-      }
-    }
-    return false;
-  }
-};
-
 class VerifyRSCleanCardOopClosure: public OopClosure {
   G1CollectedHeap* _g1;
 public:
@@ -329,7 +307,7 @@
     // is during RSet updating within an evacuation pause.
     // In this case worker_i should be the id of a GC worker thread.
     assert(SafepointSynchronize::is_at_safepoint(), "not during an evacuation pause");
-    assert(worker_i < (int) DirtyCardQueueSet::num_par_ids(), "should be a GC worker");
+    assert(worker_i < (int) (ParallelGCThreads == 0 ? 1 : ParallelGCThreads), "should be a GC worker");
 
     if (_g1rs->concurrentRefineOneCard(card_ptr, worker_i, true)) {
       // 'card_ptr' contains references that point into the collection
--- a/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.hpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.hpp	Mon Apr 04 19:23:29 2011 -0700
@@ -83,11 +83,15 @@
   }
 
   template <class T> void write_ref_array_pre_work(T* dst, int count);
-  virtual void write_ref_array_pre(oop* dst, int count) {
-    write_ref_array_pre_work(dst, count);
+  virtual void write_ref_array_pre(oop* dst, int count, bool dest_uninitialized) {
+    if (!dest_uninitialized) {
+      write_ref_array_pre_work(dst, count);
+    }
   }
-  virtual void write_ref_array_pre(narrowOop* dst, int count) {
-    write_ref_array_pre_work(dst, count);
+  virtual void write_ref_array_pre(narrowOop* dst, int count, bool dest_uninitialized) {
+    if (!dest_uninitialized) {
+      write_ref_array_pre_work(dst, count);
+    }
   }
 };
 
--- a/src/share/vm/gc_implementation/g1/heapRegion.hpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/gc_implementation/g1/heapRegion.hpp	Mon Apr 04 19:23:29 2011 -0700
@@ -53,8 +53,8 @@
 class HeapRegionSetBase;
 
 #define HR_FORMAT "%d:["PTR_FORMAT","PTR_FORMAT","PTR_FORMAT"]"
-#define HR_FORMAT_PARAMS(__hr) (__hr)->hrs_index(), (__hr)->bottom(), \
-                               (__hr)->top(), (__hr)->end()
+#define HR_FORMAT_PARAMS(_hr_) (_hr_)->hrs_index(), (_hr_)->bottom(), \
+                               (_hr_)->top(), (_hr_)->end()
 
 // A dirty card to oop closure for heap regions. It
 // knows how to get the G1 heap and how to use the bitmap
@@ -518,13 +518,13 @@
                    containing_set, _containing_set));
 
     _containing_set = containing_set;
-}
+  }
 
   HeapRegionSetBase* containing_set() { return _containing_set; }
 #else // ASSERT
   void set_containing_set(HeapRegionSetBase* containing_set) { }
 
-  // containing_set() is only used in asserts so there's not reason
+  // containing_set() is only used in asserts so there's no reason
   // to provide a dummy version of it.
 #endif // ASSERT
 
@@ -535,14 +535,15 @@
   bool pending_removal() { return _pending_removal; }
 
   void set_pending_removal(bool pending_removal) {
-    // We can only set pending_removal to true, if it's false and the
-    // region belongs to a set.
-    assert(!pending_removal ||
-           (!_pending_removal && containing_set() != NULL), "pre-condition");
-    // We can only set pending_removal to false, if it's true and the
-    // region does not belong to a set.
-    assert( pending_removal ||
-           ( _pending_removal && containing_set() == NULL), "pre-condition");
+    if (pending_removal) {
+      assert(!_pending_removal && containing_set() != NULL,
+             "can only set pending removal to true if it's false and "
+             "the region belongs to a region set");
+    } else {
+      assert( _pending_removal && containing_set() == NULL,
+              "can only set pending removal to false if it's true and "
+              "the region does not belong to a region set");
+    }
 
     _pending_removal = pending_removal;
   }
--- a/src/share/vm/gc_implementation/g1/heapRegionSeq.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/gc_implementation/g1/heapRegionSeq.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -165,7 +165,7 @@
 
   assert(num_so_far <= num, "post-condition");
   if (num_so_far == num) {
-    // we find enough space for the humongous object
+    // we found enough space for the humongous object
     assert(from <= first && first < _regions.length(), "post-condition");
     assert(first < curr && (curr - first) == (int) num, "post-condition");
     for (int i = first; i < first + (int) num; ++i) {
--- a/src/share/vm/gc_implementation/g1/heapRegionSeq.hpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/gc_implementation/g1/heapRegionSeq.hpp	Mon Apr 04 19:23:29 2011 -0700
@@ -76,7 +76,8 @@
   // that are available for allocation.
   size_t free_suffix();
 
-  // Finds a contiguous set of empty regions of length num.
+  // Find a contiguous set of empty regions of length num and return
+  // the index of the first region or -1 if the search was unsuccessful.
   int find_contiguous(size_t num);
 
   // Apply the "doHeapRegion" method of "blk" to all regions in "this",
--- a/src/share/vm/gc_implementation/g1/heapRegionSet.cpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/gc_implementation/g1/heapRegionSet.cpp	Mon Apr 04 19:23:29 2011 -0700
@@ -42,7 +42,7 @@
   return region_num;
 }
 
-void HeapRegionSetBase::fill_in_ext_msg(hrl_ext_msg* msg, const char* message) {
+void HeapRegionSetBase::fill_in_ext_msg(hrs_ext_msg* msg, const char* message) {
   msg->append("[%s] %s "
               "ln: "SIZE_FORMAT" rn: "SIZE_FORMAT" "
               "cy: "SIZE_FORMAT" ud: "SIZE_FORMAT,
@@ -109,30 +109,30 @@
   // for the verification calls. If we do verification without the
   // appropriate locks and the set changes underneath our feet
   // verification might fail and send us on a wild goose chase.
-  hrl_assert_mt_safety_ok(this);
+  hrs_assert_mt_safety_ok(this);
 
   guarantee(( is_empty() && length() == 0 && region_num() == 0 &&
               total_used_bytes() == 0 && total_capacity_bytes() == 0) ||
             (!is_empty() && length() >= 0 && region_num() >= 0 &&
               total_used_bytes() >= 0 && total_capacity_bytes() >= 0),
-            hrl_ext_msg(this, "invariant"));
+            hrs_ext_msg(this, "invariant"));
 
   guarantee((!regions_humongous() && region_num() == length()) ||
             ( regions_humongous() && region_num() >= length()),
-            hrl_ext_msg(this, "invariant"));
+            hrs_ext_msg(this, "invariant"));
 
   guarantee(!regions_empty() || total_used_bytes() == 0,
-            hrl_ext_msg(this, "invariant"));
+            hrs_ext_msg(this, "invariant"));
 
   guarantee(total_used_bytes() <= total_capacity_bytes(),
-            hrl_ext_msg(this, "invariant"));
+            hrs_ext_msg(this, "invariant"));
 }
 
 void HeapRegionSetBase::verify_start() {
   // See comment in verify() about MT safety and verification.
-  hrl_assert_mt_safety_ok(this);
+  hrs_assert_mt_safety_ok(this);
   assert(!_verify_in_progress,
-         hrl_ext_msg(this, "verification should not be in progress"));
+         hrs_ext_msg(this, "verification should not be in progress"));
 
   // Do the basic verification first before we do the checks over the regions.
   HeapRegionSetBase::verify();
@@ -146,11 +146,11 @@
 
 void HeapRegionSetBase::verify_next_region(HeapRegion* hr) {
   // See comment in verify() about MT safety and verification.
-  hrl_assert_mt_safety_ok(this);
+  hrs_assert_mt_safety_ok(this);
   assert(_verify_in_progress,
-         hrl_ext_msg(this, "verification should be in progress"));
+         hrs_ext_msg(this, "verification should be in progress"));
 
-  guarantee(verify_region(hr, this), hrl_ext_msg(this, "region verification"));
+  guarantee(verify_region(hr, this), hrs_ext_msg(this, "region verification"));
 
   _calc_length               += 1;
   if (!hr->isHumongous()) {
@@ -164,28 +164,28 @@
 
 void HeapRegionSetBase::verify_end() {
   // See comment in verify() about MT safety and verification.
-  hrl_assert_mt_safety_ok(this);
+  hrs_assert_mt_safety_ok(this);
   assert(_verify_in_progress,
-         hrl_ext_msg(this, "verification should be in progress"));
+         hrs_ext_msg(this, "verification should be in progress"));
 
   guarantee(length() == _calc_length,
-            hrl_err_msg("[%s] length: "SIZE_FORMAT" should be == "
+            hrs_err_msg("[%s] length: "SIZE_FORMAT" should be == "
                         "calc length: "SIZE_FORMAT,
                         name(), length(), _calc_length));
 
   guarantee(region_num() == _calc_region_num,
-            hrl_err_msg("[%s] region num: "SIZE_FORMAT" should be == "
+            hrs_err_msg("[%s] region num: "SIZE_FORMAT" should be == "
                         "calc region num: "SIZE_FORMAT,
                         name(), region_num(), _calc_region_num));
 
   guarantee(total_capacity_bytes() == _calc_total_capacity_bytes,
-            hrl_err_msg("[%s] capacity bytes: "SIZE_FORMAT" should be == "
+            hrs_err_msg("[%s] capacity bytes: "SIZE_FORMAT" should be == "
                         "calc capacity bytes: "SIZE_FORMAT,
                         name(),
                         total_capacity_bytes(), _calc_total_capacity_bytes));
 
   guarantee(total_used_bytes() == _calc_total_used_bytes,
-            hrl_err_msg("[%s] used bytes: "SIZE_FORMAT" should be == "
+            hrs_err_msg("[%s] used bytes: "SIZE_FORMAT" should be == "
                         "calc used bytes: "SIZE_FORMAT,
                         name(), total_used_bytes(), _calc_total_used_bytes));
 
@@ -221,9 +221,9 @@
 //////////////////// HeapRegionSet ////////////////////
 
 void HeapRegionSet::update_from_proxy(HeapRegionSet* proxy_set) {
-  hrl_assert_mt_safety_ok(this);
-  hrl_assert_mt_safety_ok(proxy_set);
-  hrl_assert_sets_match(this, proxy_set);
+  hrs_assert_mt_safety_ok(this);
+  hrs_assert_mt_safety_ok(proxy_set);
+  hrs_assert_sets_match(this, proxy_set);
 
   verify_optional();
   proxy_set->verify_optional();
@@ -231,19 +231,19 @@
   if (proxy_set->is_empty()) return;
 
   assert(proxy_set->length() <= _length,
-         hrl_err_msg("[%s] proxy set length: "SIZE_FORMAT" "
+         hrs_err_msg("[%s] proxy set length: "SIZE_FORMAT" "
                      "should be <= length: "SIZE_FORMAT,
                      name(), proxy_set->length(), _length));
   _length -= proxy_set->length();
 
   assert(proxy_set->region_num() <= _region_num,
-         hrl_err_msg("[%s] proxy set region num: "SIZE_FORMAT" "
+         hrs_err_msg("[%s] proxy set region num: "SIZE_FORMAT" "
                      "should be <= region num: "SIZE_FORMAT,
                      name(), proxy_set->region_num(), _region_num));
   _region_num -= proxy_set->region_num();
 
   assert(proxy_set->total_used_bytes() <= _total_used_bytes,
-         hrl_err_msg("[%s] proxy set used bytes: "SIZE_FORMAT" "
+         hrs_err_msg("[%s] proxy set used bytes: "SIZE_FORMAT" "
                      "should be <= used bytes: "SIZE_FORMAT,
                      name(), proxy_set->total_used_bytes(),
                      _total_used_bytes));
@@ -257,13 +257,13 @@
 
 //////////////////// HeapRegionLinkedList ////////////////////
 
-void HeapRegionLinkedList::fill_in_ext_msg_extra(hrl_ext_msg* msg) {
+void HeapRegionLinkedList::fill_in_ext_msg_extra(hrs_ext_msg* msg) {
   msg->append(" hd: "PTR_FORMAT" tl: "PTR_FORMAT, head(), tail());
 }
 
 void HeapRegionLinkedList::add_as_tail(HeapRegionLinkedList* from_list) {
-  hrl_assert_mt_safety_ok(this);
-  hrl_assert_mt_safety_ok(from_list);
+  hrs_assert_mt_safety_ok(this);
+  hrs_assert_mt_safety_ok(from_list);
 
   verify_optional();
   from_list->verify_optional();
@@ -283,10 +283,10 @@
 #endif // ASSERT
 
   if (_tail != NULL) {
-    assert(length() >  0 && _head != NULL, hrl_ext_msg(this, "invariant"));
+    assert(length() >  0 && _head != NULL, hrs_ext_msg(this, "invariant"));
     _tail->set_next(from_list->_head);
   } else {
-    assert(length() == 0 && _head == NULL, hrl_ext_msg(this, "invariant"));
+    assert(length() == 0 && _head == NULL, hrs_ext_msg(this, "invariant"));
     _head = from_list->_head;
   }
   _tail = from_list->_tail;
@@ -301,12 +301,12 @@
 }
 
 void HeapRegionLinkedList::remove_all() {
-  hrl_assert_mt_safety_ok(this);
+  hrs_assert_mt_safety_ok(this);
   verify_optional();
 
   HeapRegion* curr = _head;
   while (curr != NULL) {
-    hrl_assert_region_ok(this, curr, this);
+    hrs_assert_region_ok(this, curr, this);
 
     HeapRegion* next = curr->next();
     curr->set_next(NULL);
@@ -319,9 +319,9 @@
 }
 
 void HeapRegionLinkedList::remove_all_pending(size_t target_count) {
-  hrl_assert_mt_safety_ok(this);
-  assert(target_count > 1, hrl_ext_msg(this, "pre-condition"));
-  assert(!is_empty(), hrl_ext_msg(this, "pre-condition"));
+  hrs_assert_mt_safety_ok(this);
+  assert(target_count > 1, hrs_ext_msg(this, "pre-condition"));
+  assert(!is_empty(), hrs_ext_msg(this, "pre-condition"));
 
   verify_optional();
   DEBUG_ONLY(size_t old_length = length();)
@@ -330,27 +330,27 @@
   HeapRegion* prev = NULL;
   size_t count = 0;
   while (curr != NULL) {
-    hrl_assert_region_ok(this, curr, this);
+    hrs_assert_region_ok(this, curr, this);
     HeapRegion* next = curr->next();
 
     if (curr->pending_removal()) {
       assert(count < target_count,
-             hrl_err_msg("[%s] should not come across more regions "
+             hrs_err_msg("[%s] should not come across more regions "
                          "pending for removal than target_count: "SIZE_FORMAT,
                          name(), target_count));
 
       if (prev == NULL) {
-        assert(_head == curr, hrl_ext_msg(this, "invariant"));
+        assert(_head == curr, hrs_ext_msg(this, "invariant"));
         _head = next;
       } else {
-        assert(_head != curr, hrl_ext_msg(this, "invariant"));
+        assert(_head != curr, hrs_ext_msg(this, "invariant"));
         prev->set_next(next);
       }
       if (next == NULL) {
-        assert(_tail == curr, hrl_ext_msg(this, "invariant"));
+        assert(_tail == curr, hrs_ext_msg(this, "invariant"));
         _tail = prev;
       } else {
-        assert(_tail != curr, hrl_ext_msg(this, "invariant"));
+        assert(_tail != curr, hrs_ext_msg(this, "invariant"));
       }
 
       curr->set_next(NULL);
@@ -371,10 +371,10 @@
   }
 
   assert(count == target_count,
-         hrl_err_msg("[%s] count: "SIZE_FORMAT" should be == "
+         hrs_err_msg("[%s] count: "SIZE_FORMAT" should be == "
                      "target_count: "SIZE_FORMAT, name(), count, target_count));
   assert(length() + target_count == old_length,
-         hrl_err_msg("[%s] new length should be consistent "
+         hrs_err_msg("[%s] new length should be consistent "
                      "new length: "SIZE_FORMAT" old length: "SIZE_FORMAT" "
                      "target_count: "SIZE_FORMAT,
                      name(), length(), old_length, target_count));
@@ -385,7 +385,7 @@
 void HeapRegionLinkedList::verify() {
   // See comment in HeapRegionSetBase::verify() about MT safety and
   // verification.
-  hrl_assert_mt_safety_ok(this);
+  hrs_assert_mt_safety_ok(this);
 
   // This will also do the basic verification too.
   verify_start();
@@ -399,7 +399,7 @@
 
     count += 1;
     guarantee(count < _unrealistically_long_length,
-              hrl_err_msg("[%s] the calculated length: "SIZE_FORMAT" "
+              hrs_err_msg("[%s] the calculated length: "SIZE_FORMAT" "
                           "seems very long, is there maybe a cycle? "
                           "curr: "PTR_FORMAT" prev0: "PTR_FORMAT" "
                           "prev1: "PTR_FORMAT" length: "SIZE_FORMAT,
@@ -410,7 +410,7 @@
     curr  = curr->next();
   }
 
-  guarantee(_tail == prev0, hrl_ext_msg(this, "post-condition"));
+  guarantee(_tail == prev0, hrs_ext_msg(this, "post-condition"));
 
   verify_end();
 }
--- a/src/share/vm/gc_implementation/g1/heapRegionSet.hpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/gc_implementation/g1/heapRegionSet.hpp	Mon Apr 04 19:23:29 2011 -0700
@@ -28,8 +28,8 @@
 #include "gc_implementation/g1/heapRegion.hpp"
 
 // Large buffer for some cases where the output might be larger than normal.
-#define HRL_ERR_MSG_BUFSZ 512
-typedef FormatBuffer<HRL_ERR_MSG_BUFSZ> hrl_err_msg;
+#define HRS_ERR_MSG_BUFSZ 512
+typedef FormatBuffer<HRS_ERR_MSG_BUFSZ> hrs_err_msg;
 
 // Set verification will be forced either if someone defines
 // HEAP_REGION_SET_FORCE_VERIFY to be 1, or in builds in which
@@ -45,10 +45,10 @@
 // (e.g., length, region num, used bytes sum) plus any shared
 // functionality (e.g., verification).
 
-class hrl_ext_msg;
+class hrs_ext_msg;
 
 class HeapRegionSetBase VALUE_OBJ_CLASS_SPEC {
-  friend class hrl_ext_msg;
+  friend class hrs_ext_msg;
 
 protected:
   static size_t calculate_region_num(HeapRegion* hr);
@@ -104,10 +104,10 @@
   virtual bool check_mt_safety() { return true; }
 
   // fill_in_ext_msg() writes the the values of the set's attributes
-  // in the custom err_msg (hrl_ext_msg). fill_in_ext_msg_extra()
+  // in the custom err_msg (hrs_ext_msg). fill_in_ext_msg_extra()
   // allows subclasses to append further information.
-  virtual void fill_in_ext_msg_extra(hrl_ext_msg* msg) { }
-  void fill_in_ext_msg(hrl_ext_msg* msg, const char* message);
+  virtual void fill_in_ext_msg_extra(hrs_ext_msg* msg) { }
+  void fill_in_ext_msg(hrs_ext_msg* msg, const char* message);
 
   // It updates the fields of the set to reflect hr being added to
   // the set.
@@ -170,9 +170,9 @@
 // the fields of the associated set. This can be very helpful in
 // diagnosing failures.
 
-class hrl_ext_msg : public hrl_err_msg {
+class hrs_ext_msg : public hrs_err_msg {
 public:
-  hrl_ext_msg(HeapRegionSetBase* set, const char* message) : hrl_err_msg("") {
+  hrs_ext_msg(HeapRegionSetBase* set, const char* message) : hrs_err_msg("") {
     set->fill_in_ext_msg(this, message);
   }
 };
@@ -180,25 +180,25 @@
 // These two macros are provided for convenience, to keep the uses of
 // these two asserts a bit more concise.
 
-#define hrl_assert_mt_safety_ok(_set_)                                        \
+#define hrs_assert_mt_safety_ok(_set_)                                        \
   do {                                                                        \
-    assert((_set_)->check_mt_safety(), hrl_ext_msg((_set_), "MT safety"));    \
+    assert((_set_)->check_mt_safety(), hrs_ext_msg((_set_), "MT safety"));    \
   } while (0)
 
-#define hrl_assert_region_ok(_set_, _hr_, _expected_)                         \
+#define hrs_assert_region_ok(_set_, _hr_, _expected_)                         \
   do {                                                                        \
     assert((_set_)->verify_region((_hr_), (_expected_)),                      \
-           hrl_ext_msg((_set_), "region verification"));                      \
+           hrs_ext_msg((_set_), "region verification"));                      \
   } while (0)
 
 //////////////////// HeapRegionSet ////////////////////
 
-#define hrl_assert_sets_match(_set1_, _set2_)                                 \
+#define hrs_assert_sets_match(_set1_, _set2_)                                 \
   do {                                                                        \
     assert(((_set1_)->regions_humongous() ==                                  \
                                             (_set2_)->regions_humongous()) && \
            ((_set1_)->regions_empty() == (_set2_)->regions_empty()),          \
-           hrl_err_msg("the contents of set %s and set %s should match",      \
+           hrs_err_msg("the contents of set %s and set %s should match",      \
                        (_set1_)->name(), (_set2_)->name()));                  \
   } while (0)
 
@@ -267,7 +267,7 @@
   HeapRegion* tail() { return _tail; }
 
 protected:
-  virtual void fill_in_ext_msg_extra(hrl_ext_msg* msg);
+  virtual void fill_in_ext_msg_extra(hrs_ext_msg* msg);
 
   // See the comment for HeapRegionSetBase::clear()
   virtual void clear();
@@ -309,10 +309,10 @@
   virtual void print_on(outputStream* out, bool print_contents = false);
 };
 
-//////////////////// HeapRegionLinkedList ////////////////////
+//////////////////// HeapRegionLinkedListIterator ////////////////////
 
-// Iterator class that provides a convenient way to iterator over the
-// regions in a HeapRegionLinkedList instance.
+// Iterator class that provides a convenient way to iterate over the
+// regions of a HeapRegionLinkedList instance.
 
 class HeapRegionLinkedListIterator : public StackObj {
 private:
--- a/src/share/vm/gc_implementation/g1/heapRegionSet.inline.hpp	Thu Mar 03 23:48:25 2011 -0800
+++ b/src/share/vm/gc_implementation/g1/heapRegionSet.inline.hpp	Mon Apr 04 19:23:29 2011 -0700
@@ -42,8 +42,8 @@
 }
 
 inline void HeapRegionSetBase::add_internal(HeapRegion* hr) {
-  hrl_assert_region_ok(this, hr, NULL);
-  assert(hr->next() == NULL, hrl_ext_msg(this, "should not already be linked"));
+  hrs_assert_region_ok(this, hr, NULL);
+  assert(hr->next() == NULL, hrs_ext_msg(this, "should not already be linked"));
 
   update_for_addition(hr);
   hr->set_containing_set(this);
@@ -51,7 +51,7 @@
 
 inline void HeapRegionSetBase::update_for_removal(HeapRegion* hr) {
   // Assumes the caller has already verified the region.
-  assert(_length > 0, hrl_ext_msg(this, "pre-condition"));
+  assert(_length > 0, hrs_ext_msg(this, "pre-condition"));
   _length -= 1;
 
   size_t region_num_diff;
@@ -61,22 +61,22 @@
     region_num_diff = calculate_region_num(hr);
   }
   assert(region_num_diff <= _region_num,
-         hrl_err_msg("[%s] region's region num: "SIZE_FORMAT" "
+         hrs_err_msg("[%s] region's region num: "SIZE_FORMAT" "
                      "should be <= region num: "SIZE_FORMAT,
                      name(), region_num_diff, _region_num));
   _region_num -= region_num_diff;
 
   size_t used_bytes = hr->used();
   assert(used_bytes <= _total_used_bytes,
-         hrl_err_msg("[%s] region's used bytes: "SIZE_FORMAT" "
+         hrs_err_msg("[%s] region's used bytes: "SIZE_FORMAT" "
                      "should be <= used bytes: "SIZE_FORMAT,
                      name(), used_bytes, _total_used_bytes));
   _total_used_bytes -= used_bytes;
 }
 
 inline void HeapRegionSetBase::remove_internal(HeapRegion* hr) {
-  hrl_assert_region_ok(this, hr, this);
-  assert(hr->next() == NULL, hrl_ext_msg(this, "should already be unlinked"));
+  hrs_assert_region_ok(this, hr, this);
+  assert(hr->next() == NULL, hrs_ext_msg(this, "should already be unlinked"));
 
   hr->set_containing_set(NULL);
   update_for_removal(hr);
@@ -85,13 +85,13 @@
 //////////////////// HeapRegionSet ////////////////////
 
 inline void HeapRegionSet::add(HeapRegion* hr) {
-  hrl_assert_mt_safety_ok(this);
+  hrs_assert_mt_safety_ok(this);
   // add_internal() will verify the region.
   add_internal(hr);
 }
 
 inline void HeapRegionSet::remove(HeapRegion* hr) {
-  hrl_assert_mt_safety_ok(this);
+  hrs_assert_mt_safety_ok(this);
   // remove_internal() will verify the region.
   remove_internal(hr);
 }
@@ -101,8 +101,8 @@
   // No need to fo the MT safety check here given that this method
   // does not update the contents of the set but instead accumulates
   // the changes in proxy_set which is assumed to be thread-local.
-  hrl_assert_sets_match(this, proxy_set);
-  hrl_assert_region_ok(this, hr, this);
+  hrs_assert_sets_match(this, proxy_set);
+  hrs_assert_region_ok(th