changeset 2340:208b6c560ff4

Merge
author vladidan
date Thu, 14 Apr 2011 11:02:05 -0400
parents c737922fd8bb 3449f5e02cc4
children a534c140904e 7ec4bb02d5f0
files src/share/vm/c1/c1_Instruction.cpp
diffstat 427 files changed, 5643 insertions(+), 3541 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Tue Apr 12 10:32:42 2011 -0400
+++ b/.hgtags	Thu Apr 14 11:02:05 2011 -0400
@@ -156,3 +156,9 @@
 1b3a350709e4325d759bb453ff3fb6a463270488 jdk7-b133
 447e6faab4a8755d4860c2366630729dbaec111c jdk7-b134
 3c76374706ea8a77e15aec8310e831e5734f8775 hs21-b04
+b898f0fc3cedc972d884d31a751afd75969531cf jdk7-b135
+b898f0fc3cedc972d884d31a751afd75969531cf hs21-b05
+bd586e392d93b7ed7a1636dcc8da2b6a4203a102 jdk7-b136
+bd586e392d93b7ed7a1636dcc8da2b6a4203a102 hs21-b06
+2dbcb4a4d8dace5fe78ceb563b134f1fb296cd8f jdk7-b137
+2dbcb4a4d8dace5fe78ceb563b134f1fb296cd8f hs21-b07
--- a/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java	Tue Apr 12 10:32:42 2011 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/agent/src/share/classes/sun/jvm/hotspot/HotSpotTypeDataBase.java	Tue Apr 12 10:32:42 2011 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/HotSpotTypeDataBase.java	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/agent/src/share/classes/sun/jvm/hotspot/interpreter/BytecodeLoadConstant.java	Tue Apr 12 10:32:42 2011 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/interpreter/BytecodeLoadConstant.java	Thu Apr 14 11:02:05 2011 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2010, 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
--- a/agent/src/share/classes/sun/jvm/hotspot/interpreter/BytecodeWithKlass.java	Tue Apr 12 10:32:42 2011 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/interpreter/BytecodeWithKlass.java	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/agent/src/share/classes/sun/jvm/hotspot/jdi/ClassObjectReferenceImpl.java	Tue Apr 12 10:32:42 2011 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/jdi/ClassObjectReferenceImpl.java	Thu Apr 14 11:02:05 2011 -0400
@@ -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
@@ -27,7 +27,7 @@
 import com.sun.jdi.*;
 import sun.jvm.hotspot.oops.Instance;
 import sun.jvm.hotspot.oops.Klass;
-import sun.jvm.hotspot.oops.OopUtilities;
+import sun.jvm.hotspot.oops.java_lang_Class;
 
 public class ClassObjectReferenceImpl extends ObjectReferenceImpl
                                       implements ClassObjectReference {
@@ -39,7 +39,7 @@
 
     public ReferenceType reflectedType() {
         if (reflectedType == null) {
-            Klass k = OopUtilities.classOopToKlass(ref());
+            Klass k = java_lang_Class.asKlass(ref());
             reflectedType = vm.referenceType(k);
         }
         return reflectedType;
--- a/agent/src/share/classes/sun/jvm/hotspot/memory/DictionaryEntry.java	Tue Apr 12 10:32:42 2011 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/memory/DictionaryEntry.java	Thu Apr 14 11:02:05 2011 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2005, 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
--- a/agent/src/share/classes/sun/jvm/hotspot/memory/LoaderConstraintEntry.java	Tue Apr 12 10:32:42 2011 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/memory/LoaderConstraintEntry.java	Thu Apr 14 11:02:05 2011 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 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
--- a/agent/src/share/classes/sun/jvm/hotspot/memory/PlaceholderEntry.java	Tue Apr 12 10:32:42 2011 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/memory/PlaceholderEntry.java	Thu Apr 14 11:02:05 2011 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 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
--- a/agent/src/share/classes/sun/jvm/hotspot/memory/StringTable.java	Tue Apr 12 10:32:42 2011 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/memory/StringTable.java	Thu Apr 14 11:02:05 2011 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/agent/src/share/classes/sun/jvm/hotspot/memory/SymbolTable.java	Tue Apr 12 10:32:42 2011 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/memory/SymbolTable.java	Thu Apr 14 11:02:05 2011 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2005, 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
--- a/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPool.java	Tue Apr 12 10:32:42 2011 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPool.java	Thu Apr 14 11:02:05 2011 -0400
@@ -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
@@ -331,8 +331,6 @@
     if (Assert.ASSERTS_ENABLED) {
       Assert.that(getTagAt(i).isInvokeDynamic(), "Corrupted constant pool");
     }
-    if (getTagAt(i).value() == JVM_CONSTANT_InvokeDynamicTrans)
-        return null;
     int bsmSpec = extractLowShortFromInt(this.getIntAt(i));
     TypeArray operands = getOperands();
     if (operands == null)  return null;  // safety first
@@ -368,7 +366,6 @@
     case JVM_CONSTANT_MethodHandle:       return "JVM_CONSTANT_MethodHandle";
     case JVM_CONSTANT_MethodType:         return "JVM_CONSTANT_MethodType";
     case JVM_CONSTANT_InvokeDynamic:      return "JVM_CONSTANT_InvokeDynamic";
-    case JVM_CONSTANT_InvokeDynamicTrans: return "JVM_CONSTANT_InvokeDynamic/transitional";
     case JVM_CONSTANT_Invalid:            return "JVM_CONSTANT_Invalid";
     case JVM_CONSTANT_UnresolvedClass:    return "JVM_CONSTANT_UnresolvedClass";
     case JVM_CONSTANT_UnresolvedClassInError:    return "JVM_CONSTANT_UnresolvedClassInError";
@@ -428,7 +425,6 @@
         case JVM_CONSTANT_MethodHandle:
         case JVM_CONSTANT_MethodType:
         case JVM_CONSTANT_InvokeDynamic:
-        case JVM_CONSTANT_InvokeDynamicTrans:
           visitor.doInt(new IntField(new NamedFieldIdentifier(nameForTag(ctag)), indexOffset(index), true), true);
           break;
         }
@@ -592,7 +588,6 @@
                   break;
               }
 
-              case JVM_CONSTANT_InvokeDynamicTrans:
               case JVM_CONSTANT_InvokeDynamic: {
                   dos.writeByte(cpConstType);
                   int value = getIntAt(ci);
--- a/agent/src/share/classes/sun/jvm/hotspot/oops/GenerateOopMap.java	Tue Apr 12 10:32:42 2011 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/GenerateOopMap.java	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/agent/src/share/classes/sun/jvm/hotspot/oops/Instance.java	Tue Apr 12 10:32:42 2011 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/Instance.java	Thu Apr 14 11:02:05 2011 -0400
@@ -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
@@ -64,7 +64,7 @@
 
   public void iterateFields(OopVisitor visitor, boolean doVMFields) {
     super.iterateFields(visitor, doVMFields);
-    ((InstanceKlass) getKlass()).iterateNonStaticFields(visitor);
+    ((InstanceKlass) getKlass()).iterateNonStaticFields(visitor, this);
   }
 
   public void printValueOn(PrintStream tty) {
--- a/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java	Tue Apr 12 10:32:42 2011 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java	Thu Apr 14 11:02:05 2011 -0400
@@ -241,6 +241,10 @@
   // Byteside of the header
   private static long headerSize;
 
+  public long getObjectSize(Oop object) {
+    return getSizeHelper() * VM.getVM().getAddressSize();
+  }
+
   public static long getHeaderSize() { return headerSize; }
 
   // Accessors for declared fields
@@ -459,7 +463,22 @@
       visitor.doCInt(vtableLen, true);
       visitor.doCInt(itableLen, true);
     }
+  }
 
+  /*
+   *  Visit the static fields of this InstanceKlass with the obj of
+   *  the visitor set to the oop holding the fields, which is
+   *  currently the java mirror.
+   */
+  public void iterateStaticFields(OopVisitor visitor) {
+    visitor.setObj(getJavaMirror());
+    visitor.prologue();
+    iterateStaticFieldsInternal(visitor);
+    visitor.epilogue();
+
+  }
+
+  void iterateStaticFieldsInternal(OopVisitor visitor) {
     TypeArray fields = getFields();
     int length = (int) fields.getLength();
     for (int index = 0; index < length; index += NEXT_OFFSET) {
@@ -477,9 +496,9 @@
     return getSuper();
   }
 
-  public void iterateNonStaticFields(OopVisitor visitor) {
+  public void iterateNonStaticFields(OopVisitor visitor, Oop obj) {
     if (getSuper() != null) {
-      ((InstanceKlass) getSuper()).iterateNonStaticFields(visitor);
+      ((InstanceKlass) getSuper()).iterateNonStaticFields(visitor, obj);
     }
     TypeArray fields = getFields();
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceMirrorKlass.java	Thu Apr 14 11:02:05 2011 -0400
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package sun.jvm.hotspot.oops;
+
+import java.io.*;
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.memory.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.types.*;
+import sun.jvm.hotspot.utilities.*;
+
+// An InstanceKlass is the VM level representation of a Java class.
+
+public class InstanceMirrorKlass extends InstanceKlass {
+  static {
+    VM.registerVMInitializedObserver(new Observer() {
+        public void update(Observable o, Object data) {
+          initialize(VM.getVM().getTypeDataBase());
+        }
+      });
+  }
+
+  private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+    // Just make sure it's there for now
+    Type type = db.lookupType("instanceMirrorKlass");
+  }
+
+  InstanceMirrorKlass(OopHandle handle, ObjectHeap heap) {
+    super(handle, heap);
+  }
+
+  public long getObjectSize(Oop o) {
+    return java_lang_Class.getOopSize(o) * VM.getVM().getAddressSize();
+  }
+
+  public void iterateNonStaticFields(OopVisitor visitor, Oop obj) {
+    super.iterateNonStaticFields(visitor, obj);
+    // Fetch the real klass from the mirror object
+    Klass klass = java_lang_Class.asKlass(obj);
+    if (klass instanceof InstanceKlass) {
+      ((InstanceKlass)klass).iterateStaticFields(visitor);
+    }
+  }
+}
--- a/agent/src/share/classes/sun/jvm/hotspot/oops/Klass.java	Tue Apr 12 10:32:42 2011 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/Klass.java	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/agent/src/share/classes/sun/jvm/hotspot/oops/Method.java	Tue Apr 12 10:32:42 2011 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/Method.java	Thu Apr 14 11:02:05 2011 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2004, 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
--- a/agent/src/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java	Tue Apr 12 10:32:42 2011 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java	Thu Apr 14 11:02:05 2011 -0400
@@ -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
@@ -362,7 +362,16 @@
         if (klass.equals(compiledICHolderKlassHandle))  return new CompiledICHolder(handle, this);
         if (klass.equals(methodDataKlassHandle))        return new MethodData(handle, this);
       }
-      if (klass.equals(instanceKlassKlassHandle))       return new InstanceKlass(handle, this);
+      if (klass.equals(instanceKlassKlassHandle)) {
+          InstanceKlass ik = new InstanceKlass(handle, this);
+          if (ik.getName().asString().equals("java/lang/Class")) {
+              // We would normally do this using the vtable style
+              // lookup but since it's not used for these currently
+              // it's simpler to just check for the name.
+              return new InstanceMirrorKlass(handle, this);
+          }
+          return ik;
+      }
       if (klass.equals(objArrayKlassKlassHandle))       return new ObjArrayKlass(handle, this);
       if (klass.equals(typeArrayKlassKlassHandle))      return new TypeArrayKlass(handle, this);
 
--- a/agent/src/share/classes/sun/jvm/hotspot/oops/Oop.java	Tue Apr 12 10:32:42 2011 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/Oop.java	Thu Apr 14 11:02:05 2011 -0400
@@ -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
@@ -103,12 +103,8 @@
   // Returns the byte size of this object
   public long getObjectSize() {
     Klass k = getKlass();
-    if (k instanceof InstanceKlass) {
-        return ((InstanceKlass)k).getSizeHelper()
-            * VM.getVM().getAddressSize();
-    }
-    // If it is not an instance, this method should be replaced.
-    return getHeaderSize();
+    // All other types should be overriding getObjectSize directly
+    return ((InstanceKlass)k).getObjectSize(this);
   }
 
   // Type test operations
--- a/agent/src/share/classes/sun/jvm/hotspot/oops/OopUtilities.java	Tue Apr 12 10:32:42 2011 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/OopUtilities.java	Thu Apr 14 11:02:05 2011 -0400
@@ -74,9 +74,6 @@
     private static int THREAD_STATUS_TERMINATED;
   */
 
-  // java.lang.Class fields
-  private static OopField hcKlassField;
-
   // java.util.concurrent.locks.AbstractOwnableSynchronizer fields
   private static OopField absOwnSyncOwnerThreadField;
 
@@ -268,27 +265,6 @@
     return null;
   }
 
-  // initialize fields for java.lang.Class
-  private static void initClassFields() {
-    if (hcKlassField == null) {
-       // 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) db.lookupType("java_lang_Class").getCIntegerField("klass_offset").getValue();
-       if (VM.getVM().isCompressedOopsEnabled()) {
-         hcKlassField = new NarrowOopField(new NamedFieldIdentifier("hc_klass"), hcKlassOffset, true);
-       } else {
-         hcKlassField = new OopField(new NamedFieldIdentifier("hc_klass"), hcKlassOffset, true);
-       }
-    }
-  }
-
-  /** get klassOop field at offset hc_klass_offset from a java.lang.Class object */
-  public static Klass classOopToKlass(Oop aClass) {
-    initClassFields();
-    return (Klass) hcKlassField.getValue(aClass);
-  }
-
   // initialize fields for j.u.c.l AbstractOwnableSynchornizer class
   private static void initAbsOwnSyncFields() {
     if (absOwnSyncOwnerThreadField == null) {
--- a/agent/src/share/classes/sun/jvm/hotspot/oops/Symbol.java	Tue Apr 12 10:32:42 2011 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/Symbol.java	Thu Apr 14 11:02:05 2011 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2004, 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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/java_lang_Class.java	Thu Apr 14 11:02:05 2011 -0400
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package sun.jvm.hotspot.oops;
+
+import java.util.*;
+
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.memory.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.types.Type;
+import sun.jvm.hotspot.types.TypeDataBase;
+import sun.jvm.hotspot.utilities.*;
+import sun.jvm.hotspot.jdi.JVMTIThreadState;
+
+/** A utility class encapsulating useful oop operations */
+
+// initialize fields for java.lang.Class
+public class java_lang_Class {
+
+  // java.lang.Class fields
+  static OopField klassField;
+  static IntField oopSizeField;
+
+  static {
+    VM.registerVMInitializedObserver(new Observer() {
+        public void update(Observable o, Object data) {
+          initialize(VM.getVM().getTypeDataBase());
+        }
+      });
+  }
+
+  private static synchronized void initialize(TypeDataBase db) {
+    // klass and oop_size are HotSpot magic fields and hence we can't
+    // find them from InstanceKlass for java.lang.Class.
+    Type jlc = db.lookupType("java_lang_Class");
+    int klassOffset = (int) jlc.getCIntegerField("klass_offset").getValue();
+    if (VM.getVM().isCompressedOopsEnabled()) {
+      klassField = new NarrowOopField(new NamedFieldIdentifier("klass"), klassOffset, true);
+    } else {
+      klassField = new OopField(new NamedFieldIdentifier("klass"), klassOffset, true);
+    }
+    int oopSizeOffset = (int) jlc.getCIntegerField("oop_size_offset").getValue();
+    oopSizeField = new IntField(new NamedFieldIdentifier("oop_size"), oopSizeOffset, true);
+  }
+
+  /** get klassOop field at offset hc_klass_offset from a java.lang.Class object */
+  public static Klass asKlass(Oop aClass) {
+    return (Klass) java_lang_Class.klassField.getValue(aClass);
+  }
+
+  /** get oop_size field at offset oop_size_offset from a java.lang.Class object */
+  public static long getOopSize(Oop aClass) {
+    return java_lang_Class.oopSizeField.getValue(aClass);
+  }
+}
--- a/agent/src/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java	Tue Apr 12 10:32:42 2011 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java	Thu Apr 14 11:02:05 2011 -0400
@@ -42,7 +42,7 @@
     public static final int JVM_CONSTANT_NameAndType        = 12;
     public static final int JVM_CONSTANT_MethodHandle       = 15;
     public static final int JVM_CONSTANT_MethodType         = 16;
-    public static final int JVM_CONSTANT_InvokeDynamicTrans = 17;  // only occurs in old class files
+    //     static final int JVM_CONSTANT_(unused)           = 17;
     public static final int JVM_CONSTANT_InvokeDynamic      = 18;
 
     // JVM_CONSTANT_MethodHandle subtypes
--- a/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java	Tue Apr 12 10:32:42 2011 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java	Thu Apr 14 11:02:05 2011 -0400
@@ -839,20 +839,18 @@
   }
 
   private void readSystemProperties() {
-     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(systemKls.getJavaMirror()));
-                                     } catch (Exception e) {
-                                        if (Assert.ASSERTS_ENABLED) {
-                                           e.printStackTrace();
-                                        }
-                                     }
-                                  }
-                               }
-                        }, false);
+    final InstanceKlass systemKls = getSystemDictionary().getSystemKlass();
+    systemKls.iterateStaticFields(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()));
+            } catch (Exception e) {
+              e.printStackTrace();
+            }
+          }
+        }
+      });
   }
 }
--- a/agent/src/share/classes/sun/jvm/hotspot/tools/FinalizerInfo.java	Tue Apr 12 10:32:42 2011 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/tools/FinalizerInfo.java	Thu Apr 14 11:02:05 2011 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 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
@@ -64,16 +64,16 @@
          */
         InstanceKlass ik =
             SystemDictionaryHelper.findInstanceKlass("java.lang.ref.Finalizer");
-        final OopField queueField[] = new OopField[1];
-        ik.iterateFields(new DefaultOopVisitor() {
+        final Oop[] queueref = new Oop[1];
+        ik.iterateStaticFields(new DefaultOopVisitor() {
             public void doOop(OopField field, boolean isVMField) {
-                String name = field.getID().getName();
-                if (name.equals("queue")) {
-                    queueField[0] = field;
-                }
+              String name = field.getID().getName();
+              if (name.equals("queue")) {
+                queueref[0] = field.getValue(getObj());
+              }
             }
-        }, false);
-        Oop queue = queueField[0].getValue(ik);
+          });
+        Oop queue = queueref[0];
 
         InstanceKlass k = (InstanceKlass) queue.getKlass();
 
--- a/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java	Tue Apr 12 10:32:42 2011 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java	Thu Apr 14 11:02:05 2011 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2010, 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
@@ -321,7 +321,6 @@
                      break;
                 }
 
-                case JVM_CONSTANT_InvokeDynamicTrans:
                 case JVM_CONSTANT_InvokeDynamic: {
                      dos.writeByte(cpConstType);
                      int value = cpool.getIntAt(ci);
--- a/agent/src/share/classes/sun/jvm/hotspot/types/Field.java	Tue Apr 12 10:32:42 2011 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/types/Field.java	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java	Tue Apr 12 10:32:42 2011 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java	Thu Apr 14 11:02:05 2011 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2010, 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
@@ -598,7 +598,6 @@
                buf.cell(Integer.toString(cpool.getIntAt(index)));
                break;
 
-            case JVM_CONSTANT_InvokeDynamicTrans:
             case JVM_CONSTANT_InvokeDynamic:
                buf.cell("JVM_CONSTANT_InvokeDynamic");
                buf.cell(genLowHighShort(cpool.getIntAt(index)) +
--- a/agent/src/share/classes/sun/jvm/hotspot/utilities/ConstantTag.java	Tue Apr 12 10:32:42 2011 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/utilities/ConstantTag.java	Thu Apr 14 11:02:05 2011 -0400
@@ -40,7 +40,7 @@
   private static int JVM_CONSTANT_NameAndType             = 12;
   private static int JVM_CONSTANT_MethodHandle            = 15;  // JSR 292
   private static int JVM_CONSTANT_MethodType              = 16;  // JSR 292
-  private static int JVM_CONSTANT_InvokeDynamicTrans      = 17;  // JSR 292, only occurs in old class files
+  //      static int JVM_CONSTANT_(unused)                = 17;  // JSR 292 early drafts only
   private static int JVM_CONSTANT_InvokeDynamic           = 18;  // JSR 292
   private static int JVM_CONSTANT_Invalid                 = 0;   // For bad value initialization
   private static int JVM_CONSTANT_UnresolvedClass         = 100; // Temporary tag until actual use
@@ -83,7 +83,6 @@
   public boolean isMethodHandle()     { return tag == JVM_CONSTANT_MethodHandle; }
   public boolean isMethodType()       { return tag == JVM_CONSTANT_MethodType; }
   public boolean isInvokeDynamic()    { return tag == JVM_CONSTANT_InvokeDynamic; }
-  public boolean isInvokeDynamicTrans() { return tag == JVM_CONSTANT_InvokeDynamicTrans; }
 
   public boolean isInvalid()          { return tag == JVM_CONSTANT_Invalid; }
 
--- a/agent/src/share/classes/sun/jvm/hotspot/utilities/Hashtable.java	Tue Apr 12 10:32:42 2011 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/utilities/Hashtable.java	Thu Apr 14 11:02:05 2011 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 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
--- a/agent/src/share/classes/sun/jvm/hotspot/utilities/HashtableEntry.java	Tue Apr 12 10:32:42 2011 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/utilities/HashtableEntry.java	Thu Apr 14 11:02:05 2011 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 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
--- a/agent/src/share/classes/sun/jvm/hotspot/utilities/HeapGXLWriter.java	Tue Apr 12 10:32:42 2011 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/utilities/HeapGXLWriter.java	Thu Apr 14 11:02:05 2011 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2007, 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
@@ -164,7 +164,7 @@
 
     protected void writeClass(Instance instance) throws IOException  {
         writeObjectHeader(instance);
-        Klass reflectedType = OopUtilities.classOopToKlass(instance);
+        Klass reflectedType = java_lang_Class.asKlass(instance);
         boolean isInstanceKlass = (reflectedType instanceof InstanceKlass);
         // reflectedType is null for primitive types (int.class etc).
         if (reflectedType != null) {
--- a/agent/src/share/classes/sun/jvm/hotspot/utilities/HeapHprofBinWriter.java	Tue Apr 12 10:32:42 2011 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/utilities/HeapHprofBinWriter.java	Thu Apr 14 11:02:05 2011 -0400
@@ -455,7 +455,7 @@
     }
 
     protected void writeClass(Instance instance) throws IOException {
-        Klass reflectedKlass = OopUtilities.classOopToKlass(instance);
+        Klass reflectedKlass = java_lang_Class.asKlass(instance);
         // dump instance record only for primitive type Class objects.
         // all other Class objects are covered by writeClassDumpRecords.
         if (reflectedKlass == null) {
--- a/agent/src/share/classes/sun/jvm/hotspot/utilities/ReversePtrsAnalysis.java	Tue Apr 12 10:32:42 2011 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/utilities/ReversePtrsAnalysis.java	Thu Apr 14 11:02:05 2011 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2008, 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
@@ -117,10 +117,10 @@
         public boolean doObj(Oop obj) {
           if (obj instanceof InstanceKlass) {
             final InstanceKlass ik = (InstanceKlass) obj;
-            ik.iterateFields(
+            ik.iterateStaticFields(
                new DefaultOopVisitor() {
                    public void doOop(OopField field, boolean isVMField) {
-                     Oop next = field.getValue(ik);
+                     Oop next = field.getValue(getObj());
                      LivenessPathElement lp = new LivenessPathElement(null,
                              new NamedFieldIdentifier("Static field \"" +
                                                 field.getID().getName() +
@@ -142,8 +142,7 @@
                        System.err.println();
                      }
                    }
-                 },
-               false);
+                 });
           }
                   return false;
         }
--- a/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/JSJavaFactoryImpl.java	Tue Apr 12 10:32:42 2011 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/JSJavaFactoryImpl.java	Thu Apr 14 11:02:05 2011 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 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
@@ -158,7 +158,7 @@
       } else if (className.equals(javaLangThread())) {
          res = new JSJavaThread(instance, this);
       } else if (className.equals(javaLangClass())) {
-         Klass reflectedType = OopUtilities.classOopToKlass(instance);
+         Klass reflectedType = java_lang_Class.asKlass(instance);
          if (reflectedType != null) {
              JSJavaKlass jk = newJSJavaKlass(reflectedType);
              // we don't support mirrors of VM internal Klasses
--- a/make/hotspot_version	Tue Apr 12 10:32:42 2011 -0400
+++ b/make/hotspot_version	Thu Apr 14 11:02:05 2011 -0400
@@ -35,7 +35,7 @@
 
 HS_MAJOR_VER=21
 HS_MINOR_VER=0
-HS_BUILD_NUMBER=05
+HS_BUILD_NUMBER=08
 
 JDK_MAJOR_VER=1
 JDK_MINOR_VER=7
--- a/make/linux/Makefile	Tue Apr 12 10:32:42 2011 -0400
+++ b/make/linux/Makefile	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/make/linux/makefiles/adlc.make	Tue Apr 12 10:32:42 2011 -0400
+++ b/make/linux/makefiles/adlc.make	Thu Apr 14 11:02:05 2011 -0400
@@ -102,7 +102,7 @@
 
 $(EXEC) : $(OBJECTS)
 	@echo Making adlc
-	$(QUIETLY) $(LINK_NOPROF.CC) -o $(EXEC) $(OBJECTS)
+	$(QUIETLY) $(HOST.LINK_NOPROF.CC) -o $(EXEC) $(OBJECTS)
 
 # Random dependencies:
 $(OBJECTS): opcodes.hpp classes.hpp adlc.hpp adlcVMDeps.hpp adlparse.hpp archDesc.hpp arena.hpp dict2.hpp filebuff.hpp forms.hpp formsopt.hpp formssel.hpp
@@ -204,14 +204,14 @@
 $(OUTDIR)/%.o: %.cpp
 	@echo Compiling $<
 	$(QUIETLY) $(REMOVE_TARGET)
-	$(QUIETLY) $(COMPILE.CC) -o $@ $< $(COMPILE_DONE)
+	$(QUIETLY) $(HOST.COMPILE.CC) -o $@ $< $(COMPILE_DONE)
 
 # Some object files are given a prefix, to disambiguate
 # them from objects of the same name built for the VM.
 $(OUTDIR)/adlc-%.o: %.cpp
 	@echo Compiling $<
 	$(QUIETLY) $(REMOVE_TARGET)
-	$(QUIETLY) $(COMPILE.CC) -o $@ $< $(COMPILE_DONE)
+	$(QUIETLY) $(HOST.COMPILE.CC) -o $@ $< $(COMPILE_DONE)
 
 # #########################################################################
 
--- a/make/linux/makefiles/arm.make	Tue Apr 12 10:32:42 2011 -0400
+++ b/make/linux/makefiles/arm.make	Thu Apr 14 11:02:05 2011 -0400
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
 # ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 #
 
--- a/make/linux/makefiles/gcc.make	Tue Apr 12 10:32:42 2011 -0400
+++ b/make/linux/makefiles/gcc.make	Thu Apr 14 11:02:05 2011 -0400
@@ -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
@@ -30,9 +30,13 @@
 ifdef CROSS_COMPILE_ARCH
 CPP = $(ALT_COMPILER_PATH)/g++
 CC  = $(ALT_COMPILER_PATH)/gcc
+HOSTCPP = g++
+HOSTCC  = gcc
 else
 CPP = g++
 CC  = gcc
+HOSTCPP = $(CPP)
+HOSTCC  = $(CC)
 endif
 
 AS  = $(CC) -c
--- a/make/linux/makefiles/mapfile-vers-debug	Tue Apr 12 10:32:42 2011 -0400
+++ b/make/linux/makefiles/mapfile-vers-debug	Thu Apr 14 11:02:05 2011 -0400
@@ -3,7 +3,7 @@
 #
 
 #
-# Copyright (c) 2002, 2010, 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
--- a/make/linux/makefiles/mapfile-vers-product	Tue Apr 12 10:32:42 2011 -0400
+++ b/make/linux/makefiles/mapfile-vers-product	Thu Apr 14 11:02:05 2011 -0400
@@ -3,7 +3,7 @@
 #
 
 #
-# Copyright (c) 2002, 2010, 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
--- a/make/linux/makefiles/ppc.make	Tue Apr 12 10:32:42 2011 -0400
+++ b/make/linux/makefiles/ppc.make	Thu Apr 14 11:02:05 2011 -0400
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
 # ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 #
 
--- a/make/linux/makefiles/rules.make	Tue Apr 12 10:32:42 2011 -0400
+++ b/make/linux/makefiles/rules.make	Thu Apr 14 11:02:05 2011 -0400
@@ -55,6 +55,14 @@
 LINK_LIB.CC     = $(CCC) $(LFLAGS) $(SHARED_FLAG)
 PREPROCESS.CC   = $(CC_COMPILE) -E
 
+# cross compiling the jvm with c2 requires host compilers to build
+# adlc tool
+
+HOST.CC_COMPILE      = $(HOSTCPP) $(CPPFLAGS) $(CFLAGS)
+HOST.COMPILE.CC      = $(HOST.CC_COMPILE) -c
+HOST.LINK_NOPROF.CC  = $(HOSTCPP) $(LFLAGS) $(AOUT_FLAGS)
+
+
 # Effect of REMOVE_TARGET is to delete out-of-date files during "gnumake -k".
 REMOVE_TARGET   = rm -f $@
 
--- a/make/linux/makefiles/sparcWorks.make	Tue Apr 12 10:32:42 2011 -0400
+++ b/make/linux/makefiles/sparcWorks.make	Thu Apr 14 11:02:05 2011 -0400
@@ -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
@@ -29,6 +29,9 @@
 CC  = cc
 AS  = $(CC) -c
 
+HOSTCPP = $(CPP)
+HOSTCC  = $(CC)
+
 ARCHFLAG = $(ARCHFLAG/$(BUILDARCH))
 ARCHFLAG/i486    = -m32
 ARCHFLAG/amd64   = -m64
--- a/make/linux/makefiles/top.make	Tue Apr 12 10:32:42 2011 -0400
+++ b/make/linux/makefiles/top.make	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/make/linux/makefiles/vm.make	Tue Apr 12 10:32:42 2011 -0400
+++ b/make/linux/makefiles/vm.make	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/make/solaris/makefiles/adlc.make	Tue Apr 12 10:32:42 2011 -0400
+++ b/make/solaris/makefiles/adlc.make	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/make/solaris/makefiles/buildtree.make	Tue Apr 12 10:32:42 2011 -0400
+++ b/make/solaris/makefiles/buildtree.make	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/make/solaris/makefiles/rules.make	Tue Apr 12 10:32:42 2011 -0400
+++ b/make/solaris/makefiles/rules.make	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/make/solaris/makefiles/top.make	Tue Apr 12 10:32:42 2011 -0400
+++ b/make/solaris/makefiles/top.make	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/make/solaris/makefiles/vm.make	Tue Apr 12 10:32:42 2011 -0400
+++ b/make/solaris/makefiles/vm.make	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/make/windows/create_obj_files.sh	Tue Apr 12 10:32:42 2011 -0400
+++ b/make/windows/create_obj_files.sh	Thu Apr 14 11:02:05 2011 -0400
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2010, 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
--- a/make/windows/makefiles/launcher.make	Tue Apr 12 10:32:42 2011 -0400
+++ b/make/windows/makefiles/launcher.make	Thu Apr 14 11:02:05 2011 -0400
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2010, 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
--- a/make/windows/makefiles/vm.make	Tue Apr 12 10:32:42 2011 -0400
+++ b/make/windows/makefiles/vm.make	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -2058,6 +2058,13 @@
   BasicType basic_type = default_type != NULL ? default_type->element_type()->basic_type() : T_ILLEGAL;
   if (basic_type == T_ARRAY) basic_type = T_OBJECT;
 
+#ifdef _LP64
+  // higher 32bits must be null
+  __ sra(dst_pos, 0, dst_pos);
+  __ sra(src_pos, 0, src_pos);
+  __ sra(length, 0, length);
+#endif
+
   // set up the arraycopy stub information
   ArrayCopyStub* stub = op->stub();
 
@@ -2065,20 +2072,36 @@
   // the known type isn't loaded since the code sanity checks
   // in debug mode and the type isn't required when we know the exact type
   // also check that the type is an array type.
-  // We also, for now, always call the stub if the barrier set requires a
-  // write_ref_pre barrier (which the stub does, but none of the optimized
-  // cases currently does).
-  if (op->expected_type() == NULL ||
-      Universe::heap()->barrier_set()->has_write_ref_pre_barrier()) {
+  if (op->expected_type() == NULL) {
     __ mov(src,     O0);
     __ mov(src_pos, O1);
     __ mov(dst,     O2);
     __ mov(dst_pos, O3);
     __ mov(length,  O4);
-    __ call_VM_leaf(tmp, CAST_FROM_FN_PTR(address, Runtime1::arraycopy));
-
-    __ br_zero(Assembler::less, false, Assembler::pn, O0, *stub->entry());
-    __ delayed()->nop();
+    address copyfunc_addr = StubRoutines::generic_arraycopy();
+
+    if (copyfunc_addr == NULL) { // Use C version if stub was not generated
+      __ call_VM_leaf(tmp, CAST_FROM_FN_PTR(address, Runtime1::arraycopy));
+    } else {
+#ifndef PRODUCT
+      if (PrintC1Statistics) {
+        address counter = (address)&Runtime1::_generic_arraycopystub_cnt;
+        __ inc_counter(counter, G1, G3);
+      }
+#endif
+      __ call_VM_leaf(tmp, copyfunc_addr);
+    }
+
+    if (copyfunc_addr != NULL) {
+      __ xor3(O0, -1, tmp);
+      __ sub(length, tmp, length);
+      __ add(src_pos, tmp, src_pos);
+      __ br_zero(Assembler::less, false, Assembler::pn, O0, *stub->entry());
+      __ delayed()->add(dst_pos, tmp, dst_pos);
+    } else {
+      __ br_zero(Assembler::less, false, Assembler::pn, O0, *stub->entry());
+      __ delayed()->nop();
+    }
     __ bind(*stub->continuation());
     return;
   }
@@ -2135,20 +2158,137 @@
     __ delayed()->nop();
   }
 
+  int shift = shift_amount(basic_type);
+
   if (flags & LIR_OpArrayCopy::type_check) {
-    if (UseCompressedOops) {
-      // We don't need decode because we just need to compare
-      __ lduw(src, oopDesc::klass_offset_in_bytes(), tmp);
-      __ lduw(dst, oopDesc::klass_offset_in_bytes(), tmp2);
-      __ cmp(tmp, tmp2);
-      __ br(Assembler::notEqual, false, Assembler::pt, *stub->entry());
+    // We don't know the array types are compatible
+    if (basic_type != T_OBJECT) {
+      // Simple test for basic type arrays
+      if (UseCompressedOops) {
+        // We don't need decode because we just need to compare
+        __ lduw(src, oopDesc::klass_offset_in_bytes(), tmp);
+        __ lduw(dst, oopDesc::klass_offset_in_bytes(), tmp2);
+        __ cmp(tmp, tmp2);
+        __ br(Assembler::notEqual, false, Assembler::pt, *stub->entry());
+      } else {
+        __ ld_ptr(src, oopDesc::klass_offset_in_bytes(), tmp);
+        __ ld_ptr(dst, oopDesc::klass_offset_in_bytes(), tmp2);
+        __ cmp(tmp, tmp2);
+        __ brx(Assembler::notEqual, false, Assembler::pt, *stub->entry());
+      }
+      __ delayed()->nop();
     } else {
-      __ ld_ptr(src, oopDesc::klass_offset_in_bytes(), tmp);
-      __ ld_ptr(dst, oopDesc::klass_offset_in_bytes(), tmp2);
-      __ cmp(tmp, tmp2);
-      __ brx(Assembler::notEqual, false, Assembler::pt, *stub->entry());
+      // For object arrays, if src is a sub class of dst then we can
+      // safely do the copy.
+      address copyfunc_addr = StubRoutines::checkcast_arraycopy();
+
+      Label cont, slow;
+      assert_different_registers(tmp, tmp2, G3, G1);
+
+      __ load_klass(src, G3);
+      __ load_klass(dst, G1);
+
+      __ check_klass_subtype_fast_path(G3, G1, tmp, tmp2, &cont, copyfunc_addr == NULL ? stub->entry() : &slow, NULL);
+
+      __ call(Runtime1::entry_for(Runtime1::slow_subtype_check_id), relocInfo::runtime_call_type);
+      __ delayed()->nop();
+
+      __ cmp(G3, 0);
+      if (copyfunc_addr != NULL) { // use stub if available
+        // src is not a sub class of dst so we have to do a
+        // per-element check.
+        __ br(Assembler::notEqual, false, Assembler::pt, cont);
+        __ delayed()->nop();
+
+        __ bind(slow);
+
+        int mask = LIR_OpArrayCopy::src_objarray|LIR_OpArrayCopy::dst_objarray;
+        if ((flags & mask) != mask) {
+          // Check that at least both of them object arrays.
+          assert(flags & mask, "one of the two should be known to be an object array");
+
+          if (!(flags & LIR_OpArrayCopy::src_objarray)) {
+            __ load_klass(src, tmp);
+          } else if (!(flags & LIR_OpArrayCopy::dst_objarray)) {
+            __ load_klass(dst, tmp);
+          }
+          int lh_offset = klassOopDesc::header_size() * HeapWordSize +
+            Klass::layout_helper_offset_in_bytes();
+
+          __ lduw(tmp, lh_offset, tmp2);
+
+          jint objArray_lh = Klass::array_layout_helper(T_OBJECT);
+          __ set(objArray_lh, tmp);
+          __ cmp(tmp, tmp2);
+          __ br(Assembler::notEqual, false, Assembler::pt,  *stub->entry());
+          __ delayed()->nop();
+        }
+
+        Register src_ptr = O0;
+        Register dst_ptr = O1;
+        Register len     = O2;
+        Register chk_off = O3;
+        Register super_k = O4;
+
+        __ add(src, arrayOopDesc::base_offset_in_bytes(basic_type), src_ptr);
+        if (shift == 0) {
+          __ add(src_ptr, src_pos, src_ptr);
+        } else {
+          __ sll(src_pos, shift, tmp);
+          __ add(src_ptr, tmp, src_ptr);
+        }
+
+        __ add(dst, arrayOopDesc::base_offset_in_bytes(basic_type), dst_ptr);
+        if (shift == 0) {
+          __ add(dst_ptr, dst_pos, dst_ptr);
+        } else {
+          __ sll(dst_pos, shift, tmp);
+          __ add(dst_ptr, tmp, dst_ptr);
+        }
+        __ mov(length, len);
+        __ load_klass(dst, tmp);
+
+        int ek_offset = (klassOopDesc::header_size() * HeapWordSize +
+                         objArrayKlass::element_klass_offset_in_bytes());
+        __ ld_ptr(tmp, ek_offset, super_k);
+
+        int sco_offset = (klassOopDesc::header_size() * HeapWordSize +
+                          Klass::super_check_offset_offset_in_bytes());
+        __ lduw(super_k, sco_offset, chk_off);
+
+        __ call_VM_leaf(tmp, copyfunc_addr);
+
+#ifndef PRODUCT
+        if (PrintC1Statistics) {
+          Label failed;
+          __ br_notnull(O0, false, Assembler::pn,  failed);
+          __ delayed()->nop();
+          __ inc_counter((address)&Runtime1::_arraycopy_checkcast_cnt, G1, G3);
+          __ bind(failed);
+        }
+#endif
+
+        __ br_null(O0, false, Assembler::pt,  *stub->continuation());
+        __ delayed()->xor3(O0, -1, tmp);
+
+#ifndef PRODUCT
+        if (PrintC1Statistics) {
+          __ inc_counter((address)&Runtime1::_arraycopy_checkcast_attempt_cnt, G1, G3);
+        }
+#endif
+
+        __ sub(length, tmp, length);
+        __ add(src_pos, tmp, src_pos);
+        __ br(Assembler::always, false, Assembler::pt, *stub->entry());
+        __ delayed()->add(dst_pos, tmp, dst_pos);
+
+        __ bind(cont);
+      } else {
+        __ br(Assembler::equal, false, Assembler::pn, *stub->entry());
+        __ delayed()->nop();
+        __ bind(cont);
+      }
     }
-    __ delayed()->nop();
   }
 
 #ifdef ASSERT
@@ -2207,14 +2347,18 @@
   }
 #endif
 
-  int shift = shift_amount(basic_type);
+#ifndef PRODUCT
+  if (PrintC1Statistics) {
+    address counter = Runtime1::arraycopy_count_address(basic_type);
+    __ inc_counter(counter, G1, G3);
+  }
+#endif
 
   Register src_ptr = O0;
   Register dst_ptr = O1;
   Register len     = O2;
 
   __ add(src, arrayOopDesc::base_offset_in_bytes(basic_type), src_ptr);
-  LP64_ONLY(__ sra(src_pos, 0, src_pos);) //higher 32bits must be null
   if (shift == 0) {
     __ add(src_ptr, src_pos, src_ptr);
   } else {
@@ -2223,7 +2367,6 @@
   }
 
   __ add(dst, arrayOopDesc::base_offset_in_bytes(basic_type), dst_ptr);
-  LP64_ONLY(__ sra(dst_pos, 0, dst_pos);) //higher 32bits must be null
   if (shift == 0) {
     __ add(dst_ptr, dst_pos, dst_ptr);
   } else {
@@ -2231,18 +2374,14 @@
     __ add(dst_ptr, tmp, dst_ptr);
   }
 
-  if (basic_type != T_OBJECT) {
-    if (shift == 0) {
-      __ mov(length, len);
-    } else {
-      __ sll(length, shift, len);
-    }
-    __ call_VM_leaf(tmp, CAST_FROM_FN_PTR(address, Runtime1::primitive_arraycopy));
-  } else {
-    // oop_arraycopy takes a length in number of elements, so don't scale it.
-    __ mov(length, len);
-    __ call_VM_leaf(tmp, CAST_FROM_FN_PTR(address, Runtime1::oop_arraycopy));
-  }
+  bool disjoint = (flags & LIR_OpArrayCopy::overlapping) == 0;
+  bool aligned = (flags & LIR_OpArrayCopy::unaligned) == 0;
+  const char *name;
+  address entry = StubRoutines::select_arraycopy_function(basic_type, aligned, disjoint, name, false);
+
+  // arraycopy stubs takes a length in number of elements, so don't scale it.
+  __ mov(length, len);
+  __ call_VM_leaf(tmp, entry);
 
   __ bind(*stub->continuation());
 }
--- a/src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
@@ -387,7 +387,7 @@
 
 void C1_MacroAssembler::verify_not_null_oop(Register r) {
   Label not_null;
-  br_zero(Assembler::notEqual, false, Assembler::pt, r, not_null);
+  br_notnull(r, false, Assembler::pt, not_null);
   delayed()->nop();
   stop("non-null oop required");
   bind(not_null);
--- a/src/cpu/sparc/vm/cppInterpreter_sparc.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/cpu/sparc/vm/cppInterpreter_sparc.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -1188,8 +1188,8 @@
   __ st_ptr(O2, XXX_STATE(_stack));                // PREPUSH
 
   __ lduh(max_stack, O3);                      // Full size expression stack
-  guarantee(!EnableMethodHandles, "no support yet for java.lang.invoke.MethodHandle"); //6815692
-  //6815692//if (EnableMethodHandles)
+  guarantee(!EnableInvokeDynamic, "no support yet for java.lang.invoke.MethodHandle"); //6815692
+  //6815692//if (EnableInvokeDynamic)
   //6815692//  __ inc(O3, methodOopDesc::extra_stack_entries());
   __ sll(O3, LogBytesPerWord, O3);
   __ sub(O2, O3, O3);
--- a/src/cpu/sparc/vm/dump_sparc.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/cpu/sparc/vm/dump_sparc.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2010, 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
--- a/src/cpu/sparc/vm/interp_masm_sparc.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/cpu/sparc/vm/interp_masm_sparc.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -743,12 +743,12 @@
   if (index_size == sizeof(u2)) {
     get_2_byte_integer_at_bcp(bcp_offset, cache, tmp, Unsigned);
   } else if (index_size == sizeof(u4)) {
-    assert(EnableInvokeDynamic, "giant index used only for EnableInvokeDynamic");
+    assert(EnableInvokeDynamic, "giant index used only for JSR 292");
     get_4_byte_integer_at_bcp(bcp_offset, cache, tmp);
     assert(constantPoolCacheOopDesc::decode_secondary_index(~123) == 123, "else change next line");
     xor3(tmp, -1, tmp);  // convert to plain index
   } else if (index_size == sizeof(u1)) {
-    assert(EnableMethodHandles, "tiny index used only for EnableMethodHandles");
+    assert(EnableInvokeDynamic, "tiny index used only for JSR 292");
     ldub(Lbcp, bcp_offset, tmp);
   } else {
     ShouldNotReachHere();
--- a/src/cpu/sparc/vm/interpreter_sparc.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/cpu/sparc/vm/interpreter_sparc.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -262,7 +262,7 @@
 // Method handle invoker
 // Dispatch a method of the form java.lang.invoke.MethodHandles::invoke(...)
 address InterpreterGenerator::generate_method_handle_entry(void) {
-  if (!EnableMethodHandles) {
+  if (!EnableInvokeDynamic) {
     return generate_abstract_entry();
   }
 
--- a/src/cpu/sparc/vm/jni_sparc.h	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/cpu/sparc/vm/jni_sparc.h	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/cpu/sparc/vm/nativeInst_sparc.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/cpu/sparc/vm/nativeInst_sparc.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/cpu/sparc/vm/nativeInst_sparc.hpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/cpu/sparc/vm/nativeInst_sparc.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/cpu/sparc/vm/relocInfo_sparc.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/cpu/sparc/vm/relocInfo_sparc.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/cpu/sparc/vm/sharedRuntime_sparc.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/cpu/sparc/vm/sharedRuntime_sparc.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
@@ -1769,6 +1769,7 @@
 // returns.
 nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
                                                 methodHandle method,
+                                                int compile_id,
                                                 int total_in_args,
                                                 int comp_args_on_stack, // in VMRegStackSlots
                                                 BasicType *in_sig_bt,
@@ -2462,6 +2463,7 @@
   __ flush();
 
   nmethod *nm = nmethod::new_native_nmethod(method,
+                                            compile_id,
                                             masm->code(),
                                             vep_offset,
                                             frame_complete,
--- a/src/cpu/sparc/vm/sparc.ad	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/cpu/sparc/vm/sparc.ad	Thu Apr 14 11:02:05 2011 -0400
@@ -1843,6 +1843,10 @@
 // registers?  True for Intel but false for most RISCs
 const bool Matcher::clone_shift_expressions = false;
 
+// Do we need to mask the count passed to shift instructions or does
+// the cpu only look at the lower 5/6 bits anyway?
+const bool Matcher::need_masked_shift_count = false;
+
 bool Matcher::narrow_oop_use_complex_address() {
   NOT_LP64(ShouldNotCallThis());
   assert(UseCompressedOops, "only for compressed oops code");
--- a/src/cpu/sparc/vm/templateTable_sparc.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/cpu/sparc/vm/templateTable_sparc.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -334,8 +334,8 @@
 void TemplateTable::fast_aldc(bool wide) {
   transition(vtos, atos);
 
-  if (!EnableMethodHandles) {
-    // We should not encounter this bytecode if !EnableMethodHandles.
+  if (!EnableInvokeDynamic) {
+    // We should not encounter this bytecode if !EnableInvokeDynamic.
     // The verifier will stop it.  However, if we get past the verifier,
     // this will stop the thread in a reasonable way, without crashing the JVM.
     __ call_VM(noreg, CAST_FROM_FN_PTR(address,
--- a/src/cpu/x86/vm/assembler_x86.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/cpu/x86/vm/assembler_x86.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -3510,7 +3510,6 @@
   // anywhere in the codeCache then we are always reachable.
   // This would have to change if we ever save/restore shared code
   // to be more pessimistic.
-
   disp = (int64_t)adr._target - ((int64_t)CodeCache::low_bound() + sizeof(int));
   if (!is_simm32(disp)) return false;
   disp = (int64_t)adr._target - ((int64_t)CodeCache::high_bound() + sizeof(int));
@@ -3534,6 +3533,14 @@
   return is_simm32(disp);
 }
 
+// Check if the polling page is not reachable from the code cache using rip-relative
+// addressing.
+bool Assembler::is_polling_page_far() {
+  intptr_t addr = (intptr_t)os::get_polling_page();
+  return !is_simm32(addr - (intptr_t)CodeCache::low_bound()) ||
+         !is_simm32(addr - (intptr_t)CodeCache::high_bound());
+}
+
 void Assembler::emit_data64(jlong data,
                             relocInfo::relocType rtype,
                             int format) {
@@ -6886,6 +6893,11 @@
   }
 }
 
+void MacroAssembler::testl(Register dst, AddressLiteral src) {
+  assert(reachable(src), "Address should be reachable");
+  testl(dst, as_Address(src));
+}
+
 //////////////////////////////////////////////////////////////////////////////////
 #ifndef SERIALGC
 
@@ -7121,17 +7133,6 @@
   LP64_ONLY(subq(dst, src)) NOT_LP64(subl(dst, src));
 }
 
-void MacroAssembler::test32(Register src1, AddressLiteral src2) {
-  // src2 must be rval
-
-  if (reachable(src2)) {
-    testl(src1, as_Address(src2));
-  } else {
-    lea(rscratch1, src2);
-    testl(src1, Address(rscratch1, 0));
-  }
-}
-
 // C++ bool manipulation
 void MacroAssembler::testbool(Register dst) {
   if(sizeof(bool) == 1)
@@ -7768,6 +7769,28 @@
   }
 }
 
+void MacroAssembler::cmov32(Condition cc, Register dst, Address src) {
+  if (VM_Version::supports_cmov()) {
+    cmovl(cc, dst, src);
+  } else {
+    Label L;
+    jccb(negate_condition(cc), L);
+    movl(dst, src);
+    bind(L);
+  }
+}
+
+void MacroAssembler::cmov32(Condition cc, Register dst, Register src) {
+  if (VM_Version::supports_cmov()) {
+    cmovl(cc, dst, src);
+  } else {
+    Label L;
+    jccb(negate_condition(cc), L);
+    movl(dst, src);
+    bind(L);
+  }
+}
+
 void MacroAssembler::verify_oop(Register reg, const char* s) {
   if (!VerifyOops) return;
 
@@ -7918,12 +7941,12 @@
 #endif
   push(rax);                          // save rax,
   // addr may contain rsp so we will have to adjust it based on the push
-  // we just did
+  // we just did (and on 64 bit we do two pushes)
   // NOTE: 64bit seemed to have had a bug in that it did movq(addr, rax); which
   // stores rax into addr which is backwards of what was intended.
   if (addr.uses(rsp)) {
     lea(rax, addr);
-    pushptr(Address(rax, BytesPerWord));
+    pushptr(Address(rax, LP64_ONLY(2 *) BytesPerWord));
   } else {
     pushptr(addr);
   }
@@ -8373,6 +8396,17 @@
     movptr(dst, src);
 }
 
+// Doesn't do verfication, generates fixed size code
+void MacroAssembler::load_heap_oop_not_null(Register dst, Address src) {
+#ifdef _LP64
+  if (UseCompressedOops) {
+    movl(dst, src);
+    decode_heap_oop_not_null(dst);
+  } else
+#endif
+    movptr(dst, src);
+}
+
 void MacroAssembler::store_heap_oop(Address dst, Register src) {
 #ifdef _LP64
   if (UseCompressedOops) {
@@ -9018,14 +9052,7 @@
   movl(result, cnt1);
   subl(cnt1, cnt2);
   push(cnt1);
-  if (VM_Version::supports_cmov()) {
-    cmovl(Assembler::lessEqual, cnt2, result);
-  } else {
-    Label GT_LABEL;
-    jccb(Assembler::greater, GT_LABEL);
-    movl(cnt2, result);
-    bind(GT_LABEL);
-  }
+  cmov32(Assembler::lessEqual, cnt2, result);
 
   // Is the minimum length zero?
   testl(cnt2, cnt2);
--- a/src/cpu/x86/vm/assembler_x86.hpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/cpu/x86/vm/assembler_x86.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -385,10 +385,18 @@
 };
 
 class ExternalAddress: public AddressLiteral {
-
-  public:
-
-  ExternalAddress(address target) : AddressLiteral(target, relocInfo::external_word_type){}
+ private:
+  static relocInfo::relocType reloc_for_target(address target) {
+    // Sometimes ExternalAddress is used for values which aren't
+    // exactly addresses, like the card table base.
+    // external_word_type can't be used for values in the first page
+    // so just skip the reloc in that case.
+    return external_word_Relocation::can_be_relocated(target) ? relocInfo::external_word_type : relocInfo::none;
+  }
+
+ public:
+
+  ExternalAddress(address target) : AddressLiteral(target, reloc_for_target(target)) {}
 
 };
 
@@ -580,7 +588,6 @@
   void emit_data64(jlong data, relocInfo::relocType rtype, int format = 0);
   void emit_data64(jlong data, RelocationHolder const& rspec, int format = 0);
 
-
   bool reachable(AddressLiteral adr) NOT_LP64({ return true;});
 
   // These are all easily abused and hence protected
@@ -683,6 +690,8 @@
  static bool is_simm32(int32_t x) { return true; }
 #endif // _LP64
 
+  static bool is_polling_page_far() NOT_LP64({ return false;});
+
   // Generic instructions
   // Does 32bit or 64bit as needed for the platform. In some sense these
   // belong in macro assembler but there is no need for both varieties to exist
@@ -1700,6 +1709,7 @@
   void store_klass(Register dst, Register src);
 
   void load_heap_oop(Register dst, Address src);
+  void load_heap_oop_not_null(Register dst, Address src);
   void store_heap_oop(Address dst, Register src);
 
   // Used for storing NULL. All other oop constants should be
@@ -2094,7 +2104,10 @@
 
   void leal32(Register dst, Address src) { leal(dst, src); }
 
-  void test32(Register src1, AddressLiteral src2);
+  // Import other testl() methods from the parent class or else
+  // they will be hidden by the following overriding declaration.
+  using Assembler::testl;
+  void testl(Register dst, AddressLiteral src);
 
   void orptr(Register dst, Address src) { LP64_ONLY(orq(dst, src)) NOT_LP64(orl(dst, src)); }
   void orptr(Register dst, Register src) { LP64_ONLY(orq(dst, src)) NOT_LP64(orl(dst, src)); }
@@ -2240,10 +2253,13 @@
 
   // Data
 
-  void cmov(Condition cc, Register dst, Register src) { LP64_ONLY(cmovq(cc, dst, src)) NOT_LP64(cmovl(cc, dst, src)); }
-
-  void cmovptr(Condition cc, Register dst, Address src) { LP64_ONLY(cmovq(cc, dst, src)) NOT_LP64(cmovl(cc, dst, src)); }
-  void cmovptr(Condition cc, Register dst, Register src) { LP64_ONLY(cmovq(cc, dst, src)) NOT_LP64(cmovl(cc, dst, src)); }
+  void cmov32( Condition cc, Register dst, Address  src);
+  void cmov32( Condition cc, Register dst, Register src);
+
+  void cmov(   Condition cc, Register dst, Register src) { cmovptr(cc, dst, src); }
+
+  void cmovptr(Condition cc, Register dst, Address  src) { LP64_ONLY(cmovq(cc, dst, src)) NOT_LP64(cmov32(cc, dst, src)); }
+  void cmovptr(Condition cc, Register dst, Register src) { LP64_ONLY(cmovq(cc, dst, src)) NOT_LP64(cmov32(cc, dst, src)); }
 
   void movoop(Register dst, jobject obj);
   void movoop(Address dst, jobject obj);
--- a/src/cpu/x86/vm/c1_CodeStubs_x86.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/cpu/x86/vm/c1_CodeStubs_x86.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -316,7 +316,9 @@
     Register tmp2 = rbx;
     __ push(tmp);
     __ push(tmp2);
-    __ load_heap_oop(tmp2, Address(_obj, java_lang_Class::klass_offset_in_bytes()));
+    // Load without verification to keep code size small. We need it because
+    // begin_initialized_entry_offset has to fit in a byte. Also, we know it's not null.
+    __ load_heap_oop_not_null(tmp2, Address(_obj, java_lang_Class::klass_offset_in_bytes()));
     __ get_thread(tmp);
     __ cmpptr(tmp, Address(tmp2, instanceKlass::init_thread_offset_in_bytes() + sizeof(klassOopDesc)));
     __ pop(tmp2);
--- a/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "asm/assembler.hpp"
 #include "c1/c1_Compilation.hpp"
 #include "c1/c1_LIRAssembler.hpp"
 #include "c1/c1_MacroAssembler.hpp"
@@ -569,24 +570,13 @@
   __ lea          (rdi, Address(rdi, rcx, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR)));
 
   // compute minimum length (in rax) and difference of lengths (on top of stack)
-  if (VM_Version::supports_cmov()) {
-    __ movl     (rbx, Address(rbx, java_lang_String::count_offset_in_bytes()));
-    __ movl     (rax, Address(rax, java_lang_String::count_offset_in_bytes()));
-    __ mov      (rcx, rbx);
-    __ subptr   (rbx, rax); // subtract lengths
-    __ push     (rbx);      // result
-    __ cmov     (Assembler::lessEqual, rax, rcx);
-  } else {
-    Label L;
-    __ movl     (rbx, Address(rbx, java_lang_String::count_offset_in_bytes()));
-    __ movl     (rcx, Address(rax, java_lang_String::count_offset_in_bytes()));
-    __ mov      (rax, rbx);
-    __ subptr   (rbx, rcx);
-    __ push     (rbx);
-    __ jcc      (Assembler::lessEqual, L);
-    __ mov      (rax, rcx);
-    __ bind (L);
-  }
+  __ movl  (rbx, Address(rbx, java_lang_String::count_offset_in_bytes()));
+  __ movl  (rax, Address(rax, java_lang_String::count_offset_in_bytes()));
+  __ mov   (rcx, rbx);
+  __ subptr(rbx, rax); // subtract lengths
+  __ push  (rbx);      // result
+  __ cmov  (Assembler::lessEqual, rax, rcx);
+
   // is minimum length 0?
   Label noLoop, haveResult;
   __ testptr (rax, rax);
@@ -648,12 +638,13 @@
   AddressLiteral polling_page(os::get_polling_page() + (SafepointPollOffset % os::vm_page_size()),
                               relocInfo::poll_return_type);
 
-  // NOTE: the requires that the polling page be reachable else the reloc
-  // goes to the movq that loads the address and not the faulting instruction
-  // which breaks the signal handler code
-
-  __ test32(rax, polling_page);
-
+  if (Assembler::is_polling_page_far()) {
+    __ lea(rscratch1, polling_page);
+    __ relocate(relocInfo::poll_return_type);
+    __ testl(rax, Address(rscratch1, 0));
+  } else {
+    __ testl(rax, polling_page);
+  }
   __ ret(0);
 }
 
@@ -661,20 +652,17 @@
 int LIR_Assembler::safepoint_poll(LIR_Opr tmp, CodeEmitInfo* info) {
   AddressLiteral polling_page(os::get_polling_page() + (SafepointPollOffset % os::vm_page_size()),
                               relocInfo::poll_type);
-
-  if (info != NULL) {
+  guarantee(info != NULL, "Shouldn't be NULL");
+  int offset = __ offset();
+  if (Assembler::is_polling_page_far()) {
+    __ lea(rscratch1, polling_page);
+    offset = __ offset();
     add_debug_info_for_branch(info);
+    __ testl(rax, Address(rscratch1, 0));
   } else {
-    ShouldNotReachHere();
+    add_debug_info_for_branch(info);
+    __ testl(rax, polling_page);
   }
-
-  int offset = __ offset();
-
-  // NOTE: the requires that the polling page be reachable else the reloc
-  // goes to the movq that loads the address and not the faulting instruction
-  // which breaks the signal handler code
-
-  __ test32(rax, polling_page);
   return offset;
 }
 
@@ -3114,7 +3102,7 @@
   BasicType basic_type = default_type != NULL ? default_type->element_type()->basic_type() : T_ILLEGAL;
   if (basic_type == T_ARRAY) basic_type = T_OBJECT;
 
-  // if we don't know anything or it's an object array, just go through the generic arraycopy
+  // if we don't know anything, just go through the generic arraycopy
   if (default_type == NULL) {
     Label done;
     // save outgoing arguments on stack in case call to System.arraycopy is needed
@@ -3135,7 +3123,9 @@
     store_parameter(src, 4);
     NOT_LP64(assert(src == rcx && src_pos == rdx, "mismatch in calling convention");)
 
-    address entry = CAST_FROM_FN_PTR(address, Runtime1::arraycopy);
+    address C_entry = CAST_FROM_FN_PTR(address, Runtime1::arraycopy);
+
+    address copyfunc_addr = StubRoutines::generic_arraycopy();
 
     // pass arguments: may push as this is not a safepoint; SP must be fix at each safepoint
 #ifdef _LP64
@@ -3153,11 +3143,29 @@
     // Allocate abi space for args but be sure to keep stack aligned
     __ subptr(rsp, 6*wordSize);
     store_parameter(j_rarg4, 4);
-    __ call(RuntimeAddress(entry));
+    if (copyfunc_addr == NULL) { // Use C version if stub was not generated
+      __ call(RuntimeAddress(C_entry));
+    } else {
+#ifndef PRODUCT
+      if (PrintC1Statistics) {
+        __ incrementl(ExternalAddress((address)&Runtime1::_generic_arraycopystub_cnt));
+      }
+#endif
+      __ call(RuntimeAddress(copyfunc_addr));
+    }
     __ addptr(rsp, 6*wordSize);
 #else
     __ mov(c_rarg4, j_rarg4);
-    __ call(RuntimeAddress(entry));
+    if (copyfunc_addr == NULL) { // Use C version if stub was not generated
+      __ call(RuntimeAddress(C_entry));
+    } else {
+#ifndef PRODUCT
+      if (PrintC1Statistics) {
+        __ incrementl(ExternalAddress((address)&Runtime1::_generic_arraycopystub_cnt));
+      }
+#endif
+      __ call(RuntimeAddress(copyfunc_addr));
+    }
 #endif // _WIN64
 #else
     __ push(length);
@@ -3165,13 +3173,28 @@
     __ push(dst);
     __ push(src_pos);
     __ push(src);
-    __ call_VM_leaf(entry, 5); // removes pushed parameter from the stack
+
+    if (copyfunc_addr == NULL) { // Use C version if stub was not generated
+      __ call_VM_leaf(C_entry, 5); // removes pushed parameter from the stack
+    } else {
+#ifndef PRODUCT
+      if (PrintC1Statistics) {
+        __ incrementl(ExternalAddress((address)&Runtime1::_generic_arraycopystub_cnt));
+      }
+#endif
+      __ call_VM_leaf(copyfunc_addr, 5); // removes pushed parameter from the stack
+    }
 
 #endif // _LP64
 
     __ cmpl(rax, 0);
     __ jcc(Assembler::equal, *stub->continuation());
 
+    if (copyfunc_addr != NULL) {
+      __ mov(tmp, rax);
+      __ xorl(tmp, -1);
+    }
+
     // Reload values from the stack so they are where the stub
     // expects them.
     __ movptr   (dst,     Address(rsp, 0*BytesPerWord));
@@ -3179,6 +3202,12 @@
     __ movptr   (length,  Address(rsp, 2*BytesPerWord));
     __ movptr   (src_pos, Address(rsp, 3*BytesPerWord));
     __ movptr   (src,     Address(rsp, 4*BytesPerWord));
+
+    if (copyfunc_addr != NULL) {
+      __ subl(length, tmp);
+      __ addl(src_pos, tmp);
+      __ addl(dst_pos, tmp);
+    }
     __ jmp(*stub->entry());
 
     __ bind(*stub->continuation());
@@ -3238,10 +3267,6 @@
     __ testl(dst_pos, dst_pos);
     __ jcc(Assembler::less, *stub->entry());
   }
-  if (flags & LIR_OpArrayCopy::length_positive_check) {
-    __ testl(length, length);
-    __ jcc(Assembler::less, *stub->entry());
-  }
 
   if (flags & LIR_OpArrayCopy::src_range_check) {
     __ lea(tmp, Address(src_pos, length, Address::times_1, 0));
@@ -3254,15 +3279,190 @@
     __ jcc(Assembler::above, *stub->entry());
   }
 
+  if (flags & LIR_OpArrayCopy::length_positive_check) {
+    __ testl(length, length);
+    __ jcc(Assembler::less, *stub->entry());
+    __ jcc(Assembler::zero, *stub->continuation());
+  }
+
+#ifdef _LP64
+  __ movl2ptr(src_pos, src_pos); //higher 32bits must be null
+  __ movl2ptr(dst_pos, dst_pos); //higher 32bits must be null
+#endif
+
   if (flags & LIR_OpArrayCopy::type_check) {
-    if (UseCompressedOops) {
-      __ movl(tmp, src_klass_addr);
-      __ cmpl(tmp, dst_klass_addr);
+    // We don't know the array types are compatible
+    if (basic_type != T_OBJECT) {
+      // Simple test for basic type arrays
+      if (UseCompressedOops) {
+        __ movl(tmp, src_klass_addr);
+        __ cmpl(tmp, dst_klass_addr);
+      } else {
+        __ movptr(tmp, src_klass_addr);
+        __ cmpptr(tmp, dst_klass_addr);
+      }
+      __ jcc(Assembler::notEqual, *stub->entry());
     } else {
-      __ movptr(tmp, src_klass_addr);
-      __ cmpptr(tmp, dst_klass_addr);
+      // For object arrays, if src is a sub class of dst then we can
+      // safely do the copy.
+      Label cont, slow;
+
+      __ push(src);
+      __ push(dst);
+
+      __ load_klass(src, src);
+      __ load_klass(dst, dst);
+
+      __ check_klass_subtype_fast_path(src, dst, tmp, &cont, &slow, NULL);
+
+      __ push(src);
+      __ push(dst);
+      __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id)));
+      __ pop(dst);
+      __ pop(src);
+
+      __ cmpl(src, 0);
+      __ jcc(Assembler::notEqual, cont);
+
+      __ bind(slow);
+      __ pop(dst);
+      __ pop(src);
+
+      address copyfunc_addr = StubRoutines::checkcast_arraycopy();
+      if (copyfunc_addr != NULL) { // use stub if available
+        // src is not a sub class of dst so we have to do a
+        // per-element check.
+
+        int mask = LIR_OpArrayCopy::src_objarray|LIR_OpArrayCopy::dst_objarray;
+        if ((flags & mask) != mask) {
+          // Check that at least both of them object arrays.
+          assert(flags & mask, "one of the two should be known to be an object array");
+
+          if (!(flags & LIR_OpArrayCopy::src_objarray)) {
+            __ load_klass(tmp, src);
+          } else if (!(flags & LIR_OpArrayCopy::dst_objarray)) {
+            __ load_klass(tmp, dst);
+          }
+          int lh_offset = klassOopDesc::header_size() * HeapWordSize +
+            Klass::layout_helper_offset_in_bytes();
+          Address klass_lh_addr(tmp, lh_offset);
+          jint objArray_lh = Klass::array_layout_helper(T_OBJECT);
+          __ cmpl(klass_lh_addr, objArray_lh);
+          __ jcc(Assembler::notEqual, *stub->entry());
+        }
+
+#ifndef _LP64
+        // save caller save registers
+        store_parameter(rax, 2);
+        store_parameter(rcx, 1);
+        store_parameter(rdx, 0);
+
+        __ movptr(tmp, dst_klass_addr);
+        __ movptr(tmp, Address(tmp, objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc)));
+        __ push(tmp);
+        __ movl(tmp, Address(tmp, Klass::super_check_offset_offset_in_bytes() + sizeof(oopDesc)));
+        __ push(tmp);
+        __ push(length);
+        __ lea(tmp, Address(dst, dst_pos, scale, arrayOopDesc::base_offset_in_bytes(basic_type)));
+        __ push(tmp);
+        __ lea(tmp, Address(src, src_pos, scale, arrayOopDesc::base_offset_in_bytes(basic_type)));
+        __ push(tmp);
+
+        __ call_VM_leaf(copyfunc_addr, 5);
+#else
+        __ movl2ptr(length, length); //higher 32bits must be null
+
+        // save caller save registers: copy them to callee save registers
+        __ mov(rbx, rdx);
+        __ mov(r13, r8);
+        __ mov(r14, r9);
+#ifndef _WIN64
+        store_parameter(rsi, 1);
+        store_parameter(rcx, 0);
+        // on WIN64 other incoming parameters are in rdi and rsi saved
+        // across the call
+#endif
+
+        __ lea(c_rarg0, Address(src, src_pos, scale, arrayOopDesc::base_offset_in_bytes(basic_type)));
+        assert_different_registers(c_rarg0, dst, dst_pos, length);
+        __ lea(c_rarg1, Address(dst, dst_pos, scale, arrayOopDesc::base_offset_in_bytes(basic_type)));
+        assert_different_registers(c_rarg1, dst, length);
+
+        __ mov(c_rarg2, length);
+        assert_different_registers(c_rarg2, dst);
+
+#ifdef _WIN64
+        // Allocate abi space for args but be sure to keep stack aligned
+        __ subptr(rsp, 6*wordSize);
+        __ load_klass(c_rarg3, dst);
+        __ movptr(c_rarg3, Address(c_rarg3, objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc)));
+        store_parameter(c_rarg3, 4);
+        __ movl(c_rarg3, Address(c_rarg3, Klass::super_check_offset_offset_in_bytes() + sizeof(oopDesc)));
+        __ call(RuntimeAddress(copyfunc_addr));
+        __ addptr(rsp, 6*wordSize);
+#else
+        __ load_klass(c_rarg4, dst);
+        __ movptr(c_rarg4, Address(c_rarg4, objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc)));
+        __ movl(c_rarg3, Address(c_rarg4, Klass::super_check_offset_offset_in_bytes() + sizeof(oopDesc)));
+        __ call(RuntimeAddress(copyfunc_addr));
+#endif
+
+#endif
+
+#ifndef PRODUCT
+        if (PrintC1Statistics) {
+          Label failed;
+          __ testl(rax, rax);
+          __ jcc(Assembler::notZero, failed);
+          __ incrementl(ExternalAddress((address)&Runtime1::_arraycopy_checkcast_cnt));
+          __ bind(failed);
+        }
+#endif
+
+        __ testl(rax, rax);
+        __ jcc(Assembler::zero, *stub->continuation());
+
+#ifndef PRODUCT
+        if (PrintC1Statistics) {
+          __ incrementl(ExternalAddress((address)&Runtime1::_arraycopy_checkcast_attempt_cnt));
+        }
+#endif
+
+        __ mov(tmp, rax);
+
+        __ xorl(tmp, -1);
+
+#ifndef _LP64
+        // restore caller save registers
+        assert_different_registers(tmp, rdx, rcx, rax); // result of stub will be lost
+        __ movptr(rdx, Address(rsp, 0*BytesPerWord));
+        __ movptr(rcx, Address(rsp, 1*BytesPerWord));
+        __ movptr(rax, Address(rsp, 2*BytesPerWord));
+#else
+        // restore caller save registers
+        __ mov(rdx, rbx);
+        __ mov(r8, r13);
+        __ mov(r9, r14);
+#ifndef _WIN64
+        assert_different_registers(tmp, rdx, r8, r9, rcx, rsi); // result of stub will be lost
+        __ movptr(rcx, Address(rsp, 0*BytesPerWord));
+        __ movptr(rsi, Address(rsp, 1*BytesPerWord));
+#else
+        assert_different_registers(tmp, rdx, r8, r9); // result of stub will be lost
+#endif
+#endif
+
+        __ subl(length, tmp);
+        __ addl(src_pos, tmp);
+        __ addl(dst_pos, tmp);
+      }
+
+      __ jmp(*stub->entry());
+
+      __ bind(cont);
+      __ pop(dst);
+      __ pop(src);
     }
-    __ jcc(Assembler::notEqual, *stub->entry());
   }
 
 #ifdef ASSERT
@@ -3303,16 +3503,16 @@
   }
 #endif
 
-  if (shift_amount > 0 && basic_type != T_OBJECT) {
-    __ shlptr(length, shift_amount);
+#ifndef PRODUCT
+  if (PrintC1Statistics) {
+    __ incrementl(ExternalAddress(Runtime1::arraycopy_count_address(basic_type)));
   }
+#endif
 
 #ifdef _LP64
   assert_different_registers(c_rarg0, dst, dst_pos, length);
-  __ movl2ptr(src_pos, src_pos); //higher 32bits must be null
   __ lea(c_rarg0, Address(src, src_pos, scale, arrayOopDesc::base_offset_in_bytes(basic_type)));
   assert_different_registers(c_rarg1, length);
-  __ movl2ptr(dst_pos, dst_pos); //higher 32bits must be null
   __ lea(c_rarg1, Address(dst, dst_pos, scale, arrayOopDesc::base_offset_in_bytes(basic_type)));
   __ mov(c_rarg2, length);
 
@@ -3323,11 +3523,12 @@
   store_parameter(tmp, 1);
   store_parameter(length, 2);
 #endif // _LP64
-  if (basic_type == T_OBJECT) {
-    __ call_VM_leaf(CAST_FROM_FN_PTR(address, Runtime1::oop_arraycopy), 0);
-  } else {
-    __ call_VM_leaf(CAST_FROM_FN_PTR(address, Runtime1::primitive_arraycopy), 0);
-  }
+
+  bool disjoint = (flags & LIR_OpArrayCopy::overlapping) == 0;
+  bool aligned = (flags & LIR_OpArrayCopy::unaligned) == 0;
+  const char *name;
+  address entry = StubRoutines::select_arraycopy_function(basic_type, aligned, disjoint, name, false);
+  __ call_VM_leaf(entry, 0);
 
   __ bind(*stub->continuation());
 }
--- a/src/cpu/x86/vm/c1_Runtime1_x86.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/cpu/x86/vm/c1_Runtime1_x86.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "asm/assembler.hpp"
 #include "c1/c1_Defs.hpp"
 #include "c1/c1_MacroAssembler.hpp"
 #include "c1/c1_Runtime1.hpp"
--- a/src/cpu/x86/vm/frame_x86.hpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/cpu/x86/vm/frame_x86.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
@@ -125,7 +125,7 @@
     // Entry frames
 #ifdef AMD64
 #ifdef _WIN64
-    entry_frame_after_call_words                     =  8,
+    entry_frame_after_call_words                     =  28,
     entry_frame_call_wrapper_offset                  =  2,
 
     arg_reg_save_area_bytes                          = 32, // Register argument save area
--- a/src/cpu/x86/vm/interp_masm_x86_32.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/cpu/x86/vm/interp_masm_x86_32.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -215,7 +215,7 @@
   if (index_size == sizeof(u2)) {
     load_unsigned_short(reg, Address(rsi, bcp_offset));
   } else if (index_size == sizeof(u4)) {
-    assert(EnableInvokeDynamic, "giant index used only for EnableInvokeDynamic");
+    assert(EnableInvokeDynamic, "giant index used only for JSR 292");
     movl(reg, Address(rsi, bcp_offset));
     // Check if the secondary index definition is still ~x, otherwise
     // we have to change the following assembler code to calculate the
@@ -223,7 +223,7 @@
     assert(constantPoolCacheOopDesc::decode_secondary_index(~123) == 123, "else change next line");
     notl(reg);  // convert to plain index
   } else if (index_size == sizeof(u1)) {
-    assert(EnableMethodHandles, "tiny index used only for EnableMethodHandles");
+    assert(EnableInvokeDynamic, "tiny index used only for JSR 292");
     load_unsigned_byte(reg, Address(rsi, bcp_offset));
   } else {
     ShouldNotReachHere();
--- a/src/cpu/x86/vm/interp_masm_x86_64.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/cpu/x86/vm/interp_masm_x86_64.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -213,7 +213,7 @@
   if (index_size == sizeof(u2)) {
     load_unsigned_short(index, Address(r13, bcp_offset));
   } else if (index_size == sizeof(u4)) {
-    assert(EnableInvokeDynamic, "giant index used only for EnableInvokeDynamic");
+    assert(EnableInvokeDynamic, "giant index used only for JSR 292");
     movl(index, Address(r13, bcp_offset));
     // Check if the secondary index definition is still ~x, otherwise
     // we have to change the following assembler code to calculate the
@@ -221,7 +221,7 @@
     assert(constantPoolCacheOopDesc::decode_secondary_index(~123) == 123, "else change next line");
     notl(index);  // convert to plain index
   } else if (index_size == sizeof(u1)) {
-    assert(EnableMethodHandles, "tiny index used only for EnableMethodHandles");
+    assert(EnableInvokeDynamic, "tiny index used only for JSR 292");
     load_unsigned_byte(index, Address(r13, bcp_offset));
   } else {
     ShouldNotReachHere();
--- a/src/cpu/x86/vm/interpreter_x86_32.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/cpu/x86/vm/interpreter_x86_32.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -233,7 +233,7 @@
 // Method handle invoker
 // Dispatch a method of the form java.lang.invoke.MethodHandles::invoke(...)
 address InterpreterGenerator::generate_method_handle_entry(void) {
-  if (!EnableMethodHandles) {
+  if (!EnableInvokeDynamic) {
     return generate_abstract_entry();
   }
 
--- a/src/cpu/x86/vm/interpreter_x86_64.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/cpu/x86/vm/interpreter_x86_64.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -320,7 +320,7 @@
 // Method handle invoker
 // Dispatch a method of the form java.lang.invoke.MethodHandles::invoke(...)
 address InterpreterGenerator::generate_method_handle_entry(void) {
-  if (!EnableMethodHandles) {
+  if (!EnableInvokeDynamic) {
     return generate_abstract_entry();
   }
 
--- a/src/cpu/x86/vm/jni_x86.h	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/cpu/x86/vm/jni_x86.h	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/cpu/x86/vm/nativeInst_x86.hpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/cpu/x86/vm/nativeInst_x86.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
@@ -519,7 +519,11 @@
 class NativeTstRegMem: public NativeInstruction {
  public:
   enum Intel_specific_constants {
-    instruction_code_memXregl   = 0x85
+    instruction_rex_prefix_mask = 0xF0,
+    instruction_rex_prefix      = Assembler::REX,
+    instruction_code_memXregl   = 0x85,
+    modrm_mask                  = 0x38, // select reg from the ModRM byte
+    modrm_reg                   = 0x00  // rax
   };
 };
 
@@ -533,12 +537,25 @@
                                                           (ubyte_at(0) & 0xF0) == 0x70;  /* short jump */ }
 inline bool NativeInstruction::is_safepoint_poll() {
 #ifdef AMD64
-  if ( ubyte_at(0) == NativeTstRegMem::instruction_code_memXregl &&
-       ubyte_at(1) == 0x05 ) { // 00 rax 101
-     address fault = addr_at(6) + int_at(2);
-     return os::is_poll_address(fault);
+  if (Assembler::is_polling_page_far()) {
+    // two cases, depending on the choice of the base register in the address.
+    if (((ubyte_at(0) & NativeTstRegMem::instruction_rex_prefix_mask) == NativeTstRegMem::instruction_rex_prefix &&
+         ubyte_at(1) == NativeTstRegMem::instruction_code_memXregl &&
+         (ubyte_at(2) & NativeTstRegMem::modrm_mask) == NativeTstRegMem::modrm_reg) ||
+        ubyte_at(0) == NativeTstRegMem::instruction_code_memXregl &&
+        (ubyte_at(1) & NativeTstRegMem::modrm_mask) == NativeTstRegMem::modrm_reg) {
+      return true;
+    } else {
+      return false;
+    }
   } else {
-    return false;
+    if (ubyte_at(0) == NativeTstRegMem::instruction_code_memXregl &&
+        ubyte_at(1) == 0x05) { // 00 rax 101
+      address fault = addr_at(6) + int_at(2);
+      return os::is_poll_address(fault);
+    } else {
+      return false;
+    }
   }
 #else
   return ( ubyte_at(0) == NativeMovRegMem::instruction_code_mem2reg ||
--- a/src/cpu/x86/vm/relocInfo_x86.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/cpu/x86/vm/relocInfo_x86.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
@@ -198,41 +198,44 @@
 
 void poll_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) {
 #ifdef _LP64
-  typedef Assembler::WhichOperand WhichOperand;
-  WhichOperand which = (WhichOperand) format();
-  // This format is imm but it is really disp32
-  which = Assembler::disp32_operand;
-  address orig_addr = old_addr_for(addr(), src, dest);
-  NativeInstruction* oni = nativeInstruction_at(orig_addr);
-  int32_t* orig_disp = (int32_t*) Assembler::locate_operand(orig_addr, which);
-  // This poll_addr is incorrect by the size of the instruction it is irrelevant
-  intptr_t poll_addr = (intptr_t)oni + *orig_disp;
+  if (!Assembler::is_polling_page_far()) {
+    typedef Assembler::WhichOperand WhichOperand;
+    WhichOperand which = (WhichOperand) format();
+    // This format is imm but it is really disp32
+    which = Assembler::disp32_operand;
+    address orig_addr = old_addr_for(addr(), src, dest);
+    NativeInstruction* oni = nativeInstruction_at(orig_addr);
+    int32_t* orig_disp = (int32_t*) Assembler::locate_operand(orig_addr, which);
+    // This poll_addr is incorrect by the size of the instruction it is irrelevant
+    intptr_t poll_addr = (intptr_t)oni + *orig_disp;
 
-  NativeInstruction* ni = nativeInstruction_at(addr());
-  intptr_t new_disp = poll_addr - (intptr_t) ni;
+    NativeInstruction* ni = nativeInstruction_at(addr());
+    intptr_t new_disp = poll_addr - (intptr_t) ni;
 
-  int32_t* disp = (int32_t*) Assembler::locate_operand(addr(), which);
-  * disp = (int32_t)new_disp;
-
+    int32_t* disp = (int32_t*) Assembler::locate_operand(addr(), which);
+    * disp = (int32_t)new_disp;
+  }
 #endif // _LP64
 }
 
 void poll_return_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) {
 #ifdef _LP64
-  typedef Assembler::WhichOperand WhichOperand;
-  WhichOperand which = (WhichOperand) format();
-  // This format is imm but it is really disp32
-  which = Assembler::disp32_operand;
-  address orig_addr = old_addr_for(addr(), src, dest);
-  NativeInstruction* oni = nativeInstruction_at(orig_addr);
-  int32_t* orig_disp = (int32_t*) Assembler::locate_operand(orig_addr, which);
-  // This poll_addr is incorrect by the size of the instruction it is irrelevant
-  intptr_t poll_addr = (intptr_t)oni + *orig_disp;
+  if (!Assembler::is_polling_page_far()) {
+    typedef Assembler::WhichOperand WhichOperand;
+    WhichOperand which = (WhichOperand) format();
+    // This format is imm but it is really disp32
+    which = Assembler::disp32_operand;
+    address orig_addr = old_addr_for(addr(), src, dest);
+    NativeInstruction* oni = nativeInstruction_at(orig_addr);
+    int32_t* orig_disp = (int32_t*) Assembler::locate_operand(orig_addr, which);
+    // This poll_addr is incorrect by the size of the instruction it is irrelevant
+    intptr_t poll_addr = (intptr_t)oni + *orig_disp;
 
-  NativeInstruction* ni = nativeInstruction_at(addr());
-  intptr_t new_disp = poll_addr - (intptr_t) ni;
+    NativeInstruction* ni = nativeInstruction_at(addr());
+    intptr_t new_disp = poll_addr - (intptr_t) ni;
 
-  int32_t* disp = (int32_t*) Assembler::locate_operand(addr(), which);
-  * disp = (int32_t)new_disp;
+    int32_t* disp = (int32_t*) Assembler::locate_operand(addr(), which);
+    * disp = (int32_t)new_disp;
+  }
 #endif // _LP64
 }
--- a/src/cpu/x86/vm/sharedRuntime_x86_32.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/cpu/x86/vm/sharedRuntime_x86_32.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -1111,6 +1111,7 @@
 // returns.
 nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm,
                                                 methodHandle method,
+                                                int compile_id,
                                                 int total_in_args,
                                                 int comp_args_on_stack,
                                                 BasicType *in_sig_bt,
@@ -1854,6 +1855,7 @@
   __ flush();
 
   nmethod *nm = nmethod::new_native_nmethod(method,
+                                            compile_id,
                                             masm->code(),
                                             vep_offset,
                                             frame_complete,
--- a/src/cpu/x86/vm/sharedRuntime_x86_64.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/cpu/x86/vm/sharedRuntime_x86_64.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -1174,6 +1174,7 @@
 // returns.
 nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm,
                                                 methodHandle method,
+                                                int compile_id,
                                                 int total_in_args,
                                                 int comp_args_on_stack,
                                                 BasicType *in_sig_bt,
@@ -1881,6 +1882,7 @@
   __ flush();
 
   nmethod *nm = nmethod::new_native_nmethod(method,
+                                            compile_id,
                                             masm->code(),
                                             vep_offset,
                                             frame_complete,
--- a/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -144,8 +144,11 @@
   //     [ return_from_Java     ] <--- rsp
   //     [ argument word n      ]
   //      ...
-  //  -8 [ argument word 1      ]
-  //  -7 [ saved r15            ] <--- rsp_after_call
+  // -28 [ argument word 1      ]
+  // -27 [ saved xmm15          ] <--- rsp_after_call
+  //     [ saved xmm7-xmm14     ]
+  //  -9 [ saved xmm6           ] (each xmm register takes 2 slots)
+  //  -7 [ saved r15            ]
   //  -6 [ saved r14            ]
   //  -5 [ saved r13            ]
   //  -4 [ saved r12            ]
@@ -169,8 +172,11 @@
   // Call stub stack layout word offsets from rbp
   enum call_stub_layout {
 #ifdef _WIN64
-    rsp_after_call_off = -7,
-    r15_off            = rsp_after_call_off,
+    xmm_save_first     = 6,  // save from xmm6
+    xmm_save_last      = 15, // to xmm15
+    xmm_save_base      = -9,
+    rsp_after_call_off = xmm_save_base - 2 * (xmm_save_last - xmm_save_first), // -27
+    r15_off            = -7,
     r14_off            = -6,
     r13_off            = -5,
     r12_off            = -4,
@@ -208,6 +214,13 @@
 #endif
   };
 
+#ifdef _WIN64
+  Address xmm_save(int reg) {
+    assert(reg >= xmm_save_first && reg <= xmm_save_last, "XMM register number out of range");
+    return Address(rbp, (xmm_save_base - (reg - xmm_save_first) * 2) * wordSize);
+  }
+#endif
+
   address generate_call_stub(address& return_address) {
     assert((int)frame::entry_frame_after_call_words == -(int)rsp_after_call_off + 1 &&
            (int)frame::entry_frame_call_wrapper_offset == (int)call_wrapper_off,
@@ -256,8 +269,11 @@
     __ movptr(r13_save, r13);
     __ movptr(r14_save, r14);
     __ movptr(r15_save, r15);
-
 #ifdef _WIN64
+    for (int i = 6; i <= 15; i++) {
+      __ movdqu(xmm_save(i), as_XMMRegister(i));
+    }
+
     const Address rdi_save(rbp, rdi_off * wordSize);
     const Address rsi_save(rbp, rsi_off * wordSize);
 
@@ -360,6 +376,11 @@
 #endif
 
     // restore regs belonging to calling function
+#ifdef _WIN64
+    for (int i = 15; i >= 6; i--) {
+      __ movdqu(as_XMMRegister(i), xmm_save(i));
+    }
+#endif
     __ movptr(r15, r15_save);
     __ movptr(r14, r14_save);
     __ movptr(r13, r13_save);
@@ -2428,8 +2449,8 @@
   //
   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) {
+                                address int_copy_entry, address oop_copy_entry,
+                                address long_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;
--- a/src/cpu/x86/vm/templateInterpreter_x86_32.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/cpu/x86/vm/templateInterpreter_x86_32.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -1527,7 +1527,7 @@
 
   if (interpreter_frame != NULL) {
 #ifdef ASSERT
-    if (!EnableMethodHandles)
+    if (!EnableInvokeDynamic)
       // @@@ FIXME: Should we correct interpreter_frame_sender_sp in the calling sequences?
       // Probably, since deoptimization doesn't work yet.
       assert(caller->unextended_sp() == interpreter_frame->interpreter_frame_sender_sp(), "Frame not properly walkable");
--- a/src/cpu/x86/vm/templateInterpreter_x86_64.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/cpu/x86/vm/templateInterpreter_x86_64.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -1541,7 +1541,7 @@
          tempcount* Interpreter::stackElementWords + popframe_extra_args;
   if (interpreter_frame != NULL) {
 #ifdef ASSERT
-    if (!EnableMethodHandles)
+    if (!EnableInvokeDynamic)
       // @@@ FIXME: Should we correct interpreter_frame_sender_sp in the calling sequences?
       // Probably, since deoptimization doesn't work yet.
       assert(caller->unextended_sp() == interpreter_frame->interpreter_frame_sender_sp(), "Frame not properly walkable");
--- a/src/cpu/x86/vm/templateTable_x86_32.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/cpu/x86/vm/templateTable_x86_32.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "asm/assembler.hpp"
 #include "interpreter/interpreter.hpp"
 #include "interpreter/interpreterRuntime.hpp"
 #include "interpreter/templateTable.hpp"
@@ -391,8 +392,8 @@
 void TemplateTable::fast_aldc(bool wide) {
   transition(vtos, atos);
 
-  if (!EnableMethodHandles) {
-    // We should not encounter this bytecode if !EnableMethodHandles.
+  if (!EnableInvokeDynamic) {
+    // We should not encounter this bytecode if !EnableInvokeDynamic.
     // The verifier will stop it.  However, if we get past the verifier,
     // this will stop the thread in a reasonable way, without crashing the JVM.
     __ call_VM(noreg, CAST_FROM_FN_PTR(address,
@@ -1939,18 +1940,10 @@
     __ movl(temp, Address(array, h, Address::times_8, 0*wordSize));
     __ bswapl(temp);
     __ cmpl(key, temp);
-    if (VM_Version::supports_cmov()) {
-      __ cmovl(Assembler::less        , j, h);   // j = h if (key <  array[h].fast_match())
-      __ cmovl(Assembler::greaterEqual, i, h);   // i = h if (key >= array[h].fast_match())
-    } else {
-      Label set_i, end_of_if;
-      __ jccb(Assembler::greaterEqual, set_i);     // {
-      __ mov(j, h);                                //   j = h;
-      __ jmp(end_of_if);                           // }
-      __ bind(set_i);                              // else {
-      __ mov(i, h);                                //   i = h;
-      __ bind(end_of_if);                          // }
-    }
+    // j = h if (key <  array[h].fast_match())
+    __ cmov32(Assembler::less        , j, h);
+    // i = h if (key >= array[h].fast_match())
+    __ cmov32(Assembler::greaterEqual, i, h);
     // while (i+1 < j)
     __ bind(entry);
     __ leal(h, Address(i, 1));                   // i+1
@@ -3478,22 +3471,14 @@
 
   // find a free slot in the monitor block (result in rdx)
   { Label entry, loop, exit;
-    __ movptr(rcx, monitor_block_top);            // points to current entry, starting with top-most entry
-    __ lea(rbx, monitor_block_bot);               // points to word before bottom of monitor block
+    __ movptr(rcx, monitor_block_top);           // points to current entry, starting with top-most entry
+
+    __ lea(rbx, monitor_block_bot);              // points to word before bottom of monitor block
     __ jmpb(entry);
 
     __ bind(loop);
     __ cmpptr(Address(rcx, BasicObjectLock::obj_offset_in_bytes()), (int32_t)NULL_WORD);  // check if current entry is used
-
-// TODO - need new func here - kbt
-    if (VM_Version::supports_cmov()) {
-      __ cmov(Assembler::equal, rdx, rcx);       // if not used then remember entry in rdx
-    } else {
-      Label L;
-      __ jccb(Assembler::notEqual, L);
-      __ mov(rdx, rcx);                          // if not used then remember entry in rdx
-      __ bind(L);
-    }
+    __ cmovptr(Assembler::equal, rdx, rcx);      // if not used then remember entry in rdx
     __ cmpptr(rax, Address(rcx, BasicObjectLock::obj_offset_in_bytes()));   // check if current entry is for same object
     __ jccb(Assembler::equal, exit);             // if same object then stop searching
     __ addptr(rcx, entry_size);                  // otherwise advance to next entry
--- a/src/cpu/x86/vm/templateTable_x86_64.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/cpu/x86/vm/templateTable_x86_64.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -405,8 +405,8 @@
 void TemplateTable::fast_aldc(bool wide) {
   transition(vtos, atos);
 
-  if (!EnableMethodHandles) {
-    // We should not encounter this bytecode if !EnableMethodHandles.
+  if (!EnableInvokeDynamic) {
+    // We should not encounter this bytecode if !EnableInvokeDynamic.
     // The verifier will stop it.  However, if we get past the verifier,
     // this will stop the thread in a reasonable way, without crashing the JVM.
     __ call_VM(noreg, CAST_FROM_FN_PTR(address,
--- a/src/cpu/x86/vm/vm_version_x86.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/cpu/x86/vm/vm_version_x86.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
@@ -429,6 +429,11 @@
         UseXmmI2D = false;
       }
     }
+    if( FLAG_IS_DEFAULT(UseSSE42Intrinsics) ) {
+      if( supports_sse4_2() && UseSSE >= 4 ) {
+        UseSSE42Intrinsics = true;
+      }
+    }
 
     // Use count leading zeros count instruction if available.
     if (supports_lzcnt()) {
--- a/src/cpu/x86/vm/x86_32.ad	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/cpu/x86/vm/x86_32.ad	Thu Apr 14 11:02:05 2011 -0400
@@ -1393,6 +1393,10 @@
 // registers?  True for Intel but false for most RISCs
 const bool Matcher::clone_shift_expressions = true;
 
+// Do we need to mask the count passed to shift instructions or does
+// the cpu only look at the lower 5/6 bits anyway?
+const bool Matcher::need_masked_shift_count = false;
+
 bool Matcher::narrow_oop_use_complex_address() {
   ShouldNotCallThis();
   return true;
--- a/src/cpu/x86/vm/x86_64.ad	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/cpu/x86/vm/x86_64.ad	Thu Apr 14 11:02:05 2011 -0400
@@ -574,12 +574,11 @@
 // In os_cpu .ad file
 // int MachCallRuntimeNode::ret_addr_offset()
 
-// Indicate if the safepoint node needs the polling page as an input.
-// Since amd64 does not have absolute addressing but RIP-relative
-// addressing and the polling page is within 2G, it doesn't.
+// Indicate if the safepoint node needs the polling page as an input,
+// it does if the polling page is more than disp32 away.
 bool SafePointNode::needs_polling_address_input()
 {
-  return false;
+  return Assembler::is_polling_page_far();
 }
 
 //
@@ -992,15 +991,21 @@
   framesize -= 2*wordSize;
 
   if (framesize) {
-    st->print_cr("addq\trsp, %d\t# Destroy frame", framesize);
+    st->print_cr("addq    rsp, %d\t# Destroy frame", framesize);
     st->print("\t");
   }
 
-  st->print_cr("popq\trbp");
+  st->print_cr("popq   rbp");
   if (do_polling() && C->is_method_compilation()) {
-    st->print_cr("\ttestl\trax, [rip + #offset_to_poll_page]\t"
-                  "# Safepoint: poll for GC");
     st->print("\t");
+    if (Assembler::is_polling_page_far()) {
+      st->print_cr("movq   rscratch1, #polling_page_address\n\t"
+                   "testl  rax, [rscratch1]\t"
+                   "# Safepoint: poll for GC");
+    } else {
+      st->print_cr("testl  rax, [rip + #offset_to_poll_page]\t"
+                   "# Safepoint: poll for GC");
+    }
   }
 }
 #endif
@@ -1033,45 +1038,22 @@
   emit_opcode(cbuf, 0x58 | RBP_enc);
 
   if (do_polling() && C->is_method_compilation()) {
-    // testl %rax, off(%rip) // Opcode + ModRM + Disp32 == 6 bytes
-    // XXX reg_mem doesn't support RIP-relative addressing yet
-    cbuf.set_insts_mark();
-    cbuf.relocate(cbuf.insts_mark(), relocInfo::poll_return_type, 0); // XXX
-    emit_opcode(cbuf, 0x85); // testl
-    emit_rm(cbuf, 0x0, RAX_enc, 0x5); // 00 rax 101 == 0x5
-    // cbuf.insts_mark() is beginning of instruction
-    emit_d32_reloc(cbuf, os::get_polling_page());
-//                    relocInfo::poll_return_type,
+    MacroAssembler _masm(&cbuf);
+    AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_return_type);
+    if (Assembler::is_polling_page_far()) {
+      __ lea(rscratch1, polling_page);
+      __ relocate(relocInfo::poll_return_type);
+      __ testl(rax, Address(rscratch1, 0));
+    } else {
+      __ testl(rax, polling_page);
+    }
   }
 }
 
 uint MachEpilogNode::size(PhaseRegAlloc* ra_) const
 {
-  Compile* C = ra_->C;
-  int framesize = C->frame_slots() << LogBytesPerInt;
-  assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
-  // Remove word for return adr already pushed
-  // and RBP
-  framesize -= 2*wordSize;
-
-  uint size = 0;
-
-  if (do_polling() && C->is_method_compilation()) {
-    size += 6;
-  }
-
-  // count popq rbp
-  size++;
-
-  if (framesize) {
-    if (framesize < 0x80) {
-      size += 4;
-    } else if (framesize) {
-      size += 7;
-    }
-  }
-
-  return size;
+  return MachNode::size(ra_); // too many variables; just compute it
+                              // the hard way
 }
 
 int MachEpilogNode::reloc() const
@@ -2000,6 +1982,10 @@
 // into registers?  True for Intel but false for most RISCs
 const bool Matcher::clone_shift_expressions = true;
 
+// Do we need to mask the count passed to shift instructions or does
+// the cpu only look at the lower 5/6 bits anyway?
+const bool Matcher::need_masked_shift_count = false;
+
 bool Matcher::narrow_oop_use_complex_address() {
   assert(UseCompressedOops, "only for compressed oops code");
   return (LogMinObjAlignmentInBytes <= 3);
@@ -3406,8 +3392,8 @@
     }
     if (EmitSync & 1) {
         // Without cast to int32_t a movptr will destroy r10 which is typically obj
-        masm.movptr (Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())) ; 
-        masm.cmpptr(rsp, (int32_t)NULL_WORD) ; 
+        masm.movptr (Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())) ;
+        masm.cmpptr(rsp, (int32_t)NULL_WORD) ;
     } else
     if (EmitSync & 2) {
         Label DONE_LABEL;
@@ -3435,10 +3421,10 @@
     } else {
         Label DONE_LABEL, IsInflated, Egress;
 
-        masm.movptr(tmpReg, Address(objReg, 0)) ; 
+        masm.movptr(tmpReg, Address(objReg, 0)) ;
         masm.testl (tmpReg, 0x02) ;         // inflated vs stack-locked|neutral|biased
-        masm.jcc   (Assembler::notZero, IsInflated) ; 
-         
+        masm.jcc   (Assembler::notZero, IsInflated) ;
+
         // it's stack-locked, biased or neutral
         // TODO: optimize markword triage order to reduce the number of
         // conditional branches in the most common cases.
@@ -3452,9 +3438,9 @@
         }
 
         // was q will it destroy high?
-        masm.orl   (tmpReg, 1) ; 
-        masm.movptr(Address(boxReg, 0), tmpReg) ;  
-        if (os::is_MP()) { masm.lock(); } 
+        masm.orl   (tmpReg, 1) ;
+        masm.movptr(Address(boxReg, 0), tmpReg) ;
+        if (os::is_MP()) { masm.lock(); }
         masm.cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg
         if (_counters != NULL) {
            masm.cond_inc32(Assembler::equal,
@@ -3481,16 +3467,16 @@
         // fetched _owner.  If the CAS is successful we may
         // avoid an RTO->RTS upgrade on the $line.
         // Without cast to int32_t a movptr will destroy r10 which is typically obj
-        masm.movptr(Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())) ; 
-
-        masm.mov    (boxReg, tmpReg) ; 
-        masm.movptr (tmpReg, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; 
-        masm.testptr(tmpReg, tmpReg) ;   
-        masm.jcc    (Assembler::notZero, DONE_LABEL) ; 
+        masm.movptr(Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())) ;
+
+        masm.mov    (boxReg, tmpReg) ;
+        masm.movptr (tmpReg, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ;
+        masm.testptr(tmpReg, tmpReg) ;
+        masm.jcc    (Assembler::notZero, DONE_LABEL) ;
 
         // It's inflated and appears unlocked
-        if (os::is_MP()) { masm.lock(); } 
-        masm.cmpxchgptr(r15_thread, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; 
+        if (os::is_MP()) { masm.lock(); }
+        masm.cmpxchgptr(r15_thread, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)) ;
         // Intentional fall-through into DONE_LABEL ...
 
         masm.bind  (DONE_LABEL) ;
@@ -3509,8 +3495,8 @@
     Register tmpReg = as_Register($tmp$$reg);
     MacroAssembler masm(&cbuf);
 
-    if (EmitSync & 4) { 
-       masm.cmpptr(rsp, 0) ; 
+    if (EmitSync & 4) {
+       masm.cmpptr(rsp, 0) ;
     } else
     if (EmitSync & 8) {
        Label DONE_LABEL;
@@ -3537,25 +3523,25 @@
        if (UseBiasedLocking && !UseOptoBiasInlining) {
          masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL);
        }
-        
-       masm.movptr(tmpReg, Address(objReg, 0)) ; 
-       masm.cmpptr(Address(boxReg, 0), (int32_t)NULL_WORD) ; 
-       masm.jcc   (Assembler::zero, DONE_LABEL) ; 
-       masm.testl (tmpReg, 0x02) ; 
-       masm.jcc   (Assembler::zero, Stacked) ; 
-        
+
+       masm.movptr(tmpReg, Address(objReg, 0)) ;
+       masm.cmpptr(Address(boxReg, 0), (int32_t)NULL_WORD) ;
+       masm.jcc   (Assembler::zero, DONE_LABEL) ;
+       masm.testl (tmpReg, 0x02) ;
+       masm.jcc   (Assembler::zero, Stacked) ;
+
        // It's inflated
-       masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; 
-       masm.xorptr(boxReg, r15_thread) ; 
-       masm.orptr (boxReg, Address (tmpReg, ObjectMonitor::recursions_offset_in_bytes()-2)) ; 
-       masm.jcc   (Assembler::notZero, DONE_LABEL) ; 
-       masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::cxq_offset_in_bytes()-2)) ; 
-       masm.orptr (boxReg, Address (tmpReg, ObjectMonitor::EntryList_offset_in_bytes()-2)) ; 
-       masm.jcc   (Assembler::notZero, CheckSucc) ; 
-       masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), (int32_t)NULL_WORD) ; 
-       masm.jmp   (DONE_LABEL) ; 
-        
-       if ((EmitSync & 65536) == 0) { 
+       masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ;
+       masm.xorptr(boxReg, r15_thread) ;
+       masm.orptr (boxReg, Address (tmpReg, ObjectMonitor::recursions_offset_in_bytes()-2)) ;
+       masm.jcc   (Assembler::notZero, DONE_LABEL) ;
+       masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::cxq_offset_in_bytes()-2)) ;
+       masm.orptr (boxReg, Address (tmpReg, ObjectMonitor::EntryList_offset_in_bytes()-2)) ;
+       masm.jcc   (Assembler::notZero, CheckSucc) ;
+       masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), (int32_t)NULL_WORD) ;
+       masm.jmp   (DONE_LABEL) ;
+
+       if ((EmitSync & 65536) == 0) {
          Label LSuccess, LGoSlowPath ;
          masm.bind  (CheckSucc) ;
          masm.cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), (int32_t)NULL_WORD) ;
@@ -3587,9 +3573,9 @@
          masm.jmp   (DONE_LABEL) ;
        }
 
-       masm.bind  (Stacked) ; 
+       masm.bind  (Stacked) ;
        masm.movptr(tmpReg, Address (boxReg, 0)) ;      // re-fetch
-       if (os::is_MP()) { masm.lock(); } 
+       if (os::is_MP()) { masm.lock(); }
        masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses RAX which is box
 
        if (EmitSync & 65536) {
@@ -3910,22 +3896,6 @@
 
     // done:
   %}
-
-  // Safepoint Poll.  This polls the safepoint page, and causes an
-  // exception if it is not readable. Unfortunately, it kills
-  // RFLAGS in the process.
-  enc_class enc_safepoint_poll
-  %{
-    // testl %rax, off(%rip) // Opcode + ModRM + Disp32 == 6 bytes
-    // XXX reg_mem doesn't support RIP-relative addressing yet
-    cbuf.set_insts_mark();
-    cbuf.relocate(cbuf.insts_mark(), relocInfo::poll_type, 0); // XXX
-    emit_opcode(cbuf, 0x85); // testl
-    emit_rm(cbuf, 0x0, RAX_enc, 0x5); // 00 rax 101 == 0x5
-    // cbuf.insts_mark() is beginning of instruction
-    emit_d32_reloc(cbuf, os::get_polling_page());
-//                    relocInfo::poll_type,
-  %}
 %}
 
 
@@ -4229,6 +4199,15 @@
   interface(CONST_INTER);
 %}
 
+operand immP_poll() %{
+  predicate(n->get_ptr() != 0 && n->get_ptr() == (intptr_t)os::get_polling_page());
+  match(ConP);
+
+  // formats are generated automatically for constants and base registers
+  format %{ %}
+  interface(CONST_INTER);
+%}
+
 // Pointer Immediate
 operand immN() %{
   match(ConN);
@@ -4836,7 +4815,7 @@
 %}
 
 // Double register operands
-operand regD() 
+operand regD()
 %{
   constraint(ALLOC_IN_RC(double_reg));
   match(RegD);
@@ -6564,6 +6543,16 @@
   ins_pipe(ialu_reg);
 %}
 
+instruct loadConP_poll(rRegP dst, immP_poll src) %{
+  match(Set dst src);
+  format %{ "movq    $dst, $src\t!ptr" %}
+  ins_encode %{
+    AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_type);
+    __ lea($dst$$Register, polling_page);
+  %}
+  ins_pipe(ialu_reg_fat);
+%}
+
 instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr)
 %{
   match(Set dst src);
@@ -7237,11 +7226,11 @@
 instruct bytes_reverse_unsigned_short(rRegI dst) %{
   match(Set dst (ReverseBytesUS dst));
 
-  format %{ "bswapl  $dst\n\t" 
+  format %{ "bswapl  $dst\n\t"
             "shrl    $dst,16\n\t" %}
   ins_encode %{
     __ bswapl($dst$$Register);
-    __ shrl($dst$$Register, 16); 
+    __ shrl($dst$$Register, 16);
   %}
   ins_pipe( ialu_reg );
 %}
@@ -7249,11 +7238,11 @@
 instruct bytes_reverse_short(rRegI dst) %{
   match(Set dst (ReverseBytesS dst));
 
-  format %{ "bswapl  $dst\n\t" 
+  format %{ "bswapl  $dst\n\t"
             "sar     $dst,16\n\t" %}
   ins_encode %{
     __ bswapl($dst$$Register);
-    __ sarl($dst$$Register, 16); 
+    __ sarl($dst$$Register, 16);
   %}
   ins_pipe( ialu_reg );
 %}
@@ -7476,7 +7465,7 @@
   effect(KILL cr);
   ins_cost(400);
 
-  format %{ 
+  format %{
     $$template
     if (os::is_MP()) {
       $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile"
@@ -8287,7 +8276,7 @@
                            rFlagsReg cr)
 %{
   match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval)));
- 
+
   format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) "
             "If rax == $heap_top_ptr then store $newval into $heap_top_ptr" %}
   opcode(0x0F, 0xB1);
@@ -9850,9 +9839,9 @@
 
 // Xor Register with Immediate -1
 instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{
-  match(Set dst (XorI dst imm));  
-
-  format %{ "not    $dst" %}  
+  match(Set dst (XorI dst imm));
+
+  format %{ "not    $dst" %}
   ins_encode %{
      __ notl($dst$$Register);
   %}
@@ -10093,9 +10082,9 @@
 
 // Xor Register with Immediate -1
 instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{
-  match(Set dst (XorL dst imm));  
-
-  format %{ "notq   $dst" %}  
+  match(Set dst (XorL dst imm));
+
+  format %{ "notq   $dst" %}
   ins_encode %{
      __ notq($dst$$Register);
   %}
@@ -12469,14 +12458,33 @@
 // Safepoint Instructions
 instruct safePoint_poll(rFlagsReg cr)
 %{
+  predicate(!Assembler::is_polling_page_far());
   match(SafePoint);
   effect(KILL cr);
 
-  format %{ "testl   rax, [rip + #offset_to_poll_page]\t"
+  format %{ "testl  rax, [rip + #offset_to_poll_page]\t"
             "# Safepoint: poll for GC" %}
-  size(6); // Opcode + ModRM + Disp32 == 6 bytes
   ins_cost(125);
-  ins_encode(enc_safepoint_poll);
+  ins_encode %{
+    AddressLiteral addr(os::get_polling_page(), relocInfo::poll_type);
+    __ testl(rax, addr);
+  %}
+  ins_pipe(ialu_reg_mem);
+%}
+
+instruct safePoint_poll_far(rFlagsReg cr, rRegP poll)
+%{
+  predicate(Assembler::is_polling_page_far());
+  match(SafePoint poll);
+  effect(KILL cr, USE poll);
+
+  format %{ "testl  rax, [$poll]\t"
+            "# Safepoint: poll for GC" %}
+  ins_cost(125);
+  ins_encode %{
+    __ relocate(relocInfo::poll_type);
+    __ testl(rax, Address($poll$$Register, 0));
+  %}
   ins_pipe(ialu_reg_mem);
 %}
 
--- a/src/cpu/zero/vm/globals_zero.hpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/cpu/zero/vm/globals_zero.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2007, 2008, 2009, 2010 Red Hat, Inc.
+ * Copyright 2007, 2008, 2009, 2010, 2011 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -54,4 +54,6 @@
 
 define_pd_global(bool,  UseMembar,            false);
 
+// GC Ergo Flags
+define_pd_global(intx, CMSYoungGenPerWorker, 16*M);  // default max size of CMS young gen, per GC worker thread
 #endif // CPU_ZERO_VM_GLOBALS_ZERO_HPP
--- a/src/cpu/zero/vm/jni_zero.h	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/cpu/zero/vm/jni_zero.h	Thu Apr 14 11:02:05 2011 -0400
@@ -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.
  * Copyright 2009 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
--- a/src/cpu/zero/vm/relocInfo_zero.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/cpu/zero/vm/relocInfo_zero.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2007, 2009 Red Hat, Inc.
+ * Copyright 2007, 2009, 2010, 2011 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,7 +31,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) {
   ShouldNotCallThis();
 }
 
--- a/src/cpu/zero/vm/sharedRuntime_zero.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/cpu/zero/vm/sharedRuntime_zero.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2007, 2008, 2009, 2010 Red Hat, Inc.
+ * Copyright 2007, 2008, 2009, 2010, 2011 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -78,15 +78,17 @@
 
 nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm,
                                                 methodHandle method,
-                                                int total_in_args,
-                                                int comp_args_on_stack,
-                                                BasicType *in_sig_bt,
-                                                VMRegPair *in_regs,
+                                                int compile_id,
+                                                int total_args_passed,
+                                                int max_arg,
+                                                BasicType *sig_bt,
+                                                VMRegPair *regs,
                                                 BasicType ret_type) {
 #ifdef SHARK
   return SharkCompiler::compiler()->generate_native_wrapper(masm,
                                                             method,
-                                                            in_sig_bt,
+                                                            compile_id,
+                                                            sig_bt,
                                                             ret_type);
 #else
   ShouldNotCallThis();
--- a/src/os/linux/vm/jvm_linux.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/os/linux/vm/jvm_linux.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/os/linux/vm/osThread_linux.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/os/linux/vm/osThread_linux.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/os/linux/vm/os_linux.inline.hpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/os/linux/vm/os_linux.inline.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/os/linux/vm/thread_linux.inline.hpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/os/linux/vm/thread_linux.inline.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2010, 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
--- a/src/os/solaris/dtrace/generateJvmOffsets.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/os/solaris/dtrace/generateJvmOffsets.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/os/solaris/dtrace/jhelper.d	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/os/solaris/dtrace/jhelper.d	Thu Apr 14 11:02:05 2011 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2009, 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
--- a/src/os/solaris/dtrace/libjvm_db.c	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/os/solaris/dtrace/libjvm_db.c	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/os/solaris/vm/dtraceJSDT_solaris.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/os/solaris/vm/dtraceJSDT_solaris.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/os_cpu/linux_x86/vm/os_linux_x86.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/os_cpu/linux_x86/vm/os_linux_x86.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/os_cpu/linux_zero/vm/os_linux_zero.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/os_cpu/linux_zero/vm/os_linux_zero.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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.
  *
--- a/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/share/tools/hsdis/hsdis-demo.c	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/tools/hsdis/hsdis-demo.c	Thu Apr 14 11:02:05 2011 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 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
--- a/src/share/tools/hsdis/hsdis.c	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/tools/hsdis/hsdis.c	Thu Apr 14 11:02:05 2011 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 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
--- a/src/share/vm/adlc/main.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/adlc/main.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
@@ -240,6 +240,11 @@
   AD.addInclude(AD._CPP_file, "nativeInst_sparc.hpp");
   AD.addInclude(AD._CPP_file, "vmreg_sparc.inline.hpp");
 #endif
+#ifdef TARGET_ARCH_arm
+  AD.addInclude(AD._CPP_file, "assembler_arm.inline.hpp");
+  AD.addInclude(AD._CPP_file, "nativeInst_arm.hpp");
+  AD.addInclude(AD._CPP_file, "vmreg_arm.inline.hpp");
+#endif
   AD.addInclude(AD._HPP_file, "memory/allocation.hpp");
   AD.addInclude(AD._HPP_file, "opto/machnode.hpp");
   AD.addInclude(AD._HPP_file, "opto/node.hpp");
--- a/src/share/vm/adlc/output_c.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/adlc/output_c.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/share/vm/asm/assembler.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/asm/assembler.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/share/vm/asm/assembler.hpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/asm/assembler.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/share/vm/asm/codeBuffer.hpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/asm/codeBuffer.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/share/vm/c1/c1_Compilation.hpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/c1/c1_Compilation.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/share/vm/c1/c1_Defs.hpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/c1/c1_Defs.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/share/vm/c1/c1_FpuStackSim.hpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/c1/c1_FpuStackSim.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/share/vm/c1/c1_FrameMap.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/c1/c1_FrameMap.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/share/vm/c1/c1_FrameMap.hpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/c1/c1_FrameMap.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/share/vm/c1/c1_GraphBuilder.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/c1/c1_GraphBuilder.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -30,6 +30,7 @@
 #include "c1/c1_InstructionPrinter.hpp"
 #include "ci/ciField.hpp"
 #include "ci/ciKlass.hpp"
+#include "compiler/compileBroker.hpp"
 #include "interpreter/bytecode.hpp"
 #include "runtime/sharedRuntime.hpp"
 #include "utilities/bitMap.inline.hpp"
@@ -2823,7 +2824,7 @@
   int idx = 0;
   if (!method()->is_static()) {
     // we should always see the receiver
-    state->store_local(idx, new Local(objectType, idx));
+    state->store_local(idx, new Local(method()->holder(), objectType, idx));
     idx = 1;
   }
 
@@ -2835,7 +2836,7 @@
     // don't allow T_ARRAY to propagate into locals types
     if (basic_type == T_ARRAY) basic_type = T_OBJECT;
     ValueType* vt = as_ValueType(basic_type);
-    state->store_local(idx, new Local(vt, idx));
+    state->store_local(idx, new Local(type, vt, idx));
     idx += type->size();
   }
 
@@ -3775,24 +3776,7 @@
 
 #ifndef PRODUCT
 void GraphBuilder::print_inline_result(ciMethod* callee, bool res) {
-  const char sync_char      = callee->is_synchronized()        ? 's' : ' ';
-  const char exception_char = callee->has_exception_handlers() ? '!' : ' ';
-  const char monitors_char  = callee->has_monitor_bytecodes()  ? 'm' : ' ';
-  tty->print("     %c%c%c ", sync_char, exception_char, monitors_char);
-  for (int i = 0; i < scope()->level(); i++) tty->print("  ");
-  if (res) {
-    tty->print("  ");
-  } else {
-    tty->print("- ");
-  }
-  tty->print("@ %d  ", bci());
-  callee->print_short_name();
-  tty->print(" (%d bytes)", callee->code_size());
-  if (_inline_bailout_msg) {
-    tty->print("  %s", _inline_bailout_msg);
-  }
-  tty->cr();
-
+  CompileTask::print_inlining(callee, scope()->level(), bci(), _inline_bailout_msg);
   if (res && CIPrintMethodCodes) {
     callee->print_codes();
   }
--- a/src/share/vm/c1/c1_Instruction.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/c1/c1_Instruction.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -135,6 +135,33 @@
 }
 
 
+ciType* Local::exact_type() const {
+  ciType* type = declared_type();
+
+  // for primitive arrays, the declared type is the exact type
+  if (type->is_type_array_klass()) {
+    return type;
+  } else if (type->is_instance_klass()) {
+    ciInstanceKlass* ik = (ciInstanceKlass*)type;
+    if (ik->is_loaded() && ik->is_final() && !ik->is_interface()) {
+      return type;
+    }
+  } else if (type->is_obj_array_klass()) {
+    ciObjArrayKlass* oak = (ciObjArrayKlass*)type;
+    ciType* base = oak->base_element_type();
+    if (base->is_instance_klass()) {
+      ciInstanceKlass* ik = base->as_instance_klass();
+      if (ik->is_loaded() && ik->is_final()) {
+        return type;
+      }
+    } else if (base->is_primitive_type()) {
+      return type;
+    }
+  }
+  return NULL;
+}
+
+
 ciType* LoadIndexed::exact_type() const {
   ciType* array_type = array()->exact_type();
   if (array_type == NULL) {
@@ -189,16 +216,21 @@
   return ciTypeArrayKlass::make(elt_type());
 }
 
-
 ciType* NewObjectArray::exact_type() const {
   return ciObjArrayKlass::make(klass());
 }
 
+ciType* NewArray::declared_type() const {
+  return exact_type();
+}
 
 ciType* NewInstance::exact_type() const {
   return klass();
 }
 
+ciType* NewInstance::declared_type() const {
+  return exact_type();
+}
 
 ciType* CheckCast::declared_type() const {
   return klass();
@@ -349,6 +381,11 @@
   if (state()        != NULL) state()->values_do(f);
 }
 
+ciType* Invoke::declared_type() const {
+  ciType *t = _target->signature()->return_type();
+  assert(t->basic_type() != T_VOID, "need return value of void method?");
+  return t;
+}
 
 // Implementation of Contant
 intx Constant::hash() const {
--- a/src/share/vm/c1/c1_Instruction.hpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/c1/c1_Instruction.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -621,16 +621,21 @@
 LEAF(Local, Instruction)
  private:
   int      _java_index;                          // the local index within the method to which the local belongs
+  ciType*  _declared_type;
  public:
   // creation
-  Local(ValueType* type, int index)
+  Local(ciType* declared, ValueType* type, int index)
     : Instruction(type)
     , _java_index(index)
+    , _declared_type(declared)
   {}
 
   // accessors
   int java_index() const                         { return _java_index; }
 
+  ciType* declared_type() const                  { return _declared_type; }
+  ciType* exact_type() const;
+
   // generic
   virtual void input_values_do(ValueVisitor* f)   { /* no values */ }
 };
@@ -1146,6 +1151,8 @@
   BasicTypeList* signature() const               { return _signature; }
   ciMethod* target() const                       { return _target; }
 
+  ciType* declared_type() const;
+
   // Returns false if target is not loaded
   bool target_is_final() const                   { return check_flag(TargetIsFinalFlag); }
   bool target_is_loaded() const                  { return check_flag(TargetIsLoadedFlag); }
@@ -1187,6 +1194,7 @@
   // generic
   virtual bool can_trap() const                  { return true; }
   ciType* exact_type() const;
+  ciType* declared_type() const;
 };
 
 
@@ -1208,6 +1216,8 @@
 
   virtual bool needs_exception_state() const     { return false; }
 
+  ciType* declared_type() const;
+
   // generic
   virtual bool can_trap() const                  { return true; }
   virtual void input_values_do(ValueVisitor* f)   { StateSplit::input_values_do(f); f->visit(&_length); }
@@ -1397,6 +1407,7 @@
   vmIntrinsics::ID _id;
   Values*          _args;
   Value            _recv;
+  int              _nonnull_state; // mask identifying which args are nonnull
 
  public:
   // preserves_state can be set to true for Intrinsics
@@ -1417,6 +1428,7 @@
   , _id(id)
   , _args(args)
   , _recv(NULL)
+  , _nonnull_state(AllBits)
   {
     assert(args != NULL, "args must exist");
     ASSERT_VALUES
@@ -1442,6 +1454,23 @@
   Value receiver() const                         { assert(has_receiver(), "must have receiver"); return _recv; }
   bool preserves_state() const                   { return check_flag(PreservesStateFlag); }
 
+  bool arg_needs_null_check(int i) {
+    if (i >= 0 && i < (int)sizeof(_nonnull_state) * BitsPerByte) {
+      return is_set_nth_bit(_nonnull_state, i);
+    }
+    return true;
+  }
+
+  void set_arg_needs_null_check(int i, bool check) {
+    if (i >= 0 && i < (int)sizeof(_nonnull_state) * BitsPerByte) {
+      if (check) {
+        _nonnull_state |= nth_bit(i);
+      } else {
+        _nonnull_state &= ~(nth_bit(i));
+      }
+    }
+  }
+
   // generic
   virtual bool can_trap() const                  { return check_flag(CanTrapFlag); }
   virtual void input_values_do(ValueVisitor* f) {
--- a/src/share/vm/c1/c1_LIR.hpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/c1/c1_LIR.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -1215,7 +1215,11 @@
     src_range_check        = 1 << 5,
     dst_range_check        = 1 << 6,
     type_check             = 1 << 7,
-    all_flags              = (1 << 8) - 1
+    overlapping            = 1 << 8,
+    unaligned              = 1 << 9,
+    src_objarray           = 1 << 10,
+    dst_objarray           = 1 << 11,
+    all_flags              = (1 << 12) - 1
   };
 
   LIR_OpArrayCopy(LIR_Opr src, LIR_Opr src_pos, LIR_Opr dst, LIR_Opr dst_pos, LIR_Opr length, LIR_Opr tmp,
--- a/src/share/vm/c1/c1_LIRAssembler.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/c1/c1_LIRAssembler.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
@@ -836,6 +836,9 @@
           _masm->verify_stack_oop(r->reg2stack() * VMRegImpl::stack_slot_size);
         }
       }
+      check_codespace();
+      CHECK_BAILOUT();
+
       s.next();
     }
     VerifyOops = v;
--- a/src/share/vm/c1/c1_LIRAssembler.hpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/c1/c1_LIRAssembler.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/share/vm/c1/c1_LIRGenerator.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/c1/c1_LIRGenerator.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -706,6 +706,38 @@
   }
 }
 
+static Value maxvalue(IfOp* ifop) {
+  switch (ifop->cond()) {
+    case If::eql: return NULL;
+    case If::neq: return NULL;
+    case If::lss: // x <  y ? x : y
+    case If::leq: // x <= y ? x : y
+      if (ifop->x() == ifop->tval() &&
+          ifop->y() == ifop->fval()) return ifop->y();
+      return NULL;
+
+    case If::gtr: // x >  y ? y : x
+    case If::geq: // x >= y ? y : x
+      if (ifop->x() == ifop->tval() &&
+          ifop->y() == ifop->fval()) return ifop->y();
+      return NULL;
+
+  }
+}
+
+static ciType* phi_declared_type(Phi* phi) {
+  ciType* t = phi->operand_at(0)->declared_type();
+  if (t == NULL) {
+    return NULL;
+  }
+  for(int i = 1; i < phi->operand_count(); i++) {
+    if (t != phi->operand_at(i)->declared_type()) {
+      return NULL;
+    }
+  }
+  return t;
+}
+
 void LIRGenerator::arraycopy_helper(Intrinsic* x, int* flagsp, ciArrayKlass** expected_typep) {
   Instruction* src     = x->argument_at(0);
   Instruction* src_pos = x->argument_at(1);
@@ -715,12 +747,20 @@
 
   // first try to identify the likely type of the arrays involved
   ciArrayKlass* expected_type = NULL;
-  bool is_exact = false;
+  bool is_exact = false, src_objarray = false, dst_objarray = false;
   {
     ciArrayKlass* src_exact_type    = as_array_klass(src->exact_type());
     ciArrayKlass* src_declared_type = as_array_klass(src->declared_type());
+    Phi* phi;
+    if (src_declared_type == NULL && (phi = src->as_Phi()) != NULL) {
+      src_declared_type = as_array_klass(phi_declared_type(phi));
+    }
     ciArrayKlass* dst_exact_type    = as_array_klass(dst->exact_type());
     ciArrayKlass* dst_declared_type = as_array_klass(dst->declared_type());
+    if (dst_declared_type == NULL && (phi = dst->as_Phi()) != NULL) {
+      dst_declared_type = as_array_klass(phi_declared_type(phi));
+    }
+
     if (src_exact_type != NULL && src_exact_type == dst_exact_type) {
       // the types exactly match so the type is fully known
       is_exact = true;
@@ -744,17 +784,60 @@
     if (expected_type == NULL) expected_type = dst_exact_type;
     if (expected_type == NULL) expected_type = src_declared_type;
     if (expected_type == NULL) expected_type = dst_declared_type;
+
+    src_objarray = (src_exact_type && src_exact_type->is_obj_array_klass()) || (src_declared_type && src_declared_type->is_obj_array_klass());
+    dst_objarray = (dst_exact_type && dst_exact_type->is_obj_array_klass()) || (dst_declared_type && dst_declared_type->is_obj_array_klass());
   }
 
   // if a probable array type has been identified, figure out if any
   // of the required checks for a fast case can be elided.
   int flags = LIR_OpArrayCopy::all_flags;
+
+  if (!src_objarray)
+    flags &= ~LIR_OpArrayCopy::src_objarray;
+  if (!dst_objarray)
+    flags &= ~LIR_OpArrayCopy::dst_objarray;
+
+  if (!x->arg_needs_null_check(0))
+    flags &= ~LIR_OpArrayCopy::src_null_check;
+  if (!x->arg_needs_null_check(2))
+    flags &= ~LIR_OpArrayCopy::dst_null_check;
+
+
   if (expected_type != NULL) {
-    // try to skip null checks
-    if (src->as_NewArray() != NULL)
+    Value length_limit = NULL;
+
+    IfOp* ifop = length->as_IfOp();
+    if (ifop != NULL) {
+      // look for expressions like min(v, a.length) which ends up as
+      //   x > y ? y : x  or  x >= y ? y : x
+      if ((ifop->cond() == If::gtr || ifop->cond() == If::geq) &&
+          ifop->x() == ifop->fval() &&
+          ifop->y() == ifop->tval()) {
+        length_limit = ifop->y();
+      }
+    }
+
+    // try to skip null checks and range checks
+    NewArray* src_array = src->as_NewArray();
+    if (src_array != NULL) {
       flags &= ~LIR_OpArrayCopy::src_null_check;
-    if (dst->as_NewArray() != NULL)
+      if (length_limit != NULL &&
+          src_array->length() == length_limit &&
+          is_constant_zero(src_pos)) {
+        flags &= ~LIR_OpArrayCopy::src_range_check;
+      }
+    }
+
+    NewArray* dst_array = dst->as_NewArray();
+    if (dst_array != NULL) {
       flags &= ~LIR_OpArrayCopy::dst_null_check;
+      if (length_limit != NULL &&
+          dst_array->length() == length_limit &&
+          is_constant_zero(dst_pos)) {
+        flags &= ~LIR_OpArrayCopy::dst_range_check;
+      }
+    }
 
     // check from incoming constant values
     if (positive_constant(src_pos))
@@ -788,6 +871,28 @@
     }
   }
 
+  IntConstant* src_int = src_pos->type()->as_IntConstant();
+  IntConstant* dst_int = dst_pos->type()->as_IntConstant();
+  if (src_int && dst_int) {
+    int s_offs = src_int->value();
+    int d_offs = dst_int->value();
+    if (src_int->value() >= dst_int->value()) {
+      flags &= ~LIR_OpArrayCopy::overlapping;
+    }
+    if (expected_type != NULL) {
+      BasicType t = expected_type->element_type()->basic_type();
+      int element_size = type2aelembytes(t);
+      if (((arrayOopDesc::base_offset_in_bytes(t) + s_offs * element_size) % HeapWordSize == 0) &&
+          ((arrayOopDesc::base_offset_in_bytes(t) + d_offs * element_size) % HeapWordSize == 0)) {
+        flags &= ~LIR_OpArrayCopy::unaligned;
+      }
+    }
+  } else if (src_pos == dst_pos || is_constant_zero(dst_pos)) {
+    // src and dest positions are the same, or dst is zero so assume
+    // nonoverlapping copy.
+    flags &= ~LIR_OpArrayCopy::overlapping;
+  }
+
   if (src == dst) {
     // moving within a single array so no type checks are needed
     if (flags & LIR_OpArrayCopy::type_check) {
@@ -1351,7 +1456,7 @@
 
   if (addr->is_address()) {
     LIR_Address* address = addr->as_address_ptr();
-    LIR_Opr ptr = new_register(T_OBJECT);
+    LIR_Opr ptr = new_pointer_register();
     if (!address->index()->is_valid() && address->disp() == 0) {
       __ move(address->base(), ptr);
     } else {
@@ -1403,7 +1508,9 @@
   LIR_Const* card_table_base = new LIR_Const(((CardTableModRefBS*)_bs)->byte_map_base);
   if (addr->is_address()) {
     LIR_Address* address = addr->as_address_ptr();
-    LIR_Opr ptr = new_register(T_OBJECT);
+    // ptr cannot be an object because we use this barrier for array card marks
+    // and addr can point in the middle of an array.
+    LIR_Opr ptr = new_pointer_register();
     if (!address->index()->is_valid() && address->disp() == 0) {
       __ move(address->base(), ptr);
     } else {
--- a/src/share/vm/c1/c1_LinearScan.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/c1/c1_LinearScan.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/share/vm/c1/c1_LinearScan.hpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/c1/c1_LinearScan.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/share/vm/c1/c1_MacroAssembler.hpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/c1/c1_MacroAssembler.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/share/vm/c1/c1_Optimizer.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/c1/c1_Optimizer.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -644,7 +644,7 @@
 void NullCheckVisitor::do_InstanceOf     (InstanceOf*      x) {}
 void NullCheckVisitor::do_MonitorEnter   (MonitorEnter*    x) { nce()->handle_AccessMonitor(x); }
 void NullCheckVisitor::do_MonitorExit    (MonitorExit*     x) { nce()->handle_AccessMonitor(x); }
-void NullCheckVisitor::do_Intrinsic      (Intrinsic*       x) { nce()->clear_last_explicit_null_check(); }
+void NullCheckVisitor::do_Intrinsic      (Intrinsic*       x) { nce()->handle_Intrinsic(x);     }
 void NullCheckVisitor::do_BlockBegin     (BlockBegin*      x) {}
 void NullCheckVisitor::do_Goto           (Goto*            x) {}
 void NullCheckVisitor::do_If             (If*              x) {}
@@ -1023,6 +1023,12 @@
 
 void NullCheckEliminator::handle_Intrinsic(Intrinsic* x) {
   if (!x->has_receiver()) {
+    if (x->id() == vmIntrinsics::_arraycopy) {
+      for (int i = 0; i < x->number_of_arguments(); i++) {
+        x->set_arg_needs_null_check(i, !set_contains(x->argument_at(i)));
+      }
+    }
+
     // Be conservative
     clear_last_explicit_null_check();
     return;
--- a/src/share/vm/c1/c1_Runtime1.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/c1/c1_Runtime1.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -103,7 +103,10 @@
 int Runtime1::_generic_arraycopy_cnt = 0;
 int Runtime1::_primitive_arraycopy_cnt = 0;
 int Runtime1::_oop_arraycopy_cnt = 0;
+int Runtime1::_generic_arraycopystub_cnt = 0;
 int Runtime1::_arraycopy_slowcase_cnt = 0;
+int Runtime1::_arraycopy_checkcast_cnt = 0;
+int Runtime1::_arraycopy_checkcast_attempt_cnt = 0;
 int Runtime1::_new_type_array_slowcase_cnt = 0;
 int Runtime1::_new_object_array_slowcase_cnt = 0;
 int Runtime1::_new_instance_slowcase_cnt = 0;
@@ -119,6 +122,32 @@
 int Runtime1::_throw_incompatible_class_change_error_count = 0;
 int Runtime1::_throw_array_store_exception_count = 0;
 int Runtime1::_throw_count = 0;
+
+static int _byte_arraycopy_cnt = 0;
+static int _short_arraycopy_cnt = 0;
+static int _int_arraycopy_cnt = 0;
+static int _long_arraycopy_cnt = 0;
+static int _oop_arraycopy_cnt = 0;
+
+address Runtime1::arraycopy_count_address(BasicType type) {
+  switch (type) {
+  case T_BOOLEAN:
+  case T_BYTE:   return (address)&_byte_arraycopy_cnt;
+  case T_CHAR:
+  case T_SHORT:  return (address)&_short_arraycopy_cnt;
+  case T_FLOAT:
+  case T_INT:    return (address)&_int_arraycopy_cnt;
+  case T_DOUBLE:
+  case T_LONG:   return (address)&_long_arraycopy_cnt;
+  case T_ARRAY:
+  case T_OBJECT: return (address)&_oop_arraycopy_cnt;
+  default:
+    ShouldNotReachHere();
+    return NULL;
+  }
+}
+
+
 #endif
 
 // Simple helper to see if the caller of a runtime stub which
@@ -1229,9 +1258,17 @@
   tty->print_cr(" _handle_wrong_method_cnt:        %d", SharedRuntime::_wrong_method_ctr);
   tty->print_cr(" _ic_miss_cnt:                    %d", SharedRuntime::_ic_miss_ctr);
   tty->print_cr(" _generic_arraycopy_cnt:          %d", _generic_arraycopy_cnt);
+  tty->print_cr(" _generic_arraycopystub_cnt:      %d", _generic_arraycopystub_cnt);
+  tty->print_cr(" _byte_arraycopy_cnt:             %d", _byte_arraycopy_cnt);
+  tty->print_cr(" _short_arraycopy_cnt:            %d", _short_arraycopy_cnt);
+  tty->print_cr(" _int_arraycopy_cnt:              %d", _int_arraycopy_cnt);
+  tty->print_cr(" _long_arraycopy_cnt:             %d", _long_arraycopy_cnt);
   tty->print_cr(" _primitive_arraycopy_cnt:        %d", _primitive_arraycopy_cnt);
-  tty->print_cr(" _oop_arraycopy_cnt:              %d", _oop_arraycopy_cnt);
+  tty->print_cr(" _oop_arraycopy_cnt (C):          %d", Runtime1::_oop_arraycopy_cnt);
+  tty->print_cr(" _oop_arraycopy_cnt (stub):       %d", _oop_arraycopy_cnt);
   tty->print_cr(" _arraycopy_slowcase_cnt:         %d", _arraycopy_slowcase_cnt);
+  tty->print_cr(" _arraycopy_checkcast_cnt:        %d", _arraycopy_checkcast_cnt);
+  tty->print_cr(" _arraycopy_checkcast_attempt_cnt:%d", _arraycopy_checkcast_attempt_cnt);
 
   tty->print_cr(" _new_type_array_slowcase_cnt:    %d", _new_type_array_slowcase_cnt);
   tty->print_cr(" _new_object_array_slowcase_cnt:  %d", _new_object_array_slowcase_cnt);
--- a/src/share/vm/c1/c1_Runtime1.hpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/c1/c1_Runtime1.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -94,7 +94,10 @@
   static int _generic_arraycopy_cnt;
   static int _primitive_arraycopy_cnt;
   static int _oop_arraycopy_cnt;
+  static int _generic_arraycopystub_cnt;
   static int _arraycopy_slowcase_cnt;
+  static int _arraycopy_checkcast_cnt;
+  static int _arraycopy_checkcast_attempt_cnt;
   static int _new_type_array_slowcase_cnt;
   static int _new_object_array_slowcase_cnt;
   static int _new_instance_slowcase_cnt;
@@ -174,7 +177,8 @@
   static void trace_block_entry(jint block_id);
 
 #ifndef PRODUCT
-  static address throw_count_address()       { return (address)&_throw_count;       }
+  static address throw_count_address()               { return (address)&_throw_count;             }
+  static address arraycopy_count_address(BasicType type);
 #endif
 
   // directly accessible leaf routine
--- a/src/share/vm/c1/c1_globals.hpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/c1/c1_globals.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/share/vm/ci/ciClassList.hpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/ci/ciClassList.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/share/vm/ci/ciEnv.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/ci/ciEnv.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/share/vm/ci/ciEnv.hpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/ci/ciEnv.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/share/vm/ci/ciInstance.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/ci/ciInstance.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -66,8 +66,8 @@
          "invalid access");
   VM_ENTRY_MARK;
   ciConstant result;
-  oop obj = get_oop();
-  assert(obj != NULL, "bad oop");
+  Handle obj = get_oop();
+  assert(!obj.is_null(), "bad oop");
   BasicType field_btype = field->type()->basic_type();
   int offset = field->offset();
 
--- a/src/share/vm/ci/ciKlass.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/ci/ciKlass.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/share/vm/ci/ciMethodHandle.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/ci/ciMethodHandle.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -42,9 +42,20 @@
   methodHandle callee(_callee->get_methodOop());
   // We catch all exceptions here that could happen in the method
   // handle compiler and stop the VM.
-  MethodHandleCompiler mhc(h, callee, is_invokedynamic, CATCH);
-  methodHandle m = mhc.compile(CATCH);
-  return CURRENT_ENV->get_object(m())->as_method();
+  MethodHandleCompiler mhc(h, callee, is_invokedynamic, THREAD);
+  if (!HAS_PENDING_EXCEPTION) {
+    methodHandle m = mhc.compile(THREAD);
+    if (!HAS_PENDING_EXCEPTION) {
+      return CURRENT_ENV->get_object(m())->as_method();
+    }
+  }
+  if (PrintMiscellaneous && (Verbose || WizardMode)) {
+    tty->print("*** ciMethodHandle::get_adapter => ");
+    PENDING_EXCEPTION->print();
+    tty->print("*** get_adapter (%s): ", is_invokedynamic ? "indy" : "mh"); ((ciObject*)this)->print(); //@@
+  }
+  CLEAR_PENDING_EXCEPTION;
+  return NULL;
 }
 
 
--- a/src/share/vm/ci/ciObjArrayKlass.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/ci/ciObjArrayKlass.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/share/vm/ci/ciObject.hpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/ci/ciObject.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/share/vm/ci/ciObjectFactory.hpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/ci/ciObjectFactory.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/share/vm/ci/ciSignature.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/ci/ciSignature.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/share/vm/ci/ciSignature.hpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/ci/ciSignature.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/share/vm/ci/ciSymbol.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/ci/ciSymbol.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/share/vm/ci/ciSymbol.hpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/ci/ciSymbol.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/share/vm/ci/ciTypeFlow.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/ci/ciTypeFlow.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -1871,7 +1871,8 @@
 // ------------------------------------------------------------------
 // ciTypeFlow::Block::print_on
 void ciTypeFlow::Block::print_on(outputStream* st) const {
-  if ((Verbose || WizardMode)) {
+  if ((Verbose || WizardMode) && (limit() >= 0)) {
+    // Don't print 'dummy' blocks (i.e. blocks with limit() '-1')
     outer()->method()->print_codes_on(start(), limit(), st);
   }
   st->print_cr("  ====================================================  ");
--- a/src/share/vm/ci/ciTypeFlow.hpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/ci/ciTypeFlow.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -34,6 +34,7 @@
 #include "ci/ciEnv.hpp"
 #include "ci/ciKlass.hpp"
 #include "ci/ciMethodBlocks.hpp"
+#include "shark/shark_globals.hpp"
 #endif
 
 
--- a/src/share/vm/ci/compilerInterface.hpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/ci/compilerInterface.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/share/vm/classfile/classFileError.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/classfile/classFileError.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/share/vm/classfile/classFileParser.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/classfile/classFileParser.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -152,7 +152,7 @@
             "Class file version does not support constant tag %u in class file %s",
             tag, CHECK);
         }
-        if (!EnableMethodHandles) {
+        if (!EnableInvokeDynamic) {
           classfile_parse_error(
             "This JVM does not support constant tag %u in class file %s",
             tag, CHECK);
@@ -170,7 +170,6 @@
           ShouldNotReachHere();
         }
         break;
-      case JVM_CONSTANT_InvokeDynamicTrans :  // this tag appears only in old classfiles
       case JVM_CONSTANT_InvokeDynamic :
         {
           if (_major_version < Verifier::INVOKEDYNAMIC_MAJOR_VERSION) {
@@ -186,14 +185,6 @@
           cfs->guarantee_more(5, CHECK);  // bsm_index, nt, tag/access_flags
           u2 bootstrap_specifier_index = cfs->get_u2_fast();
           u2 name_and_type_index = cfs->get_u2_fast();
-          if (tag == JVM_CONSTANT_InvokeDynamicTrans) {
-            if (!AllowTransitionalJSR292)
-              classfile_parse_error(
-                "This JVM does not support transitional InvokeDynamic tag %u in class file %s",
-                tag, CHECK);
-            cp->invoke_dynamic_trans_at_put(index, bootstrap_specifier_index, name_and_type_index);
-            break;
-          }
           if (_max_bootstrap_specifier_index < (int) bootstrap_specifier_index)
             _max_bootstrap_specifier_index = (int) bootstrap_specifier_index;  // collect for later
           cp->invoke_dynamic_at_put(index, bootstrap_specifier_index, name_and_type_index);
@@ -260,7 +251,7 @@
             verify_legal_utf8((unsigned char*)utf8_buffer, utf8_length, CHECK);
           }
 
-          if (AnonymousClasses && has_cp_patch_at(index)) {
+          if (EnableInvokeDynamic && has_cp_patch_at(index)) {
             Handle patch = clear_cp_patch_at(index);
             guarantee_property(java_lang_String::is_instance(patch()),
                                "Illegal utf8 patch at %d in class file %s",
@@ -443,7 +434,7 @@
           int ref_index = cp->method_handle_index_at(index);
           check_property(
             valid_cp_range(ref_index, length) &&
-                EnableMethodHandles,
+                EnableInvokeDynamic,
               "Invalid constant pool index %u in class file %s",
               ref_index, CHECK_(nullHandle));
           constantTag tag = cp->tag_at(ref_index);
@@ -487,12 +478,11 @@
           check_property(
             valid_cp_range(ref_index, length) &&
                 cp->tag_at(ref_index).is_utf8() &&
-                EnableMethodHandles,
+                EnableInvokeDynamic,
               "Invalid constant pool index %u in class file %s",
               ref_index, CHECK_(nullHandle));
         }
         break;
-      case JVM_CONSTANT_InvokeDynamicTrans :
       case JVM_CONSTANT_InvokeDynamic :
         {
           int name_and_type_ref_index = cp->invoke_dynamic_name_and_type_ref_index_at(index);
@@ -501,14 +491,6 @@
                          "Invalid constant pool index %u in class file %s",
                          name_and_type_ref_index,
                          CHECK_(nullHandle));
-          if (tag == JVM_CONSTANT_InvokeDynamicTrans) {
-            int bootstrap_method_ref_index = cp->invoke_dynamic_bootstrap_method_ref_index_at(index);
-            check_property(valid_cp_range(bootstrap_method_ref_index, length) &&
-                           cp->tag_at(bootstrap_method_ref_index).is_method_handle(),
-                           "Invalid constant pool index %u in class file %s",
-                           bootstrap_method_ref_index,
-                           CHECK_(nullHandle));
-          }
           // bootstrap specifier index must be checked later, when BootstrapMethods attr is available
           break;
         }
@@ -522,7 +504,7 @@
 
   if (_cp_patches != NULL) {
     // need to treat this_class specially...
-    assert(AnonymousClasses, "");
+    assert(EnableInvokeDynamic, "");
     int this_class_index;
     {
       cfs->guarantee_more(8, CHECK_(nullHandle));  // flags, this_class, super_class, infs_len
@@ -578,6 +560,7 @@
         }
         break;
       }
+      case JVM_CONSTANT_InvokeDynamic:
       case JVM_CONSTANT_Fieldref:
       case JVM_CONSTANT_Methodref:
       case JVM_CONSTANT_InterfaceMethodref: {
@@ -677,7 +660,7 @@
 
 
 void ClassFileParser::patch_constant_pool(constantPoolHandle cp, int index, Handle patch, TRAPS) {
-  assert(AnonymousClasses, "");
+  assert(EnableInvokeDynamic, "");
   BasicType patch_type = T_VOID;
   switch (cp->tag_at(index).value()) {
 
@@ -2103,7 +2086,7 @@
     _has_vanilla_constructor = true;
   }
 
-  if (EnableMethodHandles && (m->is_method_handle_invoke() ||
+  if (EnableInvokeDynamic && (m->is_method_handle_invoke() ||
                               m->is_method_handle_adapter())) {
     THROW_MSG_(vmSymbols::java_lang_VirtualMachineError(),
                "Method handle invokers must be defined internally to the VM", nullHandle);
@@ -2771,7 +2754,7 @@
   // 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.
 
-  if (!EnableMethodHandles)  return;
+  if (!EnableInvokeDynamic)  return;
 
   int word_sig_index = 0;
   const int cp_size = cp->length();
@@ -2783,7 +2766,6 @@
     }
   }
 
-  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.lang.invoke.MethodHandle");
@@ -2823,7 +2805,6 @@
     }
   }
 
-  if (AllowTransitionalJSR292 && !found_vmentry)  return;
   if (!found_vmentry)
     THROW_MSG(vmSymbols::java_lang_VirtualMachineError(),
               "missing vmentry byte field in java.lang.invoke.MethodHandle");
@@ -3191,16 +3172,7 @@
     next_nonstatic_field_offset = first_nonstatic_field_offset;
 
     // 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));
-    }
-    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
+    if (EnableInvokeDynamic && class_name == vmSymbols::java_lang_invoke_MethodHandle() && class_loader.is_null()) {
       java_lang_invoke_MethodHandle_fix_pre(cp, fields, &fac, CHECK_(nullHandle));
     }
 
--- a/src/share/vm/classfile/classFileParser.hpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/classfile/classFileParser.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -231,11 +231,11 @@
   char* skip_over_field_signature(char* signature, bool void_ok, unsigned int length, TRAPS);
 
   bool is_anonymous() {
-    assert(AnonymousClasses || _host_klass.is_null(), "");
+    assert(EnableInvokeDynamic || _host_klass.is_null(), "");
     return _host_klass.not_null();
   }
   bool has_cp_patch_at(int index) {
-    assert(AnonymousClasses, "");
+    assert(EnableInvokeDynamic, "");
     assert(index >= 0, "oob");
     return (_cp_patches != NULL
             && index < _cp_patches->length()
@@ -258,7 +258,7 @@
   // constant pool construction, but in later versions they can.
   // %%% Let's phase out the old is_klass_reference.
   bool is_klass_reference(constantPoolHandle cp, int index) {
-    return ((LinkWellKnownClasses || AnonymousClasses)
+    return ((LinkWellKnownClasses || EnableInvokeDynamic)
             ? cp->tag_at(index).is_klass_or_reference()
             : cp->tag_at(index).is_klass_reference());
   }
--- a/src/share/vm/classfile/classFileStream.hpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/classfile/classFileStream.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/share/vm/classfile/classLoader.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/classfile/classLoader.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/share/vm/classfile/classLoader.hpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/classfile/classLoader.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/share/vm/classfile/dictionary.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/classfile/dictionary.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/share/vm/classfile/dictionary.hpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/classfile/dictionary.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/share/vm/classfile/javaAssertions.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/classfile/javaAssertions.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/share/vm/classfile/javaClasses.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/classfile/javaClasses.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -67,28 +67,6 @@
     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,
@@ -301,6 +279,15 @@
   return result;
 }
 
+unsigned int java_lang_String::hash_string(oop java_string) {
+  typeArrayOop value  = java_lang_String::value(java_string);
+  int          offset = java_lang_String::offset(java_string);
+  int          length = java_lang_String::length(java_string);
+
+  if (length == 0) return 0;
+  return hash_string(value->char_at_addr(offset), length);
+}
+
 Symbol* java_lang_String::as_symbol(Handle java_string, TRAPS) {
   oop          obj    = java_string();
   typeArrayOop value  = java_lang_String::value(obj);
@@ -2331,9 +2318,8 @@
 
 void java_lang_invoke_MethodHandle::compute_offsets() {
   klassOop k = SystemDictionary::MethodHandle_klass();
-  if (k != NULL && EnableMethodHandles) {
+  if (k != NULL && EnableInvokeDynamic) {
     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);
@@ -2346,7 +2332,7 @@
 
 void java_lang_invoke_MemberName::compute_offsets() {
   klassOop k = SystemDictionary::MemberName_klass();
-  if (k != NULL && EnableMethodHandles) {
+  if (k != NULL && EnableInvokeDynamic) {
     compute_offset(_clazz_offset,     k, vmSymbols::clazz_name(),     vmSymbols::class_signature());
     compute_offset(_name_offset,      k, vmSymbols::name_name(),      vmSymbols::string_signature());
     compute_offset(_type_offset,      k, vmSymbols::type_name(),      vmSymbols::object_signature());
@@ -2358,14 +2344,14 @@
 
 void java_lang_invoke_DirectMethodHandle::compute_offsets() {
   klassOop k = SystemDictionary::DirectMethodHandle_klass();
-  if (k != NULL && EnableMethodHandles) {
+  if (k != NULL && EnableInvokeDynamic) {
     compute_offset(_vmindex_offset,   k, vmSymbols::vmindex_name(),   vmSymbols::int_signature(),    true);
   }
 }
 
 void java_lang_invoke_BoundMethodHandle::compute_offsets() {
   klassOop k = SystemDictionary::BoundMethodHandle_klass();
-  if (k != NULL && EnableMethodHandles) {
+  if (k != NULL && EnableInvokeDynamic) {
     compute_offset(_vmargslot_offset, k, vmSymbols::vmargslot_name(), vmSymbols::int_signature(),    true);
     compute_offset(_argument_offset,  k, vmSymbols::argument_name(),  vmSymbols::object_signature(), true);
   }
@@ -2373,7 +2359,7 @@
 
 void java_lang_invoke_AdapterMethodHandle::compute_offsets() {
   klassOop k = SystemDictionary::AdapterMethodHandle_klass();
-  if (k != NULL && EnableMethodHandles) {
+  if (k != NULL && EnableInvokeDynamic) {
     compute_offset(_conversion_offset, k, vmSymbols::conversion_name(), vmSymbols::int_signature(), true);
   }
 }
@@ -2991,7 +2977,7 @@
   java_lang_Class::compute_offsets();
   java_lang_Thread::compute_offsets();
   java_lang_ThreadGroup::compute_offsets();
-  if (EnableMethodHandles) {
+  if (EnableInvokeDynamic) {
     java_lang_invoke_MethodHandle::compute_offsets();
     java_lang_invoke_MemberName::compute_offsets();
     java_lang_invoke_DirectMethodHandle::compute_offsets();
@@ -2999,8 +2985,6 @@
     java_lang_invoke_AdapterMethodHandle::compute_offsets();
     java_lang_invoke_MethodType::compute_offsets();
     java_lang_invoke_MethodTypeForm::compute_offsets();
-  }
-  if (EnableInvokeDynamic) {
     java_lang_invoke_CallSite::compute_offsets();
   }
   java_security_AccessControlContext::compute_offsets();
--- a/src/share/vm/classfile/javaClasses.hpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/classfile/javaClasses.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -109,6 +109,30 @@
   static char*  as_platform_dependent_str(Handle java_string, TRAPS);
   static jchar* as_unicode_string(oop java_string, int& length);
 
+  // Compute the hash value for a java.lang.String object which would
+  // contain the characters passed in. This hash value is used for at
+  // least two purposes.
+  //
+  // (a) As the hash value used by the StringTable for bucket selection
+  //     and comparison (stored in the HashtableEntry structures).  This
+  //     is used in the String.intern() method.
+  //
+  // (b) As the hash value used by the String object itself, in
+  //     String.hashCode().  This value is normally calculate in Java code
+  //     in the String.hashCode method(), but is precomputed for String
+  //     objects in the shared archive file.
+  //
+  //     For this reason, THIS ALGORITHM MUST MATCH String.hashCode().
+  static unsigned int hash_string(jchar* s, int len) {
+    unsigned int h = 0;
+    while (len-- > 0) {
+      h = 31*h + (unsigned int) *s;
+      s++;
+    }
+    return h;
+  }
+  static unsigned int hash_string(oop java_string);
+
   static bool equals(oop java_string, jchar* chars, int len);
 
   // Conversion between '.' and '/' formats
--- a/src/share/vm/classfile/loaderConstraints.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/classfile/loaderConstraints.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/share/vm/classfile/loaderConstraints.hpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/classfile/loaderConstraints.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/share/vm/classfile/placeholders.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/classfile/placeholders.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/share/vm/classfile/placeholders.hpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/classfile/placeholders.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/share/vm/classfile/resolutionErrors.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/classfile/resolutionErrors.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/share/vm/classfile/resolutionErrors.hpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/classfile/resolutionErrors.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/share/vm/classfile/stackMapFrame.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/classfile/stackMapFrame.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/share/vm/classfile/stackMapFrame.hpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/classfile/stackMapFrame.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/share/vm/classfile/stackMapTable.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/classfile/stackMapTable.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/share/vm/classfile/stackMapTable.hpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/classfile/stackMapTable.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/share/vm/classfile/symbolTable.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/classfile/symbolTable.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
@@ -480,33 +480,6 @@
 
 
 // --------------------------------------------------------------------------
-
-
-// Compute the hash value for a java.lang.String object which would
-// contain the characters passed in. This hash value is used for at
-// least two purposes.
-//
-// (a) As the hash value used by the StringTable for bucket selection
-//     and comparison (stored in the HashtableEntry structures).  This
-//     is used in the String.intern() method.
-//
-// (b) As the hash value used by the String object itself, in
-//     String.hashCode().  This value is normally calculate in Java code
-//     in the String.hashCode method(), but is precomputed for String
-//     objects in the shared archive file.
-//
-//     For this reason, THIS ALGORITHM MUST MATCH String.hashCode().
-
-int StringTable::hash_string(jchar* s, int len) {
-  unsigned h = 0;
-  while (len-- > 0) {
-    h = 31*h + (unsigned) *s;
-    s++;
-  }
-  return h;
-}
-
-
 StringTable* StringTable::_the_table = NULL;
 
 oop StringTable::lookup(int index, jchar* name,
@@ -561,7 +534,7 @@
   ResourceMark rm;
   int length;
   jchar* chars = symbol->as_unicode(length);
-  unsigned int hashValue = hash_string(chars, length);
+  unsigned int hashValue = java_lang_String::hash_string(chars, length);
   int index = the_table()->hash_to_index(hashValue);
   return the_table()->lookup(index, chars, length, hashValue);
 }
@@ -569,7 +542,7 @@
 
 oop StringTable::intern(Handle string_or_null, jchar* name,
                         int len, TRAPS) {
-  unsigned int hashValue = hash_string(name, len);
+  unsigned int hashValue = java_lang_String::hash_string(name, len);
   int index = the_table()->hash_to_index(hashValue);
   oop string = the_table()->lookup(index, name, len, hashValue);
 
@@ -663,10 +636,7 @@
       oop s = p->literal();
       guarantee(s != NULL, "interned string is NULL");
       guarantee(s->is_perm() || !JavaObjectsInPerm, "interned string not in permspace");
-
-      int length;
-      jchar* chars = java_lang_String::as_unicode_string(s, length);
-      unsigned int h = hash_string(chars, length);
+      unsigned int h = java_lang_String::hash_string(s);
       guarantee(p->hash() == h, "broken hash in string table entry");
       guarantee(the_table()->hash_to_index(h) == i,
                 "wrong index in string table");
--- a/src/share/vm/classfile/symbolTable.hpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/classfile/symbolTable.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
@@ -242,8 +242,6 @@
     _the_table = new StringTable(t, number_of_entries);
   }
 
-  static int hash_string(jchar* s, int len);
-
   // GC support
   //   Delete pointers to otherwise-unreachable objects.
   static void unlink(BoolObjectClosure* cl);
--- a/src/share/vm/classfile/systemDictionary.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/classfile/systemDictionary.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -1017,7 +1017,7 @@
   }
 
   if (host_klass.not_null() && k.not_null()) {
-    assert(AnonymousClasses, "");
+    assert(EnableInvokeDynamic, "");
     // If it's anonymous, initialize it now, since nobody else will.
     k->set_host_klass(host_klass());
 
@@ -1887,99 +1887,27 @@
   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 pre_load = (init_opt < SystemDictionary::Opt);
-  bool try_load = true;
+  bool must_load = (init_opt < SystemDictionary::Opt);
+  bool try_load  = true;
   if (init_opt == SystemDictionary::Opt_Kernel) {
 #ifndef KERNEL
     try_load = false;
 #endif //KERNEL
   }
-  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 ((*klassp) == NULL && try_load) {
     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 false;
+  return ((*klassp) != NULL);
 }
 
 void SystemDictionary::initialize_wk_klasses_until(WKID limit_id, WKID &start_id, TRAPS) {
@@ -2038,25 +1966,15 @@
   instanceKlass::cast(WK_KLASS(FinalReference_klass))->set_reference_type(REF_FINAL);
   instanceKlass::cast(WK_KLASS(PhantomReference_klass))->set_reference_type(REF_PHANTOM);
 
-  WKID meth_group_start = WK_KLASS_ENUM_NAME(MethodHandle_klass);
-  WKID meth_group_end   = WK_KLASS_ENUM_NAME(WrongMethodTypeException_klass);
-  initialize_wk_klasses_until(meth_group_start, scan, CHECK);
-  if (EnableMethodHandles) {
-    initialize_wk_klasses_through(meth_group_end, scan, CHECK);
-  }
-  if (_well_known_klasses[meth_group_start] == NULL) {
-    // Skip the rest of the method handle classes, if MethodHandle is not loaded.
-    scan = WKID(meth_group_end+1);
-  }
-  WKID indy_group_start = WK_KLASS_ENUM_NAME(Linkage_klass);
-  WKID indy_group_end   = WK_KLASS_ENUM_NAME(CallSite_klass);
-  initialize_wk_klasses_until(indy_group_start, scan, CHECK);
+  // JSR 292 classes
+  WKID jsr292_group_start = WK_KLASS_ENUM_NAME(MethodHandle_klass);
+  WKID jsr292_group_end   = WK_KLASS_ENUM_NAME(CallSite_klass);
+  initialize_wk_klasses_until(jsr292_group_start, scan, CHECK);
   if (EnableInvokeDynamic) {
-    initialize_wk_klasses_through(indy_group_end, scan, CHECK);
-  }
-  if (_well_known_klasses[indy_group_start] == NULL) {
-    // Skip the rest of the dynamic typing classes, if Linkage is not loaded.
-    scan = WKID(indy_group_end+1);
+    initialize_wk_klasses_through(jsr292_group_end, scan, CHECK);
+  } else {
+    // Skip the JSR 292 classes, if not enabled.
+    scan = WKID(jsr292_group_end + 1);
   }
 
   initialize_wk_klasses_until(WKID_LIMIT, scan, CHECK);
@@ -2407,7 +2325,7 @@
                                                       Symbol* signature,
                                                       KlassHandle accessing_klass,
                                                       TRAPS) {
-  if (!EnableMethodHandles)  return NULL;
+  if (!EnableInvokeDynamic)  return NULL;
   vmSymbols::SID name_id = vmSymbols::find_sid(name);
   assert(name_id != vmSymbols::NO_SID, "must be a known name");
   unsigned int hash  = invoke_method_table()->compute_hash(signature, name_id);
@@ -2419,9 +2337,7 @@
     // Must create lots of stuff here, but outside of the SystemDictionary lock.
     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 for_invokeGeneric = (name_id != vmSymbols::VM_SYMBOL_ENUM_NAME(invokeExact_name));
     bool found_on_bcp = false;
     Handle mt = find_method_handle_type(signature, accessing_klass,
                                         for_invokeGeneric,
@@ -2508,14 +2424,10 @@
   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(),
-                         findMethodHandleType_signature,
+                         vmSymbols::findMethodHandleType_signature(),
                          &args, CHECK_(empty));
   Handle method_type(THREAD, (oop) result.get_jobject());
 
@@ -2523,14 +2435,10 @@
     // 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(),
-                           notifyGenericMethodType_signature,
+                           vmSymbols::notifyGenericMethodType_signature(),
                            &args, THREAD);
     if (HAS_PENDING_EXCEPTION) {
       // If the notification fails, just kill it.
@@ -2579,14 +2487,10 @@
   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(),
-                         linkMethodHandleConstant_signature,
+                         vmSymbols::linkMethodHandleConstant_signature(),
                          &args, CHECK_(empty));
   return Handle(THREAD, (oop) result.get_jobject());
 }
@@ -2617,17 +2521,10 @@
   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(),
-                         makeDynamicCallSite_signature,
+                         vmSymbols::makeDynamicCallSite_signature(),
                          &args, CHECK_(empty));
   oop call_site_oop = (oop) result.get_jobject();
   assert(call_site_oop->is_oop()
@@ -2708,28 +2605,10 @@
       argument_info_result = argument_info;  // return argument_info to caller
       return bsm;
     }
-    // else null BSM; fall through
-  } else if (tag.is_name_and_type()) {
-    // JSR 292 EDR does not have JVM_CONSTANT_InvokeDynamic
-    // a bare name&type defaults its BSM to null, so fall through...
   } else {
     ShouldNotReachHere();  // verifier does not allow this
   }
 
-  // Fall through to pick up the per-class bootstrap method.
-  // This mechanism may go away in the PFD.
-  assert(AllowTransitionalJSR292, "else the verifier should have stopped us already");
-  argument_info_result = empty;  // return no argument_info to caller
-  oop bsm_oop = instanceKlass::cast(caller_method->method_holder())->bootstrap_method();
-  if (bsm_oop != NULL) {
-    if (TraceMethodHandles) {
-      tty->print_cr("bootstrap method for "PTR_FORMAT" registered as "PTR_FORMAT":",
-                    (intptr_t) caller_method(), (intptr_t) bsm_oop);
-    }
-    assert(bsm_oop->is_oop(), "must be sane");
-    return Handle(THREAD, bsm_oop);
-  }
-
   return empty;
 }
 
--- a/src/share/vm/classfile/systemDictionary.hpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/classfile/systemDictionary.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -146,7 +146,6 @@
   /* support for dynamic typing; it's OK if these are NULL in earlier JDKs */ \
   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) \
@@ -154,7 +153,6 @@
   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 */          \
                                                                               \
@@ -207,7 +205,7 @@
 
   enum InitOption {
     Pre,                        // preloaded; error if not present
-    Pre_JSR292,                 // preloaded if EnableMethodHandles
+    Pre_JSR292,                 // preloaded if EnableInvokeDynamic
 
     // Order is significant.  Options before this point require resolve_or_fail.
     // Options after this point will use resolve_or_null instead.
@@ -422,8 +420,6 @@
     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)]); }
@@ -445,9 +441,6 @@
 
   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; }
--- a/src/share/vm/classfile/verificationType.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/classfile/verificationType.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/share/vm/classfile/verificationType.hpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/classfile/verificationType.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/share/vm/classfile/verifier.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/classfile/verifier.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -1671,19 +1671,13 @@
       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(
-        methodHandle_name), CHECK_VERIFY(this));
+        vmSymbols::java_lang_invoke_MethodHandle()), 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(
-        methodType_name), CHECK_VERIFY(this));
+        vmSymbols::java_lang_invoke_MethodType()), CHECK_VERIFY(this));
   } else {
     verify_error(bci, "Invalid index in ldc");
     return;
@@ -1950,8 +1944,7 @@
   unsigned int types = (opcode == Bytecodes::_invokeinterface
                                 ? 1 << JVM_CONSTANT_InterfaceMethodref
                       : opcode == Bytecodes::_invokedynamic
-                                ? ((AllowTransitionalJSR292 ? 1 << JVM_CONSTANT_NameAndType : 0)
-                                  |1 << JVM_CONSTANT_InvokeDynamic)
+                                ? 1 << JVM_CONSTANT_InvokeDynamic
                                 : 1 << JVM_CONSTANT_Methodref);
   verify_cp_type(index, cp, types, CHECK_VERIFY(this));
 
--- a/src/share/vm/classfile/verifier.hpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/classfile/verifier.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/share/vm/classfile/vmSymbols.hpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/classfile/vmSymbols.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -245,44 +245,15 @@
   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/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/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/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/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) )                           \
                                                                                                   \
@@ -911,8 +882,6 @@
   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,      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_lang_invoke_MethodHandle, invokeExact_name,   object_array_object_signature, F_RN) \
--- a/src/share/vm/code/codeBlob.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/code/codeBlob.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/share/vm/code/codeCache.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/code/codeCache.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -964,3 +964,16 @@
             nof_blobs(), nof_nmethods(), nof_adapters(),
             unallocated_capacity(), largest_free_block());
 }
+
+size_t CodeCache::largest_free_block() {
+  // This is called both with and without CodeCache_lock held so
+  // handle both cases.
+  if (CodeCache_lock->owned_by_self()) {
+    return _heap->largest_free_block();
+  } else {
+    // Avoid lock ordering problems with ttyLock.
+    ttyUnlocker ttyul;
+    MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
+    return _heap->largest_free_block();
+  }
+}
--- a/src/share/vm/code/codeCache.hpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/code/codeCache.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
@@ -160,7 +160,7 @@
   static size_t  capacity()                      { return _heap->capacity(); }
   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 size_t  largest_free_block();
   static bool    needs_flushing()                { return largest_free_block() < CodeCacheFlushingMinimumFreeSpace; }
 
   static bool needs_cache_clean()                { return _needs_cache_clean; }
--- a/src/share/vm/code/compiledIC.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/code/compiledIC.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/share/vm/code/compiledIC.hpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/code/compiledIC.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/share/vm/code/dependencies.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/code/dependencies.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/share/vm/code/icBuffer.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/code/icBuffer.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/share/vm/code/nmethod.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/code/nmethod.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -28,6 +28,7 @@
 #include "code/nmethod.hpp"
 #include "code/scopeDesc.hpp"
 #include "compiler/abstractCompiler.hpp"
+#include "compiler/compileBroker.hpp"
 #include "compiler/compileLog.hpp"
 #include "compiler/compilerOracle.hpp"
 #include "compiler/disassembler.hpp"
@@ -469,6 +470,7 @@
 
 
 nmethod* nmethod::new_native_nmethod(methodHandle method,
+  int compile_id,
   CodeBuffer *code_buffer,
   int vep_offset,
   int frame_complete,
@@ -485,7 +487,7 @@
     offsets.set_value(CodeOffsets::Verified_Entry, vep_offset);
     offsets.set_value(CodeOffsets::Frame_Complete, frame_complete);
     nm = new (native_nmethod_size)
-      nmethod(method(), native_nmethod_size, &offsets,
+      nmethod(method(), native_nmethod_size, compile_id, &offsets,
               code_buffer, frame_size,
               basic_lock_owner_sp_offset, basic_lock_sp_offset,
               oop_maps);
@@ -610,6 +612,7 @@
 nmethod::nmethod(
   methodOop method,
   int nmethod_size,
+  int compile_id,
   CodeOffsets* offsets,
   CodeBuffer* code_buffer,
   int frame_size,
@@ -644,7 +647,7 @@
     _handler_table_offset    = _dependencies_offset;
     _nul_chk_table_offset    = _handler_table_offset;
     _nmethod_end_offset      = _nul_chk_table_offset;
-    _compile_id              = 0;  // default
+    _compile_id              = compile_id;
     _comp_level              = CompLevel_none;
     _entry_point             = code_begin()          + offsets->value(CodeOffsets::Entry);
     _verified_entry_point    = code_begin()          + offsets->value(CodeOffsets::Verified_Entry);
@@ -930,72 +933,11 @@
 #undef LOG_OFFSET
 
 
-void nmethod::print_compilation(outputStream *st, const char *method_name, const char *title,
-                                methodOop method, bool is_blocking, int compile_id, int bci, int comp_level) {
-  bool is_synchronized = false, has_xhandler = false, is_native = false;
-  int code_size = -1;
-  if (method != NULL) {
-    is_synchronized = method->is_synchronized();
-    has_xhandler    = method->has_exception_handler();
-    is_native       = method->is_native();
-    code_size       = method->code_size();
-  }
-  // print compilation number
-  st->print("%7d %3d", (int)tty->time_stamp().milliseconds(), compile_id);
-
-  // print method attributes
-  const bool is_osr = bci != InvocationEntryBci;
-  const char blocking_char  = is_blocking     ? 'b' : ' ';
-  const char compile_type   = is_osr          ? '%' : ' ';
-  const char sync_char      = is_synchronized ? 's' : ' ';
-  const char exception_char = has_xhandler    ? '!' : ' ';
-  const char native_char    = is_native       ? 'n' : ' ';
-  st->print("%c%c%c%c%c ", compile_type, sync_char, exception_char, blocking_char, native_char);
-  if (TieredCompilation) {
-    st->print("%d ", comp_level);
-  }
-
-  // print optional title
-  bool do_nl = false;
-  if (title != NULL) {
-    int tlen = (int) strlen(title);
-    bool do_nl = false;
-    if (tlen > 0 && title[tlen-1] == '\n') { tlen--; do_nl = true; }
-    st->print("%.*s", tlen, title);
-  } else {
-    do_nl = true;
-  }
-
-  // print method name string if given
-  if (method_name != NULL) {
-    st->print(method_name);
-  } else {
-    // otherwise as the method to print itself
-    if (method != NULL && !Universe::heap()->is_gc_active()) {
-      method->print_short_name(st);
-    } else {
-      st->print("(method)");
-    }
-  }
-
-  if (method != NULL) {
-    // print osr_bci if any
-    if (is_osr) st->print(" @ %d", bci);
-    // print method size
-    st->print(" (%d bytes)", code_size);
-  }
-  if (do_nl) st->cr();
-}
-
 // Print out more verbose output usually for a newly created nmethod.
-void nmethod::print_on(outputStream* st, const char* title) const {
+void nmethod::print_on(outputStream* st, const char* msg) const {
   if (st != NULL) {
     ttyLocker ttyl;
-    print_compilation(st, /*method_name*/NULL, title,
-                      method(), /*is_blocking*/false,
-                      compile_id(),
-                      is_osr_method() ? osr_entry_bci() : InvocationEntryBci,
-                      comp_level());
+    CompileTask::print_compilation(st, this, msg);
     if (WizardMode) st->print(" (" INTPTR_FORMAT ")", this);
   }
 }
@@ -1309,8 +1251,7 @@
     }
   }
   if (PrintCompilation && _state != unloaded) {
-    print_on(tty, _state == zombie ? "made zombie " : "made not entrant ");
-    tty->cr();
+    print_on(tty, _state == zombie ? "made zombie" : "made not entrant");
   }
 }
 
@@ -1816,7 +1757,7 @@
           break;
       }
       // Mark was clear when we first saw this guy.
-      NOT_PRODUCT(if (TraceScavenge)  print_on(tty, "oops_do, mark\n"));
+      NOT_PRODUCT(if (TraceScavenge)  print_on(tty, "oops_do, mark"));
       return false;
     }
   }
@@ -1841,7 +1782,7 @@
     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"));
+    NOT_PRODUCT(if (TraceScavenge)  cur->print_on(tty, "oops_do, unmark"));
     cur = next;
   }
   void* required = _oops_do_mark_nmethods;
@@ -2396,7 +2337,7 @@
   ResourceMark rm;
   ttyLocker ttyl;   // keep the following output all in one block
 
-  tty->print("Compiled ");
+  tty->print("Compiled method ");
 
   if (is_compiled_by_c1()) {
     tty->print("(c1) ");
@@ -2408,8 +2349,8 @@
     tty->print("(nm) ");
   }
 
-  print_on(tty, "nmethod");
-  tty->cr();
+  print_on(tty, NULL);
+
   if (WizardMode) {
     tty->print("((nmethod*) "INTPTR_FORMAT ") ", this);
     tty->print(" for method " INTPTR_FORMAT , (address)method());
@@ -2796,7 +2737,8 @@
 #ifndef PRODUCT
 
 void nmethod::print_value_on(outputStream* st) const {
-  print_on(st, "nmethod");
+  st->print("nmethod");
+  print_on(st, NULL);
 }
 
 void nmethod::print_calls(outputStream* st) {
--- a/src/share/vm/code/nmethod.hpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/code/nmethod.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -229,6 +229,7 @@
   // For native wrappers
   nmethod(methodOop method,
           int nmethod_size,
+          int compile_id,
           CodeOffsets* offsets,
           CodeBuffer *code_buffer,
           int frame_size,
@@ -299,6 +300,7 @@
                               int comp_level);
 
   static nmethod* new_native_nmethod(methodHandle method,
+                                     int compile_id,
                                      CodeBuffer *code_buffer,
                                      int vep_offset,
                                      int frame_complete,
@@ -500,8 +502,8 @@
   address continuation_for_implicit_exception(address pc);
 
   // On-stack replacement support
-  int   osr_entry_bci() const                     { assert(_entry_bci != InvocationEntryBci, "wrong kind of nmethod"); return _entry_bci; }
-  address  osr_entry() const                      { assert(_entry_bci != InvocationEntryBci, "wrong kind of nmethod"); return _osr_entry_point; }
+  int   osr_entry_bci() const                     { assert(is_osr_method(), "wrong kind of nmethod"); return _entry_bci; }
+  address  osr_entry() const                      { assert(is_osr_method(), "wrong kind of nmethod"); return _osr_entry_point; }
   void  invalidate_osr_method();
   nmethod* osr_link() const                       { return _osr_link; }
   void     set_osr_link(nmethod *n)               { _osr_link = n; }
@@ -608,10 +610,6 @@
   void verify_scopes();
   void verify_interrupt_point(address interrupt_point);
 
-  // print compilation helper
-  static void print_compilation(outputStream *st, const char *method_name, const char *title,
-                                methodOop method, bool is_blocking, int compile_id, int bci, int comp_level);
-
   // printing support
   void print()                          const;
   void print_code();
@@ -627,7 +625,7 @@
 
   // need to re-define this from CodeBlob else the overload hides it
   virtual void print_on(outputStream* st) const { CodeBlob::print_on(st); }
-  void print_on(outputStream* st, const char* title) const;
+  void print_on(outputStream* st, const char* msg) const;
 
   // Logging
   void log_identity(xmlStream* log) const;
--- a/src/share/vm/code/relocInfo.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/code/relocInfo.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
@@ -472,20 +472,14 @@
   return itr._rh;
 }
 
-
-static inline bool is_index(intptr_t index) {
-  return 0 < index && index < os::vm_page_size();
-}
-
-
 int32_t Relocation::runtime_address_to_index(address runtime_address) {
-  assert(!is_index((intptr_t)runtime_address), "must not look like an index");
+  assert(!is_reloc_index((intptr_t)runtime_address), "must not look like an index");
 
   if (runtime_address == NULL)  return 0;
 
   StubCodeDesc* p = StubCodeDesc::desc_for(runtime_address);
   if (p != NULL && p->begin() == runtime_address) {
-    assert(is_index(p->index()), "there must not be too many stubs");
+    assert(is_reloc_index(p->index()), "there must not be too many stubs");
     return (int32_t)p->index();
   } else {
     // Known "miscellaneous" non-stub pointers:
@@ -506,7 +500,7 @@
 address Relocation::index_to_runtime_address(int32_t index) {
   if (index == 0)  return NULL;
 
-  if (is_index(index)) {
+  if (is_reloc_index(index)) {
     StubCodeDesc* p = StubCodeDesc::desc_for_index(index);
     assert(p != NULL, "there must be a stub for this index");
     return p->begin();
@@ -634,7 +628,7 @@
 #ifndef _LP64
   p = pack_1_int_to(p, index);
 #else
-  if (is_index(index)) {
+  if (is_reloc_index(index)) {
     p = pack_2_ints_to(p, index, 0);
   } else {
     jlong t = (jlong) _target;
@@ -642,7 +636,7 @@
     int32_t hi = high(t);
     p = pack_2_ints_to(p, lo, hi);
     DEBUG_ONLY(jlong t1 = jlong_from(hi, lo));
-    assert(!is_index(t1) && (address) t1 == _target, "not symmetric");
+    assert(!is_reloc_index(t1) && (address) t1 == _target, "not symmetric");
   }
 #endif /* _LP64 */
   dest->set_locs_end((relocInfo*) p);
@@ -656,7 +650,7 @@
   int32_t lo, hi;
   unpack_2_ints(lo, hi);
   jlong t = jlong_from(hi, lo);;
-  if (is_index(t)) {
+  if (is_reloc_index(t)) {
     _target = index_to_runtime_address(t);
   } else {
     _target = (address) t;
--- a/src/share/vm/code/relocInfo.hpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/code/relocInfo.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
@@ -703,6 +703,10 @@
     assert(datalen()==0 || type()==relocInfo::none, "no data here");
   }
 
+  static bool is_reloc_index(intptr_t index) {
+    return 0 < index && index < os::vm_page_size();
+  }
+
  protected:
   // Helper functions for pack_data_to() and unpack_data().
 
@@ -1127,6 +1131,12 @@
     return rh;
   }
 
+  // Some address looking values aren't safe to treat as relocations
+  // and should just be treated as constants.
+  static bool can_be_relocated(address target) {
+    return target != NULL && !is_reloc_index((intptr_t)target);
+  }
+
  private:
   address _target;                  // address in runtime
 
--- a/src/share/vm/code/vmreg.hpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/code/vmreg.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/share/vm/compiler/compileBroker.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/compiler/compileBroker.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -268,11 +268,6 @@
 }
 
 
-void CompileTask::print_compilation(outputStream *st, methodOop method, char* method_name) {
-  nmethod::print_compilation(st, method_name,/*title*/ NULL, method,
-                             is_blocking(), compile_id(), osr_bci(), comp_level());
-}
-
 // ------------------------------------------------------------------
 // CompileTask::print_line_on_error
 //
@@ -284,31 +279,115 @@
 // Otherwise it's the same as CompileTask::print_line()
 //
 void CompileTask::print_line_on_error(outputStream* st, char* buf, int buflen) {
-  methodOop method = (methodOop)JNIHandles::resolve(_method);
   // print compiler name
   st->print("%s:", CompileBroker::compiler(comp_level())->name());
-  char* method_name = NULL;
-  if (method != NULL) {
-    method_name = method->name_and_sig_as_C_string(buf, buflen);
-  }
-  print_compilation(st, method, method_name);
+  print_compilation(st);
 }
 
 // ------------------------------------------------------------------
 // CompileTask::print_line
 void CompileTask::print_line() {
-  Thread *thread = Thread::current();
-  methodHandle method(thread,
-                      (methodOop)JNIHandles::resolve(method_handle()));
-  ResourceMark rm(thread);
-
   ttyLocker ttyl;  // keep the following output all in one block
-
   // print compiler name if requested
   if (CIPrintCompilerName) tty->print("%s:", CompileBroker::compiler(comp_level())->name());
-  print_compilation(tty, method(), NULL);
+  print_compilation();
+}
+
+
+// ------------------------------------------------------------------
+// CompileTask::print_compilation_impl
+void CompileTask::print_compilation_impl(outputStream* st, methodOop method, int compile_id, int comp_level, bool is_osr_method, int osr_bci, bool is_blocking, const char* msg) {
+  st->print("%7d ", (int) st->time_stamp().milliseconds());  // print timestamp
+  st->print("%4d ", compile_id);    // print compilation number
+
+  // method attributes
+  const char compile_type   = is_osr_method                   ? '%' : ' ';
+  const char sync_char      = method->is_synchronized()       ? 's' : ' ';
+  const char exception_char = method->has_exception_handler() ? '!' : ' ';
+  const char blocking_char  = is_blocking                     ? 'b' : ' ';
+  const char native_char    = method->is_native()             ? 'n' : ' ';
+
+  // print method attributes
+  st->print("%c%c%c%c%c ", compile_type, sync_char, exception_char, blocking_char, native_char);
+
+  if (TieredCompilation) {
+    if (comp_level != -1)  st->print("%d ", comp_level);
+    else                   st->print("- ");
+  }
+  st->print("     ");  // more indent
+
+  method->print_short_name(st);
+  if (is_osr_method) {
+    st->print(" @ %d", osr_bci);
+  }
+  st->print(" (%d bytes)", method->code_size());
+
+  if (msg != NULL) {
+    st->print("   %s", msg);
+  }
+  st->cr();
 }
 
+// ------------------------------------------------------------------
+// CompileTask::print_inlining
+void CompileTask::print_inlining(outputStream* st, ciMethod* method, int inline_level, int bci, const char* msg) {
+  //         1234567
+  st->print("        ");     // print timestamp
+  //         1234
+  st->print("     ");        // print compilation number
+
+  // method attributes
+  const char sync_char      = method->is_synchronized()        ? 's' : ' ';
+  const char exception_char = method->has_exception_handlers() ? '!' : ' ';
+  const char monitors_char  = method->has_monitor_bytecodes()  ? 'm' : ' ';
+
+  // print method attributes
+  st->print(" %c%c%c  ", sync_char, exception_char, monitors_char);
+
+  if (TieredCompilation) {
+    st->print("  ");
+  }
+  st->print("     ");        // more indent
+  st->print("    ");         // initial inlining indent
+
+  for (int i = 0; i < inline_level; i++)  st->print("  ");
+
+  st->print("@ %d  ", bci);  // print bci
+  method->print_short_name(st);
+  st->print(" (%d bytes)", method->code_size());
+
+  if (msg != NULL) {
+    st->print("   %s", msg);
+  }
+  st->cr();
+}
+
+// ------------------------------------------------------------------
+// CompileTask::print_inline_indent
+void CompileTask::print_inline_indent(int inline_level, outputStream* st) {
+  //         1234567
+  st->print("        ");     // print timestamp
+  //         1234
+  st->print("     ");        // print compilation number
+  //         %s!bn
+  st->print("      ");       // print method attributes
+  if (TieredCompilation) {
+    st->print("  ");
+  }
+  st->print("     ");        // more indent
+  st->print("    ");         // initial inlining indent
+  for (int i = 0; i < inline_level; i++)  st->print("  ");
+}
+
+// ------------------------------------------------------------------
+// CompileTask::print_compilation
+void CompileTask::print_compilation(outputStream* st) {
+  oop rem = JNIHandles::resolve(method_handle());
+  assert(rem != NULL && rem->is_method(), "must be");
+  methodOop method = (methodOop) rem;
+  bool is_osr_method = osr_bci() != InvocationEntryBci;
+  print_compilation_impl(st, method, compile_id(), comp_level(), is_osr_method, osr_bci(), is_blocking());
+}
 
 // ------------------------------------------------------------------
 // CompileTask::log_task
@@ -768,9 +847,9 @@
 // Initialize the compilation queue
 void CompileBroker::init_compiler_threads(int c1_compiler_count, int c2_compiler_count) {
   EXCEPTION_MARK;
-#ifndef ZERO
+#if !defined(ZERO) && !defined(SHARK)
   assert(c2_compiler_count > 0 || c1_compiler_count > 0, "No compilers?");
-#endif // !ZERO
+#endif // !ZERO && !SHARK
   if (c2_compiler_count > 0) {
     _c2_method_queue  = new CompileQueue("C2MethodQueue",  MethodCompileQueue_lock);
   }
@@ -874,6 +953,14 @@
     return;
   }
 
+#ifndef PRODUCT
+  if (osr_bci != -1 && !FLAG_IS_DEFAULT(OSROnlyBCI)) {
+    if ((OSROnlyBCI > 0) ? (OSROnlyBCI != osr_bci) : (-OSROnlyBCI == osr_bci)) {
+      // Positive OSROnlyBCI means only compile that bci.  Negative means don't compile that BCI.
+      return;
+    }
+  }
+#endif
 
   // If this method is already in the compile queue, then
   // we do not block the current thread.
@@ -1031,7 +1118,7 @@
 
   assert(!HAS_PENDING_EXCEPTION, "No exception should be present");
   // some prerequisites that are compiler specific
-  if (compiler(comp_level)->is_c2()) {
+  if (compiler(comp_level)->is_c2() || compiler(comp_level)->is_shark()) {
     method->constants()->resolve_string_constants(CHECK_0);
     // Resolve all classes seen in the signature of the method
     // we are compiling.
@@ -1078,7 +1165,13 @@
   // do the compilation
   if (method->is_native()) {
     if (!PreferInterpreterNativeStubs) {
-      (void) AdapterHandlerLibrary::create_native_wrapper(method);
+      // Acquire our lock.
+      int compile_id;
+      {
+        MutexLocker locker(MethodCompileQueue_lock, THREAD);
+        compile_id = assign_compile_id(method, standard_entry_bci);
+      }
+      (void) AdapterHandlerLibrary::create_native_wrapper(method, compile_id);
     } else {
       return NULL;
     }
@@ -1186,7 +1279,6 @@
   assert(MethodCompileQueue_lock->owner() == Thread::current(),
          "must hold the compilation queue lock");
   bool is_osr = (osr_bci != standard_entry_bci);
-  assert(!method->is_native(), "no longer compile natives");
   uint id;
   if (CICountOSR && is_osr) {
     id = ++_osr_compilation_id;
--- a/src/share/vm/compiler/compileBroker.hpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/compiler/compileBroker.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
@@ -56,7 +56,6 @@
   int          _hot_count;    // information about its invocation counter
   const char*  _comment;      // more info about the task
 
-  void print_compilation(outputStream *st, methodOop method, char* method_name);
  public:
   CompileTask() {
     _lock = new Monitor(Mutex::nonleaf+2, "CompileTaskLock");
@@ -96,10 +95,26 @@
   CompileTask* prev() const                      { return _prev; }
   void         set_prev(CompileTask* prev)       { _prev = prev; }
 
+private:
+  static void  print_compilation_impl(outputStream* st, methodOop method, int compile_id, int comp_level, bool is_osr_method = false, int osr_bci = -1, bool is_blocking = false, const char* msg = NULL);
+
+public:
+  void         print_compilation(outputStream* st = tty);
+  static void  print_compilation(outputStream* st, const nmethod* nm, const char* msg = NULL) {
+    print_compilation_impl(st, nm->method(), nm->compile_id(), nm->comp_level(), nm->is_osr_method(), nm->is_osr_method() ? nm->osr_entry_bci() : -1, /*is_blocking*/ false, msg);
+  }
+
+  static void  print_inlining(outputStream* st, ciMethod* method, int inline_level, int bci, const char* msg = NULL);
+  static void  print_inlining(ciMethod* method, int inline_level, int bci, const char* msg = NULL) {
+    print_inlining(tty, method, inline_level, bci, msg);
+  }
+
+  static void  print_inline_indent(int inline_level, outputStream* st = tty);
+
   void         print();
   void         print_line();
+  void         print_line_on_error(outputStream* st, char* buf, int buflen);
 
-  void         print_line_on_error(outputStream* st, char* buf, int buflen);
   void         log_task(xmlStream* log);
   void         log_task_queued();
   void         log_task_start(CompileLog* log);
--- a/src/share/vm/compiler/compileLog.hpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/compiler/compileLog.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2010, 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
--- a/src/share/vm/compiler/compilerOracle.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/compiler/compilerOracle.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/share/vm/compiler/compilerOracle.hpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/compiler/compilerOracle.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/share/vm/compiler/disassembler.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/compiler/disassembler.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 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
--- a/src/share/vm/compiler/disassembler.hpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/compiler/disassembler.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 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
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
--- a/src/share/vm/gc_implementation/g1/collectionSetChooser.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/gc_implementation/g1/collectionSetChooser.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -262,39 +262,18 @@
   for (int i = 0; i < _numMarkedRegions; i++) {
     assert(_markedRegions.at(i) != NULL, "Should be true by sorting!");
     _markedRegions.at(i)->set_sort_index(i);
-    if (G1PrintRegionLivenessInfo > 0) {
-      if (i == 0) gclog_or_tty->print_cr("Sorted marked regions:");
-      if (i < G1PrintRegionLivenessInfo ||
-          (_numMarkedRegions-i) < G1PrintRegionLivenessInfo) {
-        HeapRegion* hr = _markedRegions.at(i);
-        size_t u = hr->used();
-        gclog_or_tty->print_cr("  Region %d: %d used, %d max live, %5.2f%%.",
-                      i, u, hr->max_live_bytes(),
-                      100.0*(float)hr->max_live_bytes()/(float)u);
-      }
+  }
+  if (G1PrintRegionLivenessInfo) {
+    G1PrintRegionLivenessInfoClosure cl(gclog_or_tty, "Post-Sorting");
+    for (int i = 0; i < _numMarkedRegions; ++i) {
+      HeapRegion* r = _markedRegions.at(i);
+      cl.doHeapRegion(r);
     }
   }
-  if (G1PolicyVerbose > 1)
-    printSortedHeapRegions();
   assert(verify(), "should now be sorted");
 }
 
 void
-printHeapRegion(HeapRegion *hr) {
-  if (hr->isHumongous())
-    gclog_or_tty->print("H: ");
-  if (hr->in_collection_set())
-    gclog_or_tty->print("CS: ");
-  gclog_or_tty->print_cr("Region " PTR_FORMAT " (%s%s) "
-                         "[" PTR_FORMAT ", " PTR_FORMAT"] "
-                         "Used: " SIZE_FORMAT "K, garbage: " SIZE_FORMAT "K.",
-                         hr, hr->is_young() ? "Y " : "  ",
-                         hr->is_marked()? "M1" : "M0",
-                         hr->bottom(), hr->end(),
-                         hr->used()/K, hr->garbage_bytes()/K);
-}
-
-void
 CollectionSetChooser::addMarkedHeapRegion(HeapRegion* hr) {
   assert(!hr->isHumongous(),
          "Humongous regions shouldn't be added to the collection set");
@@ -351,27 +330,9 @@
 
 void
 CollectionSetChooser::updateAfterFullCollection() {
-  G1CollectedHeap* g1h = G1CollectedHeap::heap();
   clearMarkedHeapRegions();
 }
 
-void
-CollectionSetChooser::printSortedHeapRegions() {
-  gclog_or_tty->print_cr("Printing %d Heap Regions sorted by amount of known garbage",
-                _numMarkedRegions);
-
-  DEBUG_ONLY(int marked_count = 0;)
-  for (int i = 0; i < _markedRegions.length(); i++) {
-    HeapRegion* r = _markedRegions.at(i);
-    if (r != NULL) {
-      printHeapRegion(r);
-      DEBUG_ONLY(marked_count++;)
-    }
-  }
-  assert(marked_count == _numMarkedRegions, "must be");
-  gclog_or_tty->print_cr("Done sorted heap region print");
-}
-
 void CollectionSetChooser::removeRegion(HeapRegion *hr) {
   int si = hr->sort_index();
   assert(si == -1 || hr->is_marked(), "Sort index not valid.");
--- a/src/share/vm/gc_implementation/g1/collectionSetChooser.hpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/gc_implementation/g1/collectionSetChooser.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -100,8 +100,6 @@
 
   CollectionSetChooser();
 
-  void printSortedHeapRegions();
-
   void sortMarkedHeapRegions();
   void fillCache();
   bool addRegionToCache(void);
--- a/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -31,23 +31,31 @@
 #include "gc_implementation/g1/heapRegionSeq.inline.hpp"
 #include "memory/space.inline.hpp"
 #include "runtime/atomic.hpp"
+#include "runtime/java.hpp"
 #include "utilities/copy.hpp"
 
 // Possible sizes for the card counts cache: odd primes that roughly double in size.
 // (See jvmtiTagMap.cpp).
-int ConcurrentG1Refine::_cc_cache_sizes[] = {
-        16381,    32771,    76831,    150001,   307261,
-       614563,  1228891,  2457733,   4915219,  9830479,
-     19660831, 39321619, 78643219, 157286461,       -1
+
+#define MAX_SIZE ((size_t) -1)
+
+size_t ConcurrentG1Refine::_cc_cache_sizes[] = {
+          16381,    32771,    76831,    150001,   307261,
+         614563,  1228891,  2457733,   4915219,  9830479,
+       19660831, 39321619, 78643219, 157286461,  MAX_SIZE
   };
 
 ConcurrentG1Refine::ConcurrentG1Refine() :
   _card_counts(NULL), _card_epochs(NULL),
-  _n_card_counts(0), _max_n_card_counts(0),
+  _n_card_counts(0), _max_cards(0), _max_n_card_counts(0),
   _cache_size_index(0), _expand_card_counts(false),
   _hot_cache(NULL),
   _def_use_cache(false), _use_cache(false),
-  _n_periods(0),
+  // We initialize the epochs of the array to 0. By initializing
+  // _n_periods to 1 and not 0 we automatically invalidate all the
+  // entries on the array. Otherwise we might accidentally think that
+  // we claimed a card that was in fact never set (see CR7033292).
+  _n_periods(1),
   _threads(NULL), _n_threads(0)
 {
 
@@ -98,27 +106,44 @@
 void ConcurrentG1Refine::init() {
   if (G1ConcRSLogCacheSize > 0) {
     _g1h = G1CollectedHeap::heap();
-    _max_n_card_counts =
-      (unsigned) (_g1h->max_capacity() >> CardTableModRefBS::card_shift);
+
+    _max_cards = _g1h->max_capacity() >> CardTableModRefBS::card_shift;
+    _max_n_card_counts = _max_cards * G1MaxHotCardCountSizePercent / 100;
 
     size_t max_card_num = ((size_t)1 << (sizeof(unsigned)*BitsPerByte-1)) - 1;
-    guarantee(_max_n_card_counts < max_card_num, "card_num representation");
+    guarantee(_max_cards < max_card_num, "card_num representation");
 
-    int desired = _max_n_card_counts / InitialCacheFraction;
-    for (_cache_size_index = 0;
-              _cc_cache_sizes[_cache_size_index] >= 0; _cache_size_index++) {
-      if (_cc_cache_sizes[_cache_size_index] >= desired) break;
-    }
-    _cache_size_index = MAX2(0, (_cache_size_index - 1));
+    // We need _n_card_counts to be less than _max_n_card_counts here
+    // so that the expansion call (below) actually allocates the
+    // _counts and _epochs arrays.
+    assert(_n_card_counts == 0, "pre-condition");
+    assert(_max_n_card_counts > 0, "pre-condition");
 
-    int initial_size = _cc_cache_sizes[_cache_size_index];
-    if (initial_size < 0) initial_size = _max_n_card_counts;
+    // Find the index into cache size array that is of a size that's
+    // large enough to hold desired_sz.
+    size_t desired_sz = _max_cards / InitialCacheFraction;
+    int desired_sz_index = 0;
+    while (_cc_cache_sizes[desired_sz_index] < desired_sz) {
+      desired_sz_index += 1;
+      assert(desired_sz_index <  MAX_CC_CACHE_INDEX, "invariant");
+    }
+    assert(desired_sz_index <  MAX_CC_CACHE_INDEX, "invariant");
 
-    // Make sure we don't go bigger than we will ever need
-    _n_card_counts = MIN2((unsigned) initial_size, _max_n_card_counts);
+    // If the desired_sz value is between two sizes then
+    // _cc_cache_sizes[desired_sz_index-1] < desired_sz <= _cc_cache_sizes[desired_sz_index]
+    // we will start with the lower size in the optimistic expectation that
+    // we will not need to expand up. Note desired_sz_index could also be 0.
+    if (desired_sz_index > 0 &&
+        _cc_cache_sizes[desired_sz_index] > desired_sz) {
+      desired_sz_index -= 1;
+    }
 
-    _card_counts = NEW_C_HEAP_ARRAY(CardCountCacheEntry, _n_card_counts);
-    _card_epochs = NEW_C_HEAP_ARRAY(CardEpochCacheEntry, _n_card_counts);
+    if (!expand_card_count_cache(desired_sz_index)) {
+      // Allocation was unsuccessful - exit
+      vm_exit_during_initialization("Could not reserve enough space for card count cache");
+    }
+    assert(_n_card_counts > 0, "post-condition");
+    assert(_cache_size_index == desired_sz_index, "post-condition");
 
     Copy::fill_to_bytes(&_card_counts[0],
                         _n_card_counts * sizeof(CardCountCacheEntry));
@@ -163,10 +188,13 @@
 
 ConcurrentG1Refine::~ConcurrentG1Refine() {
   if (G1ConcRSLogCacheSize > 0) {
+    // Please see the comment in allocate_card_count_cache
+    // for why we call os::malloc() and os::free() directly.
     assert(_card_counts != NULL, "Logic");
-    FREE_C_HEAP_ARRAY(CardCountCacheEntry, _card_counts);
+    os::free(_card_counts);
     assert(_card_epochs != NULL, "Logic");
-    FREE_C_HEAP_ARRAY(CardEpochCacheEntry, _card_epochs);
+    os::free(_card_epochs);
+
     assert(_hot_cache != NULL, "Logic");
     FREE_C_HEAP_ARRAY(jbyte*, _hot_cache);
   }
@@ -382,29 +410,93 @@
   }
 }
 
-void ConcurrentG1Refine::expand_card_count_cache() {
-  if (_n_card_counts < _max_n_card_counts) {
-    int new_idx = _cache_size_index+1;
-    int new_size = _cc_cache_sizes[new_idx];
-    if (new_size < 0) new_size = _max_n_card_counts;
+// The arrays used to hold the card counts and the epochs must have
+// a 1:1 correspondence. Hence they are allocated and freed together
+// Returns true if the allocations of both the counts and epochs
+// were successful; false otherwise.
+bool ConcurrentG1Refine::allocate_card_count_cache(size_t n,
+                                                   CardCountCacheEntry** counts,
+                                                   CardEpochCacheEntry** epochs) {
+  // We call the allocation/free routines directly for the counts
+  // and epochs arrays. The NEW_C_HEAP_ARRAY/FREE_C_HEAP_ARRAY
+  // macros call AllocateHeap and FreeHeap respectively.
+  // AllocateHeap will call vm_exit_out_of_memory in the event
+  // of an allocation failure and abort the JVM. With the
+  // _counts/epochs arrays we only need to abort the JVM if the
+  // initial allocation of these arrays fails.
+  //
+  // Additionally AllocateHeap/FreeHeap do some tracing of
+  // allocate/free calls so calling one without calling the
+  // other can cause inconsistencies in the tracing. So we
+  // call neither.
 
-    // Make sure we don't go bigger than we will ever need
-    new_size = MIN2((unsigned) new_size, _max_n_card_counts);
+  assert(*counts == NULL, "out param");
+  assert(*epochs == NULL, "out param");
+
+  size_t counts_size = n * sizeof(CardCountCacheEntry);
+  size_t epochs_size = n * sizeof(CardEpochCacheEntry);
+
+  *counts = (CardCountCacheEntry*) os::malloc(counts_size);
+  if (*counts == NULL) {
+    // allocation was unsuccessful
+    return false;
+  }
+
+  *epochs = (CardEpochCacheEntry*) os::malloc(epochs_size);
+  if (*epochs == NULL) {
+    // allocation was unsuccessful - free counts array
+    assert(*counts != NULL, "must be");
+    os::free(*counts);
+    *counts = NULL;
+    return false;
+  }
 
-    // Expand the card count and card epoch tables
-    if (new_size > (int)_n_card_counts) {
-      // We can just free and allocate a new array as we're
-      // not interested in preserving the contents
-      assert(_card_counts != NULL, "Logic!");
-      assert(_card_epochs != NULL, "Logic!");
-      FREE_C_HEAP_ARRAY(CardCountCacheEntry, _card_counts);
-      FREE_C_HEAP_ARRAY(CardEpochCacheEntry, _card_epochs);
-      _n_card_counts = new_size;
-      _card_counts = NEW_C_HEAP_ARRAY(CardCountCacheEntry, _n_card_counts);
-      _card_epochs = NEW_C_HEAP_ARRAY(CardEpochCacheEntry, _n_card_counts);
-      _cache_size_index = new_idx;
+  // We successfully allocated both counts and epochs
+  return true;
+}
+
+// Returns true if the card counts/epochs cache was
+// successfully expanded; false otherwise.
+bool ConcurrentG1Refine::expand_card_count_cache(int cache_size_idx) {
+  // Can we expand the card count and epoch tables?
+  if (_n_card_counts < _max_n_card_counts) {
+    assert(cache_size_idx >= 0 && cache_size_idx  < MAX_CC_CACHE_INDEX, "oob");
+
+    size_t cache_size = _cc_cache_sizes[cache_size_idx];
+    // Make sure we don't go bigger than we will ever need
+    cache_size = MIN2(cache_size, _max_n_card_counts);
+
+    // Should we expand the card count and card epoch tables?
+    if (cache_size > _n_card_counts) {
+      // We have been asked to allocate new, larger, arrays for
+      // the card counts and the epochs. Attempt the allocation
+      // of both before we free the existing arrays in case
+      // the allocation is unsuccessful...
+      CardCountCacheEntry* counts = NULL;
+      CardEpochCacheEntry* epochs = NULL;
+
+      if (allocate_card_count_cache(cache_size, &counts, &epochs)) {
+        // Allocation was successful.
+        // We can just free the old arrays; we're
+        // not interested in preserving the contents
+        if (_card_counts != NULL) os::free(_card_counts);
+        if (_card_epochs != NULL) os::free(_card_epochs);
+
+        // Cache the size of the arrays and the index that got us there.
+        _n_card_counts = cache_size;
+        _cache_size_index = cache_size_idx;
+
+        _card_counts = counts;
+        _card_epochs = epochs;
+
+        // We successfully allocated/expanded the caches.
+        return true;
+      }
     }
   }
+
+  // We did not successfully expand the caches.
+  return false;
 }
 
 void ConcurrentG1Refine::clear_and_record_card_counts() {
@@ -415,10 +507,16 @@
 #endif
 
   if (_expand_card_counts) {
-    expand_card_count_cache();
+    int new_idx = _cache_size_index + 1;
+
+    if (expand_card_count_cache(new_idx)) {
+      // Allocation was successful and  _n_card_counts has
+      // been updated to the new size. We only need to clear
+      // the epochs so we don't read a bogus epoch value
+      // when inserting a card into the hot card cache.
+      Copy::fill_to_bytes(&_card_epochs[0], _n_card_counts * sizeof(CardEpochCacheEntry));
+    }
     _expand_card_counts = false;
-    // Only need to clear the epochs.
-    Copy::fill_to_bytes(&_card_epochs[0], _n_card_counts * sizeof(CardEpochCacheEntry));
   }
 
   int this_epoch = (int) _n_periods;
--- a/src/share/vm/gc_implementation/g1/concurrentG1Refine.hpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/gc_implementation/g1/concurrentG1Refine.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -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
@@ -94,7 +94,7 @@
   } CardEpochCacheEntry;
 
   julong make_epoch_entry(unsigned int card_num, unsigned int epoch) {
-    assert(0 <= card_num && card_num < _max_n_card_counts, "Bounds");
+    assert(0 <= card_num && card_num < _max_cards, "Bounds");
     assert(0 <= epoch && epoch <= _n_periods, "must be");
 
     return ((julong) card_num << card_num_shift) | epoch;
@@ -117,15 +117,24 @@
   CardEpochCacheEntry* _card_epochs;
 
   // The current number of buckets in the card count cache
-  unsigned _n_card_counts;
+  size_t _n_card_counts;
+
+  // The number of cards for the entire reserved heap
+  size_t _max_cards;
 
-  // The max number of buckets required for the number of
-  // cards for the entire reserved heap
-  unsigned _max_n_card_counts;
+  // The max number of buckets for the card counts and epochs caches.
+  // This is the maximum that the counts and epochs will grow to.
+  // It is specified as a fraction or percentage of _max_cards using
+  // G1MaxHotCardCountSizePercent.
+  size_t _max_n_card_counts;
 
   // Possible sizes of the cache: odd primes that roughly double in size.
   // (See jvmtiTagMap.cpp).
-  static int _cc_cache_sizes[];
+  enum {
+    MAX_CC_CACHE_INDEX = 15    // maximum index into the cache size array.
+  };
+
+  static size_t _cc_cache_sizes[MAX_CC_CACHE_INDEX];
 
   // The index in _cc_cache_sizes corresponding to the size of
   // _card_counts.
@@ -147,11 +156,22 @@
   CardTableModRefBS* _ct_bs;
   G1CollectedHeap*   _g1h;
 
-  // Expands the array that holds the card counts to the next size up
-  void expand_card_count_cache();
+  // Helper routine for expand_card_count_cache().
+  // The arrays used to hold the card counts and the epochs must have
+  // a 1:1 correspondence. Hence they are allocated and freed together.
+  // Returns true if the allocations of both the counts and epochs
+  // were successful; false otherwise.
+  bool allocate_card_count_cache(size_t n,
+                                 CardCountCacheEntry** counts,
+                                 CardEpochCacheEntry** epochs);
+
+  // Expands the arrays that hold the card counts and epochs
+  // to the cache size at index. Returns true if the expansion/
+  // allocation was successful; false otherwise.
+  bool expand_card_count_cache(int index);
 
   // hash a given key (index of card_ptr) with the specified size
-  static unsigned int hash(size_t key, int size) {
+  static unsigned int hash(size_t key, size_t size) {
     return (unsigned int) key % size;
   }
 
--- a/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -1204,7 +1204,6 @@
   g1p->record_concurrent_mark_remark_end();
 }
 
-
 #define CARD_BM_TEST_MODE 0
 
 class CalcLiveObjectsClosure: public HeapRegionClosure {
@@ -1726,6 +1725,11 @@
   }
   _total_counting_time += this_final_counting_time;
 
+  if (G1PrintRegionLivenessInfo) {
+    G1PrintRegionLivenessInfoClosure cl(gclog_or_tty, "Post-Marking");
+    _g1h->heap_region_iterate(&cl);
+  }
+
   // Install newly created mark bitMap as "prev".
   swapMarkBitMaps();
 
@@ -3199,8 +3203,12 @@
                CMTask* task)
     : _g1h(g1h), _cm(cm), _task(task)
   {
-    _ref_processor = g1h->ref_processor();
-    assert(_ref_processor != NULL, "should not be NULL");
+    assert(_ref_processor == NULL, "should be initialized to NULL");
+
+    if (G1UseConcMarkReferenceProcessing) {
+      _ref_processor = g1h->ref_processor();
+      assert(_ref_processor != NULL, "should not be NULL");
+    }
   }
 };
 
@@ -4423,3 +4431,175 @@
 
   _marking_step_diffs_ms.add(0.5);
 }
+
+// These are formatting macros that are used below to ensure
+// consistent formatting. The *_H_* versions are used to format the
+// header for a particular value and they should be kept consistent
+// with the corresponding macro. Also note that most of the macros add
+// the necessary white space (as a prefix) which makes them a bit
+// easier to compose.
+
+// All the output lines are prefixed with this string to be able to
+// identify them easily in a large log file.
+#define G1PPRL_LINE_PREFIX            "###"
+
+#define G1PPRL_ADDR_BASE_FORMAT    " "PTR_FORMAT"-"PTR_FORMAT
+#ifdef _LP64
+#define G1PPRL_ADDR_BASE_H_FORMAT  " %37s"
+#else // _LP64
+#define G1PPRL_ADDR_BASE_H_FORMAT  " %21s"
+#endif // _LP64
+
+// For per-region info
+#define G1PPRL_TYPE_FORMAT            "   %-4s"
+#define G1PPRL_TYPE_H_FORMAT          "   %4s"
+#define G1PPRL_BYTE_FORMAT            "  "SIZE_FORMAT_W(9)
+#define G1PPRL_BYTE_H_FORMAT          "  %9s"
+#define G1PPRL_DOUBLE_FORMAT          "  %14.1f"
+#define G1PPRL_DOUBLE_H_FORMAT        "  %14s"
+
+// For summary info
+#define G1PPRL_SUM_ADDR_FORMAT(tag)    "  "tag":"G1PPRL_ADDR_BASE_FORMAT
+#define G1PPRL_SUM_BYTE_FORMAT(tag)    "  "tag": "SIZE_FORMAT
+#define G1PPRL_SUM_MB_FORMAT(tag)      "  "tag": %1.2f MB"
+#define G1PPRL_SUM_MB_PERC_FORMAT(tag) G1PPRL_SUM_MB_FORMAT(tag)" / %1.2f %%"
+
+G1PrintRegionLivenessInfoClosure::
+G1PrintRegionLivenessInfoClosure(outputStream* out, const char* phase_name)
+  : _out(out),
+    _total_used_bytes(0), _total_capacity_bytes(0),
+    _total_prev_live_bytes(0), _total_next_live_bytes(0),
+    _hum_used_bytes(0), _hum_capacity_bytes(0),
+    _hum_prev_live_bytes(0), _hum_next_live_bytes(0) {
+  G1CollectedHeap* g1h = G1CollectedHeap::heap();
+  MemRegion g1_committed = g1h->g1_committed();
+  MemRegion g1_reserved = g1h->g1_reserved();
+  double now = os::elapsedTime();
+
+  // Print the header of the output.
+  _out->cr();
+  _out->print_cr(G1PPRL_LINE_PREFIX" PHASE %s @ %1.3f", phase_name, now);
+  _out->print_cr(G1PPRL_LINE_PREFIX" HEAP"
+                 G1PPRL_SUM_ADDR_FORMAT("committed")
+                 G1PPRL_SUM_ADDR_FORMAT("reserved")
+                 G1PPRL_SUM_BYTE_FORMAT("region-size"),
+                 g1_committed.start(), g1_committed.end(),
+                 g1_reserved.start(), g1_reserved.end(),
+                 HeapRegion::GrainBytes);
+  _out->print_cr(G1PPRL_LINE_PREFIX);
+  _out->print_cr(G1PPRL_LINE_PREFIX
+                 G1PPRL_TYPE_H_FORMAT
+                 G1PPRL_ADDR_BASE_H_FORMAT
+                 G1PPRL_BYTE_H_FORMAT
+                 G1PPRL_BYTE_H_FORMAT
+                 G1PPRL_BYTE_H_FORMAT
+                 G1PPRL_DOUBLE_H_FORMAT,
+                 "type", "address-range",
+                 "used", "prev-live", "next-live", "gc-eff");
+}
+
+// It takes as a parameter a reference to one of the _hum_* fields, it
+// deduces the corresponding value for a region in a humongous region
+// series (either the region size, or what's left if the _hum_* field
+// is < the region size), and updates the _hum_* field accordingly.
+size_t G1PrintRegionLivenessInfoClosure::get_hum_bytes(size_t* hum_bytes) {
+  size_t bytes = 0;
+  // The > 0 check is to deal with the prev and next live bytes which
+  // could be 0.
+  if (*hum_bytes > 0) {
+    bytes = MIN2((size_t) HeapRegion::GrainBytes, *hum_bytes);
+    *hum_bytes -= bytes;
+  }
+  return bytes;
+}
+
+// It deduces the values for a region in a humongous region series
+// from the _hum_* fields and updates those accordingly. It assumes
+// that that _hum_* fields have already been set up from the "starts
+// humongous" region and we visit the regions in address order.
+void G1PrintRegionLivenessInfoClosure::get_hum_bytes(size_t* used_bytes,
+                                                     size_t* capacity_bytes,
+                                                     size_t* prev_live_bytes,
+                                                     size_t* next_live_bytes) {
+  assert(_hum_used_bytes > 0 && _hum_capacity_bytes > 0, "pre-condition");
+  *used_bytes      = get_hum_bytes(&_hum_used_bytes);
+  *capacity_bytes  = get_hum_bytes(&_hum_capacity_bytes);
+  *prev_live_bytes = get_hum_bytes(&_hum_prev_live_bytes);
+  *next_live_bytes = get_hum_bytes(&_hum_next_live_bytes);
+}
+
+bool G1PrintRegionLivenessInfoClosure::doHeapRegion(HeapRegion* r) {
+  const char* type = "";
+  HeapWord* bottom       = r->bottom();
+  HeapWord* end          = r->end();
+  size_t capacity_bytes  = r->capacity();
+  size_t used_bytes      = r->used();
+  size_t prev_live_bytes = r->live_bytes();
+  size_t next_live_bytes = r->next_live_bytes();
+  double gc_eff          = r->gc_efficiency();
+  if (r->used() == 0) {
+    type = "FREE";
+  } else if (r->is_survivor()) {
+    type = "SURV";
+  } else if (r->is_young()) {
+    type = "EDEN";
+  } else if (r->startsHumongous()) {
+    type = "HUMS";
+
+    assert(_hum_used_bytes == 0 && _hum_capacity_bytes == 0 &&
+           _hum_prev_live_bytes == 0 && _hum_next_live_bytes == 0,
+           "they should have been zeroed after the last time we used them");
+    // Set up the _hum_* fields.
+    _hum_capacity_bytes  = capacity_bytes;
+    _hum_used_bytes      = used_bytes;
+    _hum_prev_live_bytes = prev_live_bytes;
+    _hum_next_live_bytes = next_live_bytes;
+    get_hum_bytes(&used_bytes, &capacity_bytes,
+                  &prev_live_bytes, &next_live_bytes);
+    end = bottom + HeapRegion::GrainWords;
+  } else if (r->continuesHumongous()) {
+    type = "HUMC";
+    get_hum_bytes(&used_bytes, &capacity_bytes,
+                  &prev_live_bytes, &next_live_bytes);
+    assert(end == bottom + HeapRegion::GrainWords, "invariant");
+  } else {
+    type = "OLD";
+  }
+
+  _total_used_bytes      += used_bytes;
+  _total_capacity_bytes  += capacity_bytes;
+  _total_prev_live_bytes += prev_live_bytes;
+  _total_next_live_bytes += next_live_bytes;
+
+  // Print a line for this particular region.
+  _out->print_cr(G1PPRL_LINE_PREFIX
+                 G1PPRL_TYPE_FORMAT
+                 G1PPRL_ADDR_BASE_FORMAT
+                 G1PPRL_BYTE_FORMAT
+                 G1PPRL_BYTE_FORMAT
+                 G1PPRL_BYTE_FORMAT
+                 G1PPRL_DOUBLE_FORMAT,
+                 type, bottom, end,
+                 used_bytes, prev_live_bytes, next_live_bytes, gc_eff);
+
+  return false;
+}
+
+G1PrintRegionLivenessInfoClosure::~G1PrintRegionLivenessInfoClosure() {
+  // Print the footer of the output.
+  _out->print_cr(G1PPRL_LINE_PREFIX);
+  _out->print_cr(G1PPRL_LINE_PREFIX
+                 " SUMMARY"
+                 G1PPRL_SUM_MB_FORMAT("capacity")
+                 G1PPRL_SUM_MB_PERC_FORMAT("used")
+                 G1PPRL_SUM_MB_PERC_FORMAT("prev-live")
+                 G1PPRL_SUM_MB_PERC_FORMAT("next-live"),
+                 bytes_to_mb(_total_capacity_bytes),
+                 bytes_to_mb(_total_used_bytes),
+                 perc(_total_used_bytes, _total_capacity_bytes),
+                 bytes_to_mb(_total_prev_live_bytes),
+                 perc(_total_prev_live_bytes, _total_capacity_bytes),
+                 bytes_to_mb(_total_next_live_bytes),
+                 perc(_total_next_live_bytes, _total_capacity_bytes));
+  _out->cr();
+}
--- a/src/share/vm/gc_implementation/g1/concurrentMark.hpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/gc_implementation/g1/concurrentMark.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -1149,4 +1149,54 @@
 #endif // _MARKING_STATS_
 };
 
+// Class that's used to to print out per-region liveness
+// information. It's currently used at the end of marking and also
+// after we sort the old regions at the end of the cleanup operation.
+class G1PrintRegionLivenessInfoClosure: public HeapRegionClosure {
+private:
+  outputStream* _out;
+
+  // Accumulators for these values.
+  size_t _total_used_bytes;
+  size_t _total_capacity_bytes;
+  size_t _total_prev_live_bytes;
+  size_t _total_next_live_bytes;
+
+  // These are set up when we come across a "stars humongous" region
+  // (as this is where most of this information is stored, not in the
+  // subsequent "continues humongous" regions). After that, for every
+  // region in a given humongous region series we deduce the right
+  // values for it by simply subtracting the appropriate amount from
+  // these fields. All these values should reach 0 after we've visited
+  // the last region in the series.
+  size_t _hum_used_bytes;
+  size_t _hum_capacity_bytes;
+  size_t _hum_prev_live_bytes;
+  size_t _hum_next_live_bytes;
+
+  static double perc(size_t val, size_t total) {
+    if (total == 0) {
+      return 0.0;
+    } else {
+      return 100.0 * ((double) val / (double) total);
+    }
+  }
+
+  static double bytes_to_mb(size_t val) {
+    return (double) val / (double) M;
+  }
+
+  // See the .cpp file.
+  size_t get_hum_bytes(size_t* hum_bytes);
+  void get_hum_bytes(size_t* used_bytes, size_t* capacity_bytes,
+                     size_t* prev_live_bytes, size_t* next_live_bytes);
+
+public:
+  // The header and footer are printed in the constructor and
+  // destructor respectively.
+  G1PrintRegionLivenessInfoClosure(outputStream* out, const char* phase_name);
+  virtual bool doHeapRegion(HeapRegion* r);
+  ~G1PrintRegionLivenessInfoClosure();
+};
+
 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_CONCURRENTMARK_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/gc_implementation/g1/g1AllocRegion.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc_implementation/g1/g1AllocRegion.inline.hpp"
+#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
+
+G1CollectedHeap* G1AllocRegion::_g1h = NULL;
+HeapRegion* G1AllocRegion::_dummy_region = NULL;
+
+void G1AllocRegion::setup(G1CollectedHeap* g1h, HeapRegion* dummy_region) {
+  assert(_dummy_region == NULL, "should be set once");
+  assert(dummy_region != NULL, "pre-condition");
+  assert(dummy_region->free() == 0, "pre-condition");
+
+  // Make sure that any allocation attempt on this region will fail
+  // and will not trigger any asserts.
+  assert(allocate(dummy_region, 1, false) == NULL, "should fail");
+  assert(par_allocate(dummy_region, 1, false) == NULL, "should fail");
+  assert(allocate(dummy_region, 1, true) == NULL, "should fail");
+  assert(par_allocate(dummy_region, 1, true) == NULL, "should fail");
+
+  _g1h = g1h;
+  _dummy_region = dummy_region;
+}
+
+void G1AllocRegion::fill_up_remaining_space(HeapRegion* alloc_region,
+                                            bool bot_updates) {
+  assert(alloc_region != NULL && alloc_region != _dummy_region,
+         "pre-condition");
+
+  // Other threads might still be trying to allocate using a CAS out
+  // of the region we are trying to retire, as they can do so without
+  // holding the lock. So, we first have to make sure that noone else
+  // can allocate out of it by doing a maximal allocation. Even if our
+  // CAS attempt fails a few times, we'll succeed sooner or later
+  // given that failed CAS attempts mean that the region is getting
+  // closed to being full.
+  size_t free_word_size = alloc_region->free() / HeapWordSize;
+
+  // This is the minimum free chunk we can turn into a dummy
+  // object. If the free space falls below this, then noone can
+  // allocate in this region anyway (all allocation requests will be
+  // of a size larger than this) so we won't have to perform the dummy
+  // allocation.
+  size_t min_word_size_to_fill = CollectedHeap::min_fill_size();
+
+  while (free_word_size >= min_word_size_to_fill) {
+    HeapWord* dummy = par_allocate(alloc_region, free_word_size, bot_updates);
+    if (dummy != NULL) {
+      // If the allocation was successful we should fill in the space.
+      CollectedHeap::fill_with_object(dummy, free_word_size);
+      alloc_region->set_pre_dummy_top(dummy);
+      break;
+    }
+
+    free_word_size = alloc_region->free() / HeapWordSize;
+    // It's also possible that someone else beats us to the
+    // allocation and they fill up the region. In that case, we can
+    // just get out of the loop.
+  }
+  assert(alloc_region->free() / HeapWordSize < min_word_size_to_fill,
+         "post-condition");
+}
+
+void G1AllocRegion::retire(bool fill_up) {
+  assert(_alloc_region != NULL, ar_ext_msg(this, "not initialized properly"));
+
+  trace("retiring");
+  HeapRegion* alloc_region = _alloc_region;
+  if (alloc_region != _dummy_region) {
+    // We never have to check whether the active region is empty or not,
+    // and potentially free it if it is, given that it's guaranteed that
+    // it will never be empty.
+    assert(!alloc_region->is_empty(),
+           ar_ext_msg(this, "the alloc region should never be empty"));
+
+    if (fill_up) {
+      fill_up_remaining_space(alloc_region, _bot_updates);
+    }
+
+    assert(alloc_region->used() >= _used_bytes_before,
+           ar_ext_msg(this, "invariant"));
+    size_t allocated_bytes = alloc_region->used() - _used_bytes_before;
+    retire_region(alloc_region, allocated_bytes);
+    _used_bytes_before = 0;
+    _alloc_region = _dummy_region;
+  }
+  trace("retired");
+}
+
+HeapWord* G1AllocRegion::new_alloc_region_and_allocate(size_t word_size,
+                                                       bool force) {
+  assert(_alloc_region == _dummy_region, ar_ext_msg(this, "pre-condition"));
+  assert(_used_bytes_before == 0, ar_ext_msg(this, "pre-condition"));
+
+  trace("attempting region allocation");
+  HeapRegion* new_alloc_region = allocate_new_region(word_size, force);
+  if (new_alloc_region != NULL) {
+    new_alloc_region->reset_pre_dummy_top();
+    // Need to do this before the allocation
+    _used_bytes_before = new_alloc_region->used();
+    HeapWord* result = allocate(new_alloc_region, word_size, _bot_updates);
+    assert(result != NULL, ar_ext_msg(this, "the allocation should succeeded"));
+
+    OrderAccess::storestore();
+    // Note that we first perform the allocation and then we store the
+    // region in _alloc_region. This is the reason why an active region
+    // can never be empty.
+    _alloc_region = new_alloc_region;
+    trace("region allocation successful");
+    return result;
+  } else {
+    trace("region allocation failed");
+    return NULL;
+  }
+  ShouldNotReachHere();
+}
+
+void G1AllocRegion::fill_in_ext_msg(ar_ext_msg* msg, const char* message) {
+  msg->append("[%s] %s b: %s r: "PTR_FORMAT" u: "SIZE_FORMAT,
+              _name, message, BOOL_TO_STR(_bot_updates),
+              _alloc_region, _used_bytes_before);
+}
+
+void G1AllocRegion::init() {
+  trace("initializing");
+  assert(_alloc_region == NULL && _used_bytes_before == 0,
+         ar_ext_msg(this, "pre-condition"));
+  assert(_dummy_region != NULL, "should have been set");
+  _alloc_region = _dummy_region;
+  trace("initialized");
+}
+
+HeapRegion* G1AllocRegion::release() {
+  trace("releasing");
+  HeapRegion* alloc_region = _alloc_region;
+  retire(false /* fill_up */);
+  assert(_alloc_region == _dummy_region, "post-condition of retire()");
+  _alloc_region = NULL;
+  trace("released");
+  return (alloc_region == _dummy_region) ? NULL : alloc_region;
+}
+
+#if G1_ALLOC_REGION_TRACING
+void G1AllocRegion::trace(const char* str, size_t word_size, HeapWord* result) {
+  // All the calls to trace that set either just the size or the size
+  // and the result are considered part of level 2 tracing and are
+  // skipped during level 1 tracing.
+  if ((word_size == 0 && result == NULL) || (G1_ALLOC_REGION_TRACING > 1)) {
+    const size_t buffer_length = 128;
+    char hr_buffer[buffer_length];
+    char rest_buffer[buffer_length];
+
+    HeapRegion* alloc_region = _alloc_region;
+    if (alloc_region == NULL) {
+      jio_snprintf(hr_buffer, buffer_length, "NULL");
+    } else if (alloc_region == _dummy_region) {
+      jio_snprintf(hr_buffer, buffer_length, "DUMMY");
+    } else {
+      jio_snprintf(hr_buffer, buffer_length,
+                   HR_FORMAT, HR_FORMAT_PARAMS(alloc_region));
+    }
+
+    if (G1_ALLOC_REGION_TRACING > 1) {
+      if (result != NULL) {
+        jio_snprintf(rest_buffer, buffer_length, SIZE_FORMAT" "PTR_FORMAT,
+                     word_size, result);
+      } else if (word_size != 0) {
+        jio_snprintf(rest_buffer, buffer_length, SIZE_FORMAT, word_size);
+      } else {
+        jio_snprintf(rest_buffer, buffer_length, "");
+      }
+    } else {
+      jio_snprintf(rest_buffer, buffer_length, "");
+    }
+
+    tty->print_cr("[%s] %s : %s %s", _name, hr_buffer, str, rest_buffer);
+  }
+}
+#endif // G1_ALLOC_REGION_TRACING
+
+G1AllocRegion::G1AllocRegion(const char* name,
+                             bool bot_updates)
+  : _name(name), _bot_updates(bot_updates),
+    _alloc_region(NULL), _used_bytes_before(0) { }
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/gc_implementation/g1/g1AllocRegion.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1ALLOCREGION_HPP
+#define SHARE_VM_GC_IMPLEMENTATION_G1_G1ALLOCREGION_HPP
+
+#include "gc_implementation/g1/heapRegion.hpp"
+
+class G1CollectedHeap;
+
+// 0 -> no tracing, 1 -> basic tracing, 2 -> basic + allocation tracing
+#define G1_ALLOC_REGION_TRACING 0
+
+class ar_ext_msg;
+
+// A class that holds a region that is active in satisfying allocation
+// requests, potentially issued in parallel. When the active region is
+// full it will be retired it replaced with a new one. The
+// implementation assumes that fast-path allocations will be lock-free
+// and a lock will need to be taken when the active region needs to be
+// replaced.
+
+class G1AllocRegion VALUE_OBJ_CLASS_SPEC {
+  friend class ar_ext_msg;
+
+private:
+  // The active allocating region we are currently allocating out
+  // of. The invariant is that if this object is initialized (i.e.,
+  // init() has been called and release() has not) then _alloc_region
+  // is either an active allocating region or the dummy region (i.e.,
+  // it can never be NULL) and this object can be used to satisfy
+  // allocation requests. If this object is not initialized
+  // (i.e. init() has not been called or release() has been called)
+  // then _alloc_region is NULL and this object should not be used to
+  // satisfy allocation requests (it was done this way to force the
+  // correct use of init() and release()).
+  HeapRegion* _alloc_region;
+
+  // When we set up a new active region we save its used bytes in this
+  // field so that, when we retire it, we can calculate how much space
+  // we allocated in it.
+  size_t _used_bytes_before;
+
+  // Specifies whether the allocate calls will do BOT updates or not.
+  bool _bot_updates;
+
+  // Useful for debugging and tracing.
+  const char* _name;
+
+  // A dummy region (i.e., it's been allocated specially for this
+  // purpose and it is not part of the heap) that is full (i.e., top()
+  // == end()). When we don't have a valid active region we make
+  // _alloc_region point to this. This allows us to skip checking
+  // whether the _alloc_region is NULL or not.
+  static HeapRegion* _dummy_region;
+
+  // Some of the methods below take a bot_updates parameter. Its value
+  // should be the same as the _bot_updates field. The idea is that
+  // the parameter will be a constant for a particular alloc region
+  // and, given that these methods will be hopefully inlined, the
+  // compiler should compile out the test.
+
+  // Perform a non-MT-safe allocation out of the given region.
+  static inline HeapWord* allocate(HeapRegion* alloc_region,
+                                   size_t word_size,
+                                   bool bot_updates);
+
+  // Perform a MT-safe allocation out of the given region.
+  static inline HeapWord* par_allocate(HeapRegion* alloc_region,
+                                       size_t word_size,
+                                       bool bot_updates);
+
+  // Ensure that the region passed as a parameter has been filled up
+  // so that noone else can allocate out of it any more.
+  static void fill_up_remaining_space(HeapRegion* alloc_region,
+                                      bool bot_updates);
+
+  // Retire the active allocating region. If fill_up is true then make
+  // sure that the region is full before we retire it so that noone
+  // else can allocate out of it.
+  void retire(bool fill_up);
+
+  // Allocate a new active region and use it to perform a word_size
+  // allocation. The force parameter will be passed on to
+  // G1CollectedHeap::allocate_new_alloc_region() and tells it to try
+  // to allocate a new region even if the max has been reached.
+  HeapWord* new_alloc_region_and_allocate(size_t word_size, bool force);
+
+  void fill_in_ext_msg(ar_ext_msg* msg, const char* message);
+
+protected:
+  // For convenience as subclasses use it.
+  static G1CollectedHeap* _g1h;
+
+  virtual HeapRegion* allocate_new_region(size_t word_size, bool force) = 0;
+  virtual void retire_region(HeapRegion* alloc_region,
+                             size_t allocated_bytes) = 0;
+
+  G1AllocRegion(const char* name, bool bot_updates);
+
+public:
+  static void setup(G1CollectedHeap* g1h, HeapRegion* dummy_region);
+
+  HeapRegion* get() const {
+    // Make sure that the dummy region does not escape this class.
+    return (_alloc_region == _dummy_region) ? NULL : _alloc_region;
+  }
+
+  // The following two are the building blocks for the allocation method.
+
+  // First-level allocation: Should be called without holding a
+  // lock. It will try to allocate lock-free out of the active region,
+  // or return NULL if it was unable to.
+  inline HeapWord* attempt_allocation(size_t word_size, bool bot_updates);
+
+  // Second-level allocation: Should be called while holding a
+  // lock. It will try to first allocate lock-free out of the active
+  // region or, if it's unable to, it will try to replace the active
+  // alloc region with a new one. We require that the caller takes the
+  // appropriate lock before calling this so that it is easier to make
+  // it conform to its locking protocol.
+  inline HeapWord* attempt_allocation_locked(size_t word_size,
+                                             bool bot_updates);
+
+  // Should be called to allocate a new region even if the max of this
+  // type of regions has been reached. Should only be called if other
+  // allocation attempts have failed and we are not holding a valid
+  // active region.
+  inline HeapWord* attempt_allocation_force(size_t word_size,
+                                            bool bot_updates);
+
+  // Should be called before we start using this object.
+  void init();
+
+  // Should be called when we want to release the active region which
+  // is returned after it's been retired.
+  HeapRegion* release();
+
+#if G1_ALLOC_REGION_TRACING
+  void trace(const char* str, size_t word_size = 0, HeapWord* result = NULL);
+#else // G1_ALLOC_REGION_TRACING
+  void trace(const char* str, size_t word_size = 0, HeapWord* result = NULL) { }
+#endif // G1_ALLOC_REGION_TRACING
+};
+
+class ar_ext_msg : public err_msg {
+public:
+  ar_ext_msg(G1AllocRegion* alloc_region, const char *message) : err_msg("") {
+    alloc_region->fill_in_ext_msg(this, message);
+  }
+};
+
+#endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1ALLOCREGION_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/gc_implementation/g1/g1AllocRegion.inline.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1ALLOCREGION_INLINE_HPP
+#define SHARE_VM_GC_IMPLEMENTATION_G1_G1ALLOCREGION_INLINE_HPP
+
+#include "gc_implementation/g1/g1AllocRegion.hpp"
+
+inline HeapWord* G1AllocRegion::allocate(HeapRegion* alloc_region,
+                                         size_t word_size,
+                                         bool bot_updates) {
+  assert(alloc_region != NULL, err_msg("pre-condition"));
+
+  if (!bot_updates) {
+    return alloc_region->allocate_no_bot_updates(word_size);
+  } else {
+    return alloc_region->allocate(word_size);
+  }
+}
+
+inline HeapWord* G1AllocRegion::par_allocate(HeapRegion* alloc_region,
+                                             size_t word_size,
+                                             bool bot_updates) {
+  assert(alloc_region != NULL, err_msg("pre-condition"));
+  assert(!alloc_region->is_empty(), err_msg("pre-condition"));
+
+  if (!bot_updates) {
+    return alloc_region->par_allocate_no_bot_updates(word_size);
+  } else {
+    return alloc_region->par_allocate(word_size);
+  }
+}
+
+inline HeapWord* G1AllocRegion::attempt_allocation(size_t word_size,
+                                                   bool bot_updates) {
+  assert(bot_updates == _bot_updates, ar_ext_msg(this, "pre-condition"));
+
+  HeapRegion* alloc_region = _alloc_region;
+  assert(alloc_region != NULL, ar_ext_msg(this, "not initialized properly"));
+
+  HeapWord* result = par_allocate(alloc_region, word_size, bot_updates);
+  if (result != NULL) {
+    trace("alloc", word_size, result);
+    return result;
+  }
+  trace("alloc failed", word_size);
+  return NULL;
+}
+
+inline HeapWord* G1AllocRegion::attempt_allocation_locked(size_t word_size,
+                                                          bool bot_updates) {
+  // First we have to tedo the allocation, assuming we're holding the
+  // appropriate lock, in case another thread changed the region while
+  // we were waiting to get the lock.
+  HeapWord* result = attempt_allocation(word_size, bot_updates);
+  if (result != NULL) {
+    return result;
+  }
+
+  retire(true /* fill_up */);
+  result = new_alloc_region_and_allocate(word_size, false /* force */);
+  if (result != NULL) {
+    trace("alloc locked (second attempt)", word_size, result);
+    return result;
+  }
+  trace("alloc locked failed", word_size);
+  return NULL;
+}
+
+inline HeapWord* G1AllocRegion::attempt_allocation_force(size_t word_size,
+                                                         bool bot_updates) {
+  assert(bot_updates == _bot_updates, ar_ext_msg(this, "pre-condition"));
+  assert(_alloc_region != NULL, ar_ext_msg(this, "not initialized properly"));
+
+  trace("forcing alloc");
+  HeapWord* result = new_alloc_region_and_allocate(word_size, true /* force */);
+  if (result != NULL) {
+    trace("alloc forced", word_size, result);
+    return result;
+  }
+  trace("alloc forced failed", word_size);
+  return NULL;
+}
+
+#endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1ALLOCREGION_INLINE_HPP
--- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Thu Apr 14 11:02:05 2011 -0400
@@ -28,6 +28,7 @@
 #include "gc_implementation/g1/concurrentG1Refine.hpp"
 #include "gc_implementation/g1/concurrentG1RefineThread.hpp"
 #include "gc_implementation/g1/concurrentMarkThread.inline.hpp"
+#include "gc_implementation/g1/g1AllocRegion.inline.hpp"
 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
 #include "gc_implementation/g1/g1CollectorPolicy.hpp"
 #include "gc_implementation/g1/g1MarkSweep.hpp"
@@ -517,8 +518,7 @@
   return NULL;
 }
 
-HeapRegion* G1CollectedHeap::new_region_work(size_t word_size,
-                                             bool do_expand) {
+HeapRegion* G1CollectedHeap::new_region(size_t word_size, bool do_expand) {
   assert(!isHumongous(word_size) ||
                                   word_size <= (size_t) HeapRegion::GrainWords,
          "the only time we use this to allocate a humongous region is "
@@ -566,7 +566,7 @@
                                                  size_t word_size) {
   HeapRegion* alloc_region = NULL;
   if (_gc_alloc_region_counts[purpose] < g1_policy()->max_regions(purpose)) {
-    alloc_region = new_region_work(word_size, true /* do_expand */);
+    alloc_region = new_region(word_size, true /* do_expand */);
     if (purpose == GCAllocForSurvived && alloc_region != NULL) {
       alloc_region->set_survivor();
     }
@@ -587,7 +587,7 @@
     // Only one region to allocate, no need to go through the slower
     // path. The caller will attempt the expasion if this fails, so
     // let's not try to expand here too.
-    HeapRegion* hr = new_region_work(word_size, false /* do_expand */);
+    HeapRegion* hr = new_region(word_size, false /* do_expand */);
     if (hr != NULL) {
       first = hr->hrs_index();
     } else {
@@ -788,407 +788,12 @@
   return result;
 }
 
-void
-G1CollectedHeap::retire_cur_alloc_region(HeapRegion* cur_alloc_region) {
-  // Other threads might still be trying to allocate using CASes out
-  // of the region we are retiring, as they can do so without holding
-  // the Heap_lock. So we first have to make sure that noone else can
-  // allocate in it by doing a maximal allocation. Even if our CAS
-  // attempt fails a few times, we'll succeed sooner or later given
-  // that a failed CAS attempt mean that the region is getting closed
-  // to being full (someone else succeeded in allocating into it).
-  size_t free_word_size = cur_alloc_region->free() / HeapWordSize;
-
-  // This is the minimum free chunk we can turn into a dummy
-  // object. If the free space falls below this, then noone can
-  // allocate in this region anyway (all allocation requests will be
-  // of a size larger than this) so we won't have to perform the dummy
-  // allocation.
-  size_t min_word_size_to_fill = CollectedHeap::min_fill_size();
-
-  while (free_word_size >= min_word_size_to_fill) {
-    HeapWord* dummy =
-      cur_alloc_region->par_allocate_no_bot_updates(free_word_size);
-    if (dummy != NULL) {
-      // If the allocation was successful we should fill in the space.
-      CollectedHeap::fill_with_object(dummy, free_word_size);
-      break;
-    }
-
-    free_word_size = cur_alloc_region->free() / HeapWordSize;
-    // It's also possible that someone else beats us to the
-    // allocation and they fill up the region. In that case, we can
-    // just get out of the loop
-  }
-  assert(cur_alloc_region->free() / HeapWordSize < min_word_size_to_fill,
-         "sanity");
-
-  retire_cur_alloc_region_common(cur_alloc_region);
-  assert(_cur_alloc_region == NULL, "post-condition");
-}
-
-// See the comment in the .hpp file about the locking protocol and
-// assumptions of this method (and other related ones).
-HeapWord*
-G1CollectedHeap::replace_cur_alloc_region_and_allocate(size_t word_size,
-                                                       bool at_safepoint,
-                                                       bool do_dirtying,
-                                                       bool can_expand) {
-  assert_heap_locked_or_at_safepoint(true /* should_be_vm_thread */);
-  assert(_cur_alloc_region == NULL,
-         "replace_cur_alloc_region_and_allocate() should only be called "
-         "after retiring the previous current alloc region");
-  assert(SafepointSynchronize::is_at_safepoint() == at_safepoint,
-         "at_safepoint and is_at_safepoint() should be a tautology");
-  assert(!can_expand || g1_policy()->can_expand_young_list(),
-         "we should not call this method with can_expand == true if "
-         "we are not allowed to expand the young gen");
-
-  if (can_expand || !g1_policy()->is_young_list_full()) {
-    HeapRegion* new_cur_alloc_region = new_alloc_region(word_size);
-    if (new_cur_alloc_region != NULL) {
-      assert(new_cur_alloc_region->is_empty(),
-             "the newly-allocated region should be empty, "
-             "as right now we only allocate new regions out of the free list");
-      g1_policy()->update_region_num(true /* next_is_young */);
-      set_region_short_lived_locked(new_cur_alloc_region);
-
-      assert(!new_cur_alloc_region->isHumongous(),
-             "Catch a regression of this bug.");
-
-      // We need to ensure that the stores to _cur_alloc_region and,
-      // subsequently, to top do not float above the setting of the
-      // young type.
-      OrderAccess::storestore();
-
-      // Now, perform the allocation out of the region we just
-      // allocated. Note that noone else can access that region at
-      // this point (as _cur_alloc_region has not been updated yet),
-      // so we can just go ahead and do the allocation without any
-      // atomics (and we expect this allocation attempt to
-      // suceeded). Given that other threads can attempt an allocation
-      // with a CAS and without needing the Heap_lock, if we assigned
-      // the new region to _cur_alloc_region before first allocating
-      // into it other threads might have filled up the new region
-      // before we got a chance to do the allocation ourselves. In
-      // that case, we would have needed to retire the region, grab a
-      // new one, and go through all this again. Allocating out of the
-      // new region before assigning it to _cur_alloc_region avoids
-      // all this.
-      HeapWord* result =
-                     new_cur_alloc_region->allocate_no_bot_updates(word_size);
-      assert(result != NULL, "we just allocate out of an empty region "
-             "so allocation should have been successful");
-      assert(is_in(result), "result should be in the heap");
-
-      // Now make sure that the store to _cur_alloc_region does not
-      // float above the store to top.
-      OrderAccess::storestore();
-      _cur_alloc_region = new_cur_alloc_region;
-
-      if (!at_safepoint) {
-        Heap_lock->unlock();
-      }
-
-      // do the dirtying, if necessary, after we release the Heap_lock
-      if (do_dirtying) {
-        dirty_young_block(result, word_size);
-      }
-      return result;
-    }
-  }
-
-  assert(_cur_alloc_region == NULL, "we failed to allocate a new current "
-         "alloc region, it should still be NULL");
-  assert_heap_locked_or_at_safepoint(true /* should_be_vm_thread */);
-  return NULL;
-}
-
-// See the comment in the .hpp file about the locking protocol and
-// assumptions of this method (and other related ones).
-HeapWord*
-G1CollectedHeap::attempt_allocation_slow(size_t word_size) {
-  assert_heap_locked_and_not_at_safepoint();
-  assert(!isHumongous(word_size), "attempt_allocation_slow() should not be "
-         "used for humongous allocations");
-
-  // We should only reach here when we were unable to allocate
-  // otherwise. So, we should have not active current alloc region.
-  assert(_cur_alloc_region == NULL, "current alloc region should be NULL");
-
-  // We will loop while succeeded is false, which means that we tried
-  // to do a collection, but the VM op did not succeed. So, when we
-  // exit the loop, either one of the allocation attempts was
-  // successful, or we succeeded in doing the VM op but which was
-  // unable to allocate after the collection.
-  for (int try_count = 1; /* we'll return or break */; try_count += 1) {
-    bool succeeded = true;
-
-    // Every time we go round the loop we should be holding the Heap_lock.
-    assert_heap_locked();
-
-    if (GC_locker::is_active_and_needs_gc()) {
-      // We are locked out of GC because of the GC locker. We can
-      // allocate a new region only if we can expand the young gen.
-
-      if (g1_policy()->can_expand_young_list()) {
-        // Yes, we are allowed to expand the young gen. Let's try to
-        // allocate a new current alloc region.
-        HeapWord* result =
-          replace_cur_alloc_region_and_allocate(word_size,
-                                                false, /* at_safepoint */
-                                                true,  /* do_dirtying */
-                                                true   /* can_expand */);
-        if (result != NULL) {
-          assert_heap_not_locked();
-          return result;
-        }
-      }
-      // We could not expand the young gen further (or we could but we
-      // failed to allocate a new region). We'll stall until the GC
-      // locker forces a GC.
-
-      // If this thread is not in a jni critical section, we stall
-      // the requestor until the critical section has cleared and
-      // GC allowed. When the critical section clears, a GC is
-      // initiated by the last thread exiting the critical section; so
-      // we retry the allocation sequence from the beginning of the loop,
-      // rather than causing more, now probably unnecessary, GC attempts.
-      JavaThread* jthr = JavaThread::current();
-      assert(jthr != NULL, "sanity");
-      if (jthr->in_critical()) {
-        if (CheckJNICalls) {
-          fatal("Possible deadlock due to allocating while"
-                " in jni critical section");
-        }
-        // We are returning NULL so the protocol is that we're still
-        // holding the Heap_lock.
-        assert_heap_locked();
-        return NULL;
-      }
-
-      Heap_lock->unlock();
-      GC_locker::stall_until_clear();
-
-      // No need to relock the Heap_lock. We'll fall off to the code
-      // below the else-statement which assumes that we are not
-      // holding the Heap_lock.
-    } else {
-      // We are not locked out. So, let's try to do a GC. The VM op
-      // will retry the allocation before it completes.
-
-      // Read the GC count while holding the Heap_lock
-      unsigned int gc_count_before = SharedHeap::heap()->total_collections();
-
-      Heap_lock->unlock();
-
-      HeapWord* result =
-        do_collection_pause(word_size, gc_count_before, &succeeded);
-      assert_heap_not_locked();
-      if (result != NULL) {
-        assert(succeeded, "the VM op should have succeeded");
-
-        // Allocations that take place on VM operations do not do any
-        // card dirtying and we have to do it here.
-        dirty_young_block(result, word_size);
-        return result;
-      }
-    }
-
-    // Both paths that get us here from above unlock the Heap_lock.
-    assert_heap_not_locked();
-
-    // We can reach here when we were unsuccessful in doing a GC,
-    // because another thread beat us to it, or because we were locked
-    // out of GC due to the GC locker. In either case a new alloc
-    // region might be available so we will retry the allocation.
-    HeapWord* result = attempt_allocation(word_size);
-    if (result != NULL) {
-      assert_heap_not_locked();
-      return result;
-    }
-
-    // So far our attempts to allocate failed. The only time we'll go
-    // around the loop and try again is if we tried to do a GC and the
-    // VM op that we tried to schedule was not successful because
-    // another thread beat us to it. If that happened it's possible
-    // that by the time we grabbed the Heap_lock again and tried to
-    // allocate other threads filled up the young generation, which
-    // means that the allocation attempt after the GC also failed. So,
-    // it's worth trying to schedule another GC pause.
-    if (succeeded) {
-      break;
-    }
-
-    // Give a warning if we seem to be looping forever.
-    if ((QueuedAllocationWarningCount > 0) &&
-        (try_count % QueuedAllocationWarningCount == 0)) {
-      warning("G1CollectedHeap::attempt_allocation_slow() "
-              "retries %d times", try_count);
-    }
-  }
-
-  assert_heap_locked();
-  return NULL;
-}
-
-// See the comment in the .hpp file about the locking protocol and
-// assumptions of this method (and other related ones).
-HeapWord*
-G1CollectedHeap::attempt_allocation_humongous(size_t word_size,
-                                              bool at_safepoint) {
-  // This is the method that will allocate a humongous object. All
-  // allocation paths that attempt to allocate a humongous object
-  // should eventually reach here. Currently, the only paths are from
-  // mem_allocate() and attempt_allocation_at_safepoint().
-  assert_heap_locked_or_at_safepoint(true /* should_be_vm_thread */);
-  assert(isHumongous(word_size), "attempt_allocation_humongous() "
-         "should only be used for humongous allocations");
-  assert(SafepointSynchronize::is_at_safepoint() == at_safepoint,
-         "at_safepoint and is_at_safepoint() should be a tautology");
-
-  HeapWord* result = NULL;
-
-  // We will loop while succeeded is false, which means that we tried
-  // to do a collection, but the VM op did not succeed. So, when we
-  // exit the loop, either one of the allocation attempts was
-  // successful, or we succeeded in doing the VM op but which was
-  // unable to allocate after the collection.
-  for (int try_count = 1; /* we'll return or break */; try_count += 1) {
-    bool succeeded = true;
-
-    // Given that humongous objects are not allocated in young
-    // regions, we'll first try to do the allocation without doing a
-    // collection hoping that there's enough space in the heap.
-    result = humongous_obj_allocate(word_size);
-    assert(_cur_alloc_region == NULL || !_cur_alloc_region->isHumongous(),
-           "catch a regression of this bug.");
-    if (result != NULL) {
-      if (!at_safepoint) {
-        // If we're not at a safepoint, unlock the Heap_lock.
-        Heap_lock->unlock();
-      }
-      return result;
-    }
-
-    // If we failed to allocate the humongous object, we should try to
-    // do a collection pause (if we're allowed) in case it reclaims
-    // enough space for the allocation to succeed after the pause.
-    if (!at_safepoint) {
-      // Read the GC count while holding the Heap_lock
-      unsigned int gc_count_before = SharedHeap::heap()->total_collections();
-
-      // If we're allowed to do a collection we're not at a
-      // safepoint, so it is safe to unlock the Heap_lock.
-      Heap_lock->unlock();
-
-      result = do_collection_pause(word_size, gc_count_before, &succeeded);
-      assert_heap_not_locked();
-      if (result != NULL) {
-        assert(succeeded, "the VM op should have succeeded");
-        return result;
-      }
-
-      // If we get here, the VM operation either did not succeed
-      // (i.e., another thread beat us to it) or it succeeded but
-      // failed to allocate the object.
-
-      // If we're allowed to do a collection we're not at a
-      // safepoint, so it is safe to lock the Heap_lock.
-      Heap_lock->lock();
-    }
-
-    assert(result == NULL, "otherwise we should have exited the loop earlier");
-
-    // So far our attempts to allocate failed. The only time we'll go
-    // around the loop and try again is if we tried to do a GC and the
-    // VM op that we tried to schedule was not successful because
-    // another thread beat us to it. That way it's possible that some
-    // space was freed up by the thread that successfully scheduled a
-    // GC. So it's worth trying to allocate again.
-    if (succeeded) {
-      break;
-    }
-
-    // Give a warning if we seem to be looping forever.
-    if ((QueuedAllocationWarningCount > 0) &&
-        (try_count % QueuedAllocationWarningCount == 0)) {
-      warning("G1CollectedHeap::attempt_allocation_humongous "
-              "retries %d times", try_count);
-    }
-  }
-
-  assert_heap_locked_or_at_safepoint(true /* should_be_vm_thread */);
-  return NULL;
-}
-
-HeapWord* G1CollectedHeap::attempt_allocation_at_safepoint(size_t word_size,
-                                           bool expect_null_cur_alloc_region) {
-  assert_at_safepoint(true /* should_be_vm_thread */);
-  assert(_cur_alloc_region == NULL || !expect_null_cur_alloc_region,
-         err_msg("the current alloc region was unexpectedly found "
-                 "to be non-NULL, cur alloc region: "PTR_FORMAT" "
-                 "expect_null_cur_alloc_region: %d word_size: "SIZE_FORMAT,
-                 _cur_alloc_region, expect_null_cur_alloc_region, word_size));
-
-  if (!isHumongous(word_size)) {
-    if (!expect_null_cur_alloc_region) {
-      HeapRegion* cur_alloc_region = _cur_alloc_region;
-      if (cur_alloc_region != NULL) {
-        // We are at a safepoint so no reason to use the MT-safe version.
-        HeapWord* result = cur_alloc_region->allocate_no_bot_updates(word_size);
-        if (result != NULL) {
-          assert(is_in(result), "result should be in the heap");
-
-          // We will not do any dirtying here. This is guaranteed to be
-          // called during a safepoint and the thread that scheduled the
-          // pause will do the dirtying if we return a non-NULL result.
-          return result;
-        }
-
-        retire_cur_alloc_region_common(cur_alloc_region);
-      }
-    }
-
-    assert(_cur_alloc_region == NULL,
-           "at this point we should have no cur alloc region");
-    return replace_cur_alloc_region_and_allocate(word_size,
-                                                 true, /* at_safepoint */
-                                                 false /* do_dirtying */,
-                                                 false /* can_expand */);
-  } else {
-    return attempt_allocation_humongous(word_size,
-                                        true /* at_safepoint */);
-  }
-
-  ShouldNotReachHere();
-}
-
 HeapWord* G1CollectedHeap::allocate_new_tlab(size_t word_size) {
   assert_heap_not_locked_and_not_at_safepoint();
-  assert(!isHumongous(word_size), "we do not allow TLABs of humongous size");
-
-  // First attempt: Try allocating out of the current alloc region
-  // using a CAS. If that fails, take the Heap_lock and retry the
-  // allocation, potentially replacing the current alloc region.
-  HeapWord* result = attempt_allocation(word_size);
-  if (result != NULL) {
-    assert_heap_not_locked();
-    return result;
-  }
-
-  // Second attempt: Go to the slower path where we might try to
-  // schedule a collection.
-  result = attempt_allocation_slow(word_size);
-  if (result != NULL) {
-    assert_heap_not_locked();
-    return result;
-  }
-
-  assert_heap_locked();
-  // Need to unlock the Heap_lock before returning.
-  Heap_lock->unlock();
-  return NULL;
+  assert(!isHumongous(word_size), "we do not allow humongous TLABs");
+
+  unsigned int dummy_gc_count_before;
+  return attempt_allocation(word_size, &dummy_gc_count_before);
 }
 
 HeapWord*
@@ -1200,48 +805,18 @@
   assert(!is_tlab, "mem_allocate() this should not be called directly "
          "to allocate TLABs");
 
-  // Loop until the allocation is satisified,
-  // or unsatisfied after GC.
+  // Loop until the allocation is satisified, or unsatisfied after GC.
   for (int try_count = 1; /* we'll return */; try_count += 1) {
     unsigned int gc_count_before;
-    {
-      if (!isHumongous(word_size)) {
-        // First attempt: Try allocating out of the current alloc region
-        // using a CAS. If that fails, take the Heap_lock and retry the
-        // allocation, potentially replacing the current alloc region.
-        HeapWord* result = attempt_allocation(word_size);
-        if (result != NULL) {
-          assert_heap_not_locked();
-          return result;
-        }
-
-        assert_heap_locked();
-
-        // Second attempt: Go to the slower path where we might try to
-        // schedule a collection.
-        result = attempt_allocation_slow(word_size);
-        if (result != NULL) {
-          assert_heap_not_locked();
-          return result;
-        }
-      } else {
-        // attempt_allocation_humongous() requires the Heap_lock to be held.
-        Heap_lock->lock();
-
-        HeapWord* result = attempt_allocation_humongous(word_size,
-                                                     false /* at_safepoint */);
-        if (result != NULL) {
-          assert_heap_not_locked();
-          return result;
-        }
-      }
-
-      assert_heap_locked();
-      // Read the gc count while the heap lock is held.
-      gc_count_before = SharedHeap::heap()->total_collections();
-
-      // Release the Heap_lock before attempting the collection.
-      Heap_lock->unlock();
+
+    HeapWord* result = NULL;
+    if (!isHumongous(word_size)) {
+      result = attempt_allocation(word_size, &gc_count_before);
+    } else {
+      result = attempt_allocation_humongous(word_size, &gc_count_before);
+    }
+    if (result != NULL) {
+      return result;
     }
 
     // Create the garbage collection operation...
@@ -1249,7 +824,6 @@
     // ...and get the VM thread to execute it.
     VMThread::execute(&op);
 
-    assert_heap_not_locked();
     if (op.prologue_succeeded() && op.pause_succeeded()) {
       // If the operation was successful we'll return the result even
       // if it is NULL. If the allocation attempt failed immediately
@@ -1275,21 +849,207 @@
   }
 
   ShouldNotReachHere();
+  return NULL;
 }
 
-void G1CollectedHeap::abandon_cur_alloc_region() {
+HeapWord* G1CollectedHeap::attempt_allocation_slow(size_t word_size,
+                                           unsigned int *gc_count_before_ret) {
+  // Make sure you read the note in attempt_allocation_humongous().
+
+  assert_heap_not_locked_and_not_at_safepoint();
+  assert(!isHumongous(word_size), "attempt_allocation_slow() should not "
+         "be called for humongous allocation requests");
+
+  // We should only get here after the first-level allocation attempt
+  // (attempt_allocation()) failed to allocate.
+
+  // We will loop until a) we manage to successfully perform the
+  // allocation or b) we successfully schedule a collection which
+  // fails to perform the allocation. b) is the only case when we'll
+  // return NULL.
+  HeapWord* result = NULL;
+  for (int try_count = 1; /* we'll return */; try_count += 1) {
+    bool should_try_gc;
+    unsigned int gc_count_before;
+
+    {
+      MutexLockerEx x(Heap_lock);
+
+      result = _mutator_alloc_region.attempt_allocation_locked(word_size,
+                                                      false /* bot_updates */);
+      if (result != NULL) {
+        return result;
+      }
+
+      // If we reach here, attempt_allocation_locked() above failed to
+      // allocate a new region. So the mutator alloc region should be NULL.
+      assert(_mutator_alloc_region.get() == NULL, "only way to get here");
+
+      if (GC_locker::is_active_and_needs_gc()) {
+        if (g1_policy()->can_expand_young_list()) {
+          result = _mutator_alloc_region.attempt_allocation_force(word_size,
+                                                      false /* bot_updates */);
+          if (result != NULL) {
+            return result;
+          }
+        }
+        should_try_gc = false;
+      } else {
+        // Read the GC count while still holding the Heap_lock.
+        gc_count_before = SharedHeap::heap()->total_collections();
+        should_try_gc = true;
+      }
+    }
+
+    if (should_try_gc) {
+      bool succeeded;
+      result = do_collection_pause(word_size, gc_count_before, &succeeded);
+      if (result != NULL) {
+        assert(succeeded, "only way to get back a non-NULL result");
+        return result;
+      }
+
+      if (succeeded) {
+        // If we get here we successfully scheduled a collection which
+        // failed to allocate. No point in trying to allocate
+        // further. We'll just return NULL.
+        MutexLockerEx x(Heap_lock);
+        *gc_count_before_ret = SharedHeap::heap()->total_collections();
+        return NULL;
+      }
+    } else {
+      GC_locker::stall_until_clear();
+    }
+
+    // We can reach here if we were unsuccessul in scheduling a
+    // collection (because another thread beat us to it) or if we were
+    // stalled due to the GC locker. In either can we should retry the
+    // allocation attempt in case another thread successfully
+    // performed a collection and reclaimed enough space. We do the
+    // first attempt (without holding the Heap_lock) here and the
+    // follow-on attempt will be at the start of the next loop
+    // iteration (after taking the Heap_lock).
+    result = _mutator_alloc_region.attempt_allocation(word_size,
+                                                      false /* bot_updates */);
+    if (result != NULL ){
+      return result;
+    }
+
+    // Give a warning if we seem to be looping forever.
+    if ((QueuedAllocationWarningCount > 0) &&
+        (try_count % QueuedAllocationWarningCount == 0)) {
+      warning("G1CollectedHeap::attempt_allocation_slow() "
+              "retries %d times", try_count);
+    }
+  }
+
+  ShouldNotReachHere();
+  return NULL;
+}
+
+HeapWord* G1CollectedHeap::attempt_allocation_humongous(size_t word_size,
+                                          unsigned int * gc_count_before_ret) {
+  // The structure of this method has a lot of similarities to
+  // attempt_allocation_slow(). The reason these two were not merged
+  // into a single one is that such a method would require several "if
+  // allocation is not humongous do this, otherwise do that"
+  // conditional paths which would obscure its flow. In fact, an early
+  // version of this code did use a unified method which was harder to
+  // follow and, as a result, it had subtle bugs that were hard to
+  // track down. So keeping these two methods separate allows each to
+  // be more readable. It will be good to keep these two in sync as
+  // much as possible.
+
+  assert_heap_not_locked_and_not_at_safepoint();
+  assert(isHumongous(word_size), "attempt_allocation_humongous() "
+         "should only be called for humongous allocations");
+
+  // We will loop until a) we manage to successfully perform the
+  // allocation or b) we successfully schedule a collection which
+  // fails to perform the allocation. b) is the only case when we'll
+  // return NULL.
+  HeapWord* result = NULL;
+  for (int try_count = 1; /* we'll return */; try_count += 1) {
+    bool should_try_gc;
+    unsigned int gc_count_before;
+
+    {
+      MutexLockerEx x(Heap_lock);
+
+      // Given that humongous objects are not allocated in young
+      // regions, we'll first try to do the allocation without doing a
+      // collection hoping that there's enough space in the heap.
+      result = humongous_obj_allocate(word_size);
+      if (result != NULL) {
+        return result;
+      }
+
+      if (GC_locker::is_active_and_needs_gc()) {
+        should_try_gc = false;
+      } else {
+        // Read the GC count while still holding the Heap_lock.
+        gc_count_before = SharedHeap::heap()->total_collections();
+        should_try_gc = true;
+      }
+    }
+
+    if (should_try_gc) {
+      // If we failed to allocate the humongous object, we should try to
+      // do a collection pause (if we're allowed) in case it reclaims
+      // enough space for the allocation to succeed after the pause.
+
+      bool succeeded;
+      result = do_collection_pause(word_size, gc_count_before, &succeeded);
+      if (result != NULL) {
+        assert(succeeded, "only way to get back a non-NULL result");
+        return result;
+      }
+
+      if (succeeded) {
+        // If we get here we successfully scheduled a collection which
+        // failed to allocate. No point in trying to allocate
+        // further. We'll just return NULL.
+        MutexLockerEx x(Heap_lock);
+        *gc_count_before_ret = SharedHeap::heap()->total_collections();
+        return NULL;
+      }
+    } else {
+      GC_locker::stall_until_clear();
+    }
+
+    // We can reach here if we were unsuccessul in scheduling a
+    // collection (because another thread beat us to it) or if we were
+    // stalled due to the GC locker. In either can we should retry the
+    // allocation attempt in case another thread successfully
+    // performed a collection and reclaimed enough space.  Give a
+    // warning if we seem to be looping forever.
+
+    if ((QueuedAllocationWarningCount > 0) &&
+        (try_count % QueuedAllocationWarningCount == 0)) {
+      warning("G1CollectedHeap::attempt_allocation_humongous() "
+              "retries %d times", try_count);
+    }
+  }
+
+  ShouldNotReachHere();
+  return NULL;
+}
+
+HeapWord* G1CollectedHeap::attempt_allocation_at_safepoint(size_t word_size,
+                                       bool expect_null_mutator_alloc_region) {
   assert_at_safepoint(true /* should_be_vm_thread */);
-
-  HeapRegion* cur_alloc_region = _cur_alloc_region;
-  if (cur_alloc_region != NULL) {
-    assert(!cur_alloc_region->is_empty(),
-           "the current alloc region can never be empty");
-    assert(cur_alloc_region->is_young(),
-           "the current alloc region should be young");
-
-    retire_cur_alloc_region_common(cur_alloc_region);
-  }
-  assert(_cur_alloc_region == NULL, "post-condition");
+  assert(_mutator_alloc_region.get() == NULL ||
+                                             !expect_null_mutator_alloc_region,
+         "the current alloc region was unexpectedly found to be non-NULL");
+
+  if (!isHumongous(word_size)) {
+    return _mutator_alloc_region.attempt_allocation_locked(word_size,
+                                                      false /* bot_updates */);
+  } else {
+    return humongous_obj_allocate(word_size);
+  }
+
+  ShouldNotReachHere();
 }
 
 void G1CollectedHeap::abandon_gc_alloc_regions() {
@@ -1417,8 +1177,8 @@
 
     if (VerifyBeforeGC && total_collections() >= VerifyGCStartAt) {
       HandleMark hm;  // Discard invalid handles created during verification
+      gclog_or_tty->print(" VerifyBeforeGC:");
       prepare_for_verify();
-      gclog_or_tty->print(" VerifyBeforeGC:");
       Universe::verify(true);
     }
 
@@ -1439,9 +1199,8 @@
     concurrent_mark()->abort();
 
     // Make sure we'll choose a new allocation region afterwards.
-    abandon_cur_alloc_region();
+    release_mutator_alloc_region();
     abandon_gc_alloc_regions();
-    assert(_cur_alloc_region == NULL, "Invariant.");
     g1_rem_set()->cleanupHRRS();
     tear_down_region_lists();
 
@@ -1547,6 +1306,8 @@
     // evacuation pause.
     clear_cset_fast_test();
 
+    init_mutator_alloc_region();
+
     double end = os::elapsedTime();
     g1_policy()->record_full_collection_end();
 
@@ -1720,8 +1481,9 @@
 
   *succeeded = true;
   // Let's attempt the allocation first.
-  HeapWord* result = attempt_allocation_at_safepoint(word_size,
-                                     false /* expect_null_cur_alloc_region */);
+  HeapWord* result =
+    attempt_allocation_at_safepoint(word_size,
+                                 false /* expect_null_mutator_alloc_region */);
   if (result != NULL) {
     assert(*succeeded, "sanity");
     return result;
@@ -1748,7 +1510,7 @@
 
   // Retry the allocation
   result = attempt_allocation_at_safepoint(word_size,
-                                      true /* expect_null_cur_alloc_region */);
+                                  true /* expect_null_mutator_alloc_region */);
   if (result != NULL) {
     assert(*succeeded, "sanity");
     return result;
@@ -1765,7 +1527,7 @@
 
   // Retry the allocation once more
   result = attempt_allocation_at_safepoint(word_size,
-                                      true /* expect_null_cur_alloc_region */);
+                                  true /* expect_null_mutator_alloc_region */);
   if (result != NULL) {
     assert(*succeeded, "sanity");
     return result;
@@ -1796,7 +1558,7 @@
   if (expand(expand_bytes)) {
     verify_region_sets_optional();
     return attempt_allocation_at_safepoint(word_size,
-                                          false /* expect_null_cur_alloc_region */);
+                                 false /* expect_null_mutator_alloc_region */);
   }
   return NULL;
 }
@@ -1940,7 +1702,6 @@
   _evac_failure_scan_stack(NULL) ,
   _mark_in_progress(false),
   _cg1r(NULL), _summary_bytes_used(0),
-  _cur_alloc_region(NULL),
   _refine_cte_cl(NULL),
   _full_collection(false),
   _free_list("Master Free List"),
@@ -2099,7 +1860,6 @@
   _g1_max_committed = _g1_committed;
   _hrs = new HeapRegionSeq(_expansion_regions);
   guarantee(_hrs != NULL, "Couldn't allocate HeapRegionSeq");
-  guarantee(_cur_alloc_region == NULL, "from constructor");
 
   // 6843694 - ensure that the maximum region index can fit
   // in the remembered set structures.
@@ -2195,6 +1955,22 @@
   // Do later initialization work for concurrent refinement.
   _cg1r->init();
 
+  // Here we allocate the dummy full region that is required by the
+  // G1AllocRegion class. If we don't pass an address in the reserved
+  // space here, lots of asserts fire.
+  MemRegion mr(_g1_reserved.start(), HeapRegion::GrainWords);
+  HeapRegion* dummy_region = new HeapRegion(_bot_shared, mr, true);
+  // We'll re-use the same region whether the alloc region will
+  // require BOT updates or not and, if it doesn't, then a non-young
+  // region will complain that it cannot support allocations without
+  // BOT updates. So we'll tag the dummy region as young to avoid that.
+  dummy_region->set_young();
+  // Make sure it's full.
+  dummy_region->set_top(dummy_region->end());
+  G1AllocRegion::setup(this, dummy_region);
+
+  init_mutator_alloc_region();
+
   return JNI_OK;
 }
 
@@ -2261,7 +2037,7 @@
          "Should be owned on this thread's behalf.");
   size_t result = _summary_bytes_used;
   // Read only once in case it is set to NULL concurrently
-  HeapRegion* hr = _cur_alloc_region;
+  HeapRegion* hr = _mutator_alloc_region.get();
   if (hr != NULL)
     result += hr->used();
   return result;
@@ -2324,13 +2100,11 @@
   // to free(), resulting in a SIGSEGV. Note that this doesn't appear
   // to be a problem in the optimized build, since the two loads of the
   // current allocation region field are optimized away.
-  HeapRegion* car = _cur_alloc_region;
-
-  // FIXME: should iterate over all regions?
-  if (car == NULL) {
+  HeapRegion* hr = _mutator_alloc_region.get();
+  if (hr == NULL) {
     return 0;
   }
-  return car->free();
+  return hr->free();
 }
 
 bool G1CollectedHeap::should_do_concurrent_full_gc(GCCause::Cause cause) {
@@ -2781,16 +2555,12 @@
   // since we can't allow tlabs to grow big enough to accomodate
   // humongous objects.
 
-  // We need to store the cur alloc region locally, since it might change
-  // between when we test for NULL and when we use it later.
-  ContiguousSpace* cur_alloc_space = _cur_alloc_region;
+  HeapRegion* hr = _mutator_alloc_region.get();
   size_t max_tlab_size = _humongous_object_threshold_in_words * wordSize;
-
-  if (cur_alloc_space == NULL) {
+  if (hr == NULL) {
     return max_tlab_size;
   } else {
-    return MIN2(MAX2(cur_alloc_space->free(), (size_t)MinTLABSize),
-                max_tlab_size);
+    return MIN2(MAX2(hr->free(), (size_t) MinTLABSize), max_tlab_size);
   }
 }
 
@@ -3364,6 +3134,7 @@
   }
 
   verify_region_sets_optional();
+  verify_dirty_young_regions();
 
   {
     // This call will decide whether this pause is an initial-mark
@@ -3425,8 +3196,8 @@
 
       if (VerifyBeforeGC && total_collections() >= VerifyGCStartAt) {
         HandleMark hm;  // Discard invalid handles created during verification
+        gclog_or_tty->print(" VerifyBeforeGC:");
         prepare_for_verify();
-        gclog_or_tty->print(" VerifyBeforeGC:");
         Universe::verify(false);
       }
 
@@ -3442,7 +3213,7 @@
 
       // Forget the current alloc region (we might even choose it to be part
       // of the collection set!).
-      abandon_cur_alloc_region();
+      release_mutator_alloc_region();
 
       // The elapsed time induced by the start time below deliberately elides
       // the possible verification above.
@@ -3573,6 +3344,8 @@
       g1_policy()->print_collection_set(g1_policy()->inc_cset_head(), gclog_or_tty);
 #endif // YOUNG_LIST_VERBOSE
 
+      init_mutator_alloc_region();
+
       double end_time_sec = os::elapsedTime();
       double pause_time_ms = (end_time_sec - start_time_sec) * MILLIUNITS;
       g1_policy()->record_pause_time_ms(pause_time_ms);
@@ -3655,6 +3428,15 @@
   return gclab_word_size;
 }
 
+void G1CollectedHeap::init_mutator_alloc_region() {
+  assert(_mutator_alloc_region.get() == NULL, "pre-condition");
+  _mutator_alloc_region.init();
+}
+
+void G1CollectedHeap::release_mutator_alloc_region() {
+  _mutator_alloc_region.release();
+  assert(_mutator_alloc_region.get() == NULL, "post-condition");
+}
 
 void G1CollectedHeap::set_gc_alloc_region(int purpose, HeapRegion* r) {
   assert(purpose >= 0 && purpose < GCAllocPurposeCount, "invalid purpose");
@@ -3879,7 +3661,7 @@
       if (r->is_empty()) {
         // We didn't actually allocate anything in it; let's just put
         // it back on the free list.
-        _free_list.add_as_tail(r);
+        _free_list.add_as_head(r);
       } else if (_retain_gc_alloc_region[ap] && !totally) {
         // retain it so that we can use it at the beginning of the next GC
         _retained_gc_alloc_regions[ap] = r;
@@ -5013,7 +4795,7 @@
 
   *pre_used += hr->used();
   hr->hr_clear(par, true /* clear_space */);
-  free_list->add_as_tail(hr);
+  free_list->add_as_head(hr);
 }
 
 void G1CollectedHeap::free_humongous_region(HeapRegion* hr,
@@ -5065,7 +4847,7 @@
   }
   if (free_list != NULL && !free_list->is_empty()) {
     MutexLockerEx x(FreeList_lock, Mutex::_no_safepoint_check_flag);
-    _free_list.add_as_tail(free_list);
+    _free_list.add_as_head(free_list);
   }
   if (humongous_proxy_set != NULL && !humongous_proxy_set->is_empty()) {
     MutexLockerEx x(OldSets_lock, Mutex::_no_safepoint_check_flag);
@@ -5140,10 +4922,8 @@
   CardTableModRefBS* _ct_bs;
 public:
   G1VerifyCardTableCleanup(CardTableModRefBS* ct_bs)
-    : _ct_bs(ct_bs)
-  { }
-  virtual bool doHeapRegion(HeapRegion* r)
-  {
+    : _ct_bs(ct_bs) { }
+  virtual bool doHeapRegion(HeapRegion* r) {
     MemRegion mr(r->bottom(), r->end());
     if (r->is_survivor()) {
       _ct_bs->verify_dirty_region(mr);
@@ -5153,6 +4933,29 @@
     return false;
   }
 };
+
+void G1CollectedHeap::verify_dirty_young_list(HeapRegion* head) {
+  CardTableModRefBS* ct_bs = (CardTableModRefBS*) (barrier_set());
+  for (HeapRegion* hr = head; hr != NULL; hr = hr->get_next_young_region()) {
+    // We cannot guarantee that [bottom(),end()] is dirty.  Threads
+    // dirty allocated blocks as they allocate them. The thread that
+    // retires each region and replaces it with a new one will do a
+    // maximal allocation to fill in [pre_dummy_top(),end()] but will
+    // not dirty that area (one less thing to have to do while holding
+    // a lock). So we can only verify that [bottom(),pre_dummy_top()]
+    // is dirty. Also note that verify_dirty_region() requires
+    // mr.start() and mr.end() to be card aligned and pre_dummy_top()
+    // is not guaranteed to be.
+    MemRegion mr(hr->bottom(),
+                 ct_bs->align_to_card_boundary(hr->pre_dummy_top()));
+    ct_bs->verify_dirty_region(mr);
+  }
+}
+
+void G1CollectedHeap::verify_dirty_young_regions() {
+  verify_dirty_young_list(_young_list->first_region());
+  verify_dirty_young_list(_young_list->first_survivor_region());
+}
 #endif
 
 void G1CollectedHeap::cleanUpCardTable() {
@@ -5500,6 +5303,44 @@
   }
 }
 
+HeapRegion* G1CollectedHeap::new_mutator_alloc_region(size_t word_size,
+                                                      bool force) {
+  assert_heap_locked_or_at_safepoint(true /* should_be_vm_thread */);
+  assert(!force || g1_policy()->can_expand_young_list(),
+         "if force is true we should be able to expand the young list");
+  if (force || !g1_policy()->is_young_list_full()) {
+    HeapRegion* new_alloc_region = new_region(word_size,
+                                              false /* do_expand */);
+    if (new_alloc_region != NULL) {
+      g1_policy()->update_region_num(true /* next_is_young */);
+      set_region_short_lived_locked(new_alloc_region);
+      return new_alloc_region;
+    }
+  }
+  return NULL;
+}
+
+void G1CollectedHeap::retire_mutator_alloc_region(HeapRegion* alloc_region,
+                                                  size_t allocated_bytes) {
+  assert_heap_locked_or_at_safepoint(true /* should_be_vm_thread */);
+  assert(alloc_region->is_young(), "all mutator alloc regions should be young");
+
+  g1_policy()->add_region_to_incremental_cset_lhs(alloc_region);
+  _summary_bytes_used += allocated_bytes;
+}
+
+HeapRegion* MutatorAllocRegion::allocate_new_region(size_t word_size,
+                                                    bool force) {
+  return _g1h->new_mutator_alloc_region(word_size, force);
+}
+
+void MutatorAllocRegion::retire_region(HeapRegion* alloc_region,
+                                       size_t allocated_bytes) {
+  _g1h->retire_mutator_alloc_region(alloc_region, allocated_bytes);
+}
+
+// Heap region set verification
+
 class VerifyRegionListsClosure : public HeapRegionClosure {
 private:
   HumongousRegionSet* _humongous_set;
--- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -26,6 +26,7 @@
 #define SHARE_VM_GC_IMPLEMENTATION_G1_G1COLLECTEDHEAP_HPP
 
 #include "gc_implementation/g1/concurrentMark.hpp"
+#include "gc_implementation/g1/g1AllocRegion.hpp"
 #include "gc_implementation/g1/g1RemSet.hpp"
 #include "gc_implementation/g1/heapRegionSets.hpp"
 #include "gc_implementation/parNew/parGCAllocBuffer.hpp"
@@ -128,6 +129,15 @@
   void          print();
 };
 
+class MutatorAllocRegion : public G1AllocRegion {
+protected:
+  virtual HeapRegion* allocate_new_region(size_t word_size, bool force);
+  virtual void retire_region(HeapRegion* alloc_region, size_t allocated_bytes);
+public:
+  MutatorAllocRegion()
+    : G1AllocRegion("Mutator Alloc Region", false /* bot_updates */) { }
+};
+
 class RefineCardTableEntryClosure;
 class G1CollectedHeap : public SharedHeap {
   friend class VM_G1CollectForAllocation;
@@ -135,6 +145,7 @@
   friend class VM_G1CollectFull;
   friend class VM_G1IncCollectionPause;
   friend class VMStructs;
+  friend class MutatorAllocRegion;
 
   // Closures used in implementation.
   friend class G1ParCopyHelper;
@@ -197,12 +208,15 @@
   // The sequence of all heap regions in the heap.
   HeapRegionSeq* _hrs;
 
-  // The region from which normal-sized objects are currently being
-  // allocated.  May be NULL.
-  HeapRegion* _cur_alloc_region;
+  // Alloc region used to satisfy mutator allocation requests.
+  MutatorAllocRegion _mutator_alloc_region;
 
-  // Postcondition: cur_alloc_region == NULL.
-  void abandon_cur_alloc_region();
+  // It resets the mutator alloc region before new allocations can take place.
+  void init_mutator_alloc_region();
+
+  // It releases the mutator alloc region.
+  void release_mutator_alloc_region();
+
   void abandon_gc_alloc_regions();
 
   // The to-space memory regions into which objects are being copied during
@@ -360,27 +374,21 @@
   G1CollectorPolicy* _g1_policy;
 
   // This is the second level of trying to allocate a new region. If
-  // new_region_work didn't find a region in the free_list, this call
-  // 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.
+  // new_region() didn't find a region on the free_list, this call will
+  // check whether there's anything available on the
+  // secondary_free_list and/or wait for more regions to appear on
+  // that list, if _free_regions_coming is set.
   HeapRegion* new_region_try_secondary_free_list();
 
   // 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);
+  HeapRegion* new_region(size_t word_size, bool do_expand);
 
-  // Try to allocate a new region to be used for allocation by a
-  // mutator thread. Attempt to expand the heap if no region is
+  // 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.
-  HeapRegion* new_alloc_region(size_t word_size) {
-    return new_region_work(word_size, false /* do_expand */);
-  }
-
-  // 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
@@ -415,10 +423,6 @@
   // * All non-TLAB allocation requests should go to mem_allocate()
   //   and mem_allocate() should never be called with is_tlab == true.
   //
-  // * If the GC locker is active we currently stall until we can
-  //   allocate a new young region. This will be changed in the
-  //   near future (see CR 6994056).
-  //
   // * If either call cannot satisfy the allocation request using the
   //   current allocating region, they will try to get a new one. If
   //   this fails, they will attempt to do an evacuation pause and
@@ -441,122 +445,38 @@
                                  bool   is_tlab, /* expected to be false */
                                  bool*  gc_overhead_limit_was_exceeded);
 
-  // The following methods, allocate_from_cur_allocation_region(),
-  // attempt_allocation(), attempt_allocation_locked(),
-  // replace_cur_alloc_region_and_allocate(),
-  // attempt_allocation_slow(), and attempt_allocation_humongous()
-  // have very awkward pre- and post-conditions with respect to
-  // locking:
-  //
-  // If they are called outside a safepoint they assume the caller
-  // holds the Heap_lock when it calls them. However, on exit they
-  // will release the Heap_lock if they return a non-NULL result, but
-  // keep holding the Heap_lock if they return a NULL result. The
-  // reason for this is that we need to dirty the cards that span
-  // allocated blocks on young regions to avoid having to take the
-  // slow path of the write barrier (for performance reasons we don't
-  // update RSets for references whose source is a young region, so we
-  // don't need to look at dirty cards on young regions). But, doing
-  // this card dirtying while holding the Heap_lock can be a
-  // scalability bottleneck, especially given that some allocation
-  // requests might be of non-trivial size (and the larger the region
-  // size is, the fewer allocations requests will be considered
-  // humongous, as the humongous size limit is a fraction of the
-  // region size). So, when one of these calls succeeds in allocating
-  // a block it does the card dirtying after it releases the Heap_lock
-  // which is why it will return without holding it.
-  //
-  // The above assymetry is the reason why locking / unlocking is done
-  // explicitly (i.e., with Heap_lock->lock() and
-  // Heap_lock->unlocked()) instead of using MutexLocker and
-  // MutexUnlocker objects. The latter would ensure that the lock is
-  // unlocked / re-locked at every possible exit out of the basic
-  // block. However, we only want that action to happen in selected
-  // places.
-  //
-  // Further, if the above methods are called during a safepoint, then
-  // naturally there's no assumption about the Heap_lock being held or
-  // there's no attempt to unlock it. The parameter at_safepoint
-  // indicates whether the call is made during a safepoint or not (as
-  // an optimization, to avoid reading the global flag with
-  // SafepointSynchronize::is_at_safepoint()).
-  //
-  // The methods share these parameters:
-  //
-  // * word_size     : the size of the allocation request in words
-  // * at_safepoint  : whether the call is done at a safepoint; this
-  //                   also determines whether a GC is permitted
-  //                   (at_safepoint == false) or not (at_safepoint == true)
-  // * do_dirtying   : whether the method should dirty the allocated
-  //                   block before returning
-  //
-  // They all return either the address of the block, if they
-  // successfully manage to allocate it, or NULL.
+  // The following three methods take a gc_count_before_ret
+  // parameter which is used to return the GC count if the method
+  // returns NULL. Given that we are required to read the GC count
+  // while holding the Heap_lock, and these paths will take the
+  // Heap_lock at some point, it's easier to get them to read the GC
+  // count while holding the Heap_lock before they return NULL instead
+  // of the caller (namely: mem_allocate()) having to also take the
+  // Heap_lock just to read the GC count.
+
+  // First-level mutator allocation attempt: try to allocate out of
+  // the mutator alloc region without taking the Heap_lock. This
+  // should only be used for non-humongous allocations.
+  inline HeapWord* attempt_allocation(size_t word_size,
+                                      unsigned int* gc_count_before_ret);
 
-  // It tries to satisfy an allocation request out of the current
-  // alloc region, which is passed as a parameter. It assumes that the
-  // caller has checked that the current alloc region is not NULL.
-  // Given that the caller has to check the current alloc region for
-  // at least NULL, it might as well pass it as the first parameter so
-  // that the method doesn't have to read it from the
-  // _cur_alloc_region field again. It is called from both
-  // attempt_allocation() and attempt_allocation_locked() and the
-  // with_heap_lock parameter indicates whether the caller was holding
-  // the heap lock when it called it or not.
-  inline HeapWord* allocate_from_cur_alloc_region(HeapRegion* cur_alloc_region,
-                                                  size_t word_size,
-                                                  bool with_heap_lock);
-
-  // First-level of allocation slow path: it attempts to allocate out
-  // of the current alloc region in a lock-free manner using a CAS. If
-  // that fails it takes the Heap_lock and calls
-  // attempt_allocation_locked() for the second-level slow path.
-  inline HeapWord* attempt_allocation(size_t word_size);
-
-  // Second-level of allocation slow path: while holding the Heap_lock
-  // it tries to allocate out of the current alloc region and, if that
-  // fails, tries to allocate out of a new current alloc region.
-  inline HeapWord* attempt_allocation_locked(size_t word_size);
+  // Second-level mutator allocation attempt: take the Heap_lock and
+  // retry the allocation attempt, potentially scheduling a GC
+  // pause. This should only be used for non-humongous allocations.
+  HeapWord* attempt_allocation_slow(size_t word_size,
+                                    unsigned int* gc_count_before_ret);
 
-  // It assumes that the current alloc region has been retired and
-  // tries to allocate a new one. If it's successful, it performs the
-  // allocation out of the new current alloc region and updates
-  // _cur_alloc_region. Normally, it would try to allocate a new
-  // region if the young gen is not full, unless can_expand is true in
-  // which case it would always try to allocate a new region.
-  HeapWord* replace_cur_alloc_region_and_allocate(size_t word_size,
-                                                  bool at_safepoint,
-                                                  bool do_dirtying,
-                                                  bool can_expand);
-
-  // Third-level of allocation slow path: when we are unable to
-  // allocate a new current alloc region to satisfy an allocation
-  // request (i.e., when attempt_allocation_locked() fails). It will
-  // try to do an evacuation pause, which might stall due to the GC
-  // locker, and retry the allocation attempt when appropriate.
-  HeapWord* attempt_allocation_slow(size_t word_size);
+  // Takes the Heap_lock and attempts a humongous allocation. It can
+  // potentially schedule a GC pause.
+  HeapWord* attempt_allocation_humongous(size_t word_size,
+                                         unsigned int* gc_count_before_ret);
 
-  // The method that tries to satisfy a humongous allocation
-  // request. If it cannot satisfy it it will try to do an evacuation
-  // pause to perhaps reclaim enough space to be able to satisfy the
-  // allocation request afterwards.
-  HeapWord* attempt_allocation_humongous(size_t word_size,
-                                         bool at_safepoint);
-
-  // It does the common work when we are retiring the current alloc region.
-  inline void retire_cur_alloc_region_common(HeapRegion* cur_alloc_region);
-
-  // It retires the current alloc region, which is passed as a
-  // parameter (since, typically, the caller is already holding on to
-  // it). It sets _cur_alloc_region to NULL.
-  void retire_cur_alloc_region(HeapRegion* cur_alloc_region);
-
-  // It attempts to do an allocation immediately before or after an
-  // evacuation pause and can only be called by the VM thread. It has
-  // slightly different assumptions that the ones before (i.e.,
-  // assumes that the current alloc region has been retired).
+  // Allocation attempt that should be called during safepoints (e.g.,
+  // at the end of a successful GC). expect_null_mutator_alloc_region
+  // specifies whether the mutator alloc region is expected to be NULL
+  // or not.
   HeapWord* attempt_allocation_at_safepoint(size_t word_size,
-                                            bool expect_null_cur_alloc_region);
+                                       bool expect_null_mutator_alloc_region);
 
   // It dirties the cards that cover the block so that so that the post
   // write barrier never queues anything when updating objects on this
@@ -583,6 +503,12 @@
   // GC pause.
   void  retire_alloc_region(HeapRegion* alloc_region, bool par);
 
+  // These two methods are the "callbacks" from the G1AllocRegion class.
+
+  HeapRegion* new_mutator_alloc_region(size_t word_size, bool force);
+  void retire_mutator_alloc_region(HeapRegion* alloc_region,
+                                   size_t allocated_bytes);
+
   // - if explicit_gc is true, the GC is for a System.gc() or a heap
   //   inspection request and should collect the entire heap
   // - if clear_all_soft_refs is true, all soft references should be
@@ -1027,6 +953,9 @@
   // The number of regions available for "regular" expansion.
   size_t expansion_regions() { return _expansion_regions; }
 
+  void verify_dirty_young_list(HeapRegion* head) PRODUCT_RETURN;
+  void verify_dirty_young_regions() PRODUCT_RETURN;
+
   // verify_region_sets() performs verification over the region
   // lists. It will be compiled in the product code to be used when
   // necessary (i.e., during heap verification).
@@ -1061,7 +990,7 @@
   }
 
   void append_secondary_free_list() {
-    _free_list.add_as_tail(&_secondary_free_list);
+    _free_list.add_as_head(&_secondary_free_list);
   }
 
   void append_secondary_free_list_if_not_empty_with_lock() {
@@ -1128,7 +1057,13 @@
     return _g1_reserved.contains(p);
   }
 
-  // Returns a MemRegion that corresponds to the space that  has been
+  // Returns a MemRegion that corresponds to the space that has been
+  // reserved for the heap
+  MemRegion g1_reserved() {
+    return _g1_reserved;
+  }
+
+  // Returns a MemRegion that corresponds to the space that has been
   // committed in the heap
   MemRegion g1_committed() {
     return _g1_committed;
--- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp	Tue Apr 12 10:32:42 2011 -0400
+++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp	Thu Apr 14 11:02:05 2011 -0400
@@ -27,6 +27,7 @@
 
 #include "gc_implementation/g1/concurrentMark.hpp"
 #include "gc_implementation/g1/g1CollectedHeap.hpp"
+#include "gc_implementation/g1/g1AllocRegion.inline.hpp"
 #include "gc_implementation/g1/g1CollectorPolicy.hpp"
 #include "gc_implementation/g1/heapRegionSeq.inline.hpp"
 #include "utilities/taskqueue.hpp"
@@ -59,131 +60,23 @@
   return r != NULL && r->in_collection_set();
 }
 
-// See the comment in the .hpp file about the locking protocol and
-// assumptions of this method (and other related ones).
 inline HeapWord*
-G1CollectedHeap::allocate_from_cur_alloc_region(HeapRegion* cur_alloc_region,
-                                                size_t word_size,
-                                                bool with_heap_lock) {
-  assert_not_at_safepoint();
-  assert(with_heap_lock == Heap_lock->owned_by_self(),
-         "with_heap_lock and Heap_lock->owned_by_self() should be a tautology");
-  assert(cur_alloc_region != NULL, "pre-condition of the method");
-  assert(cur_alloc_region->is_young(),
-         "we only support young current alloc regions");
-  assert(!isHumongous(word_size), "allocate_from_cur_alloc_region() "
-         "should not be used for humongous allocations");
-  assert(!cur_alloc_region->isHumongous(), "Catch a regression of this bug.");
-
-  assert(!cur_alloc_region->is_empty(),
-         err_msg("region ["PTR_FORMAT","PTR_FORMAT"] should not be empty",
-                 cur_alloc_region->bottom(), cur_alloc_region->end()));
-  HeapWord* result = cur_alloc_region->par_allocate_no_bot_updates(word_size);
-  if (result != NULL) {
-    assert(is_in(result), "result should be in the heap");
-
-    if (with_heap_lock) {
-      Heap_lock->unlock();
-    }
-    assert_heap_not_locked();
-    // Do the dirtying after we release the Heap_lock.
-    dirty_young_block(result, word_size);
-    return result;
-  }
-
-  if (with_heap_lock) {
-    assert_heap_locked();
-  } else {
-    assert_heap_not_locked();
-  }
-  return NULL;
-}
-
-// See the comment in the .hpp file about the locking protocol and
-// assumptions of this method (and other related ones).
-inline HeapWord*
-G1CollectedHeap::attempt_allocation(size_t word_size) {
+G1CollectedHeap::attempt_allocation(size_t word_size,
+                                    unsigned int* gc_count_before_ret) {
   assert_heap_not_locked_and_not_at_safepoint();
-  assert(!isHumongous(word_size), "attempt_allocation() should not be called "
-         "for humongous allocation requests");
-
-  HeapRegion* cur_alloc_region = _cur_alloc_region;
-  if (cur_alloc_region != NULL) {
-    HeapWord* result = allocate_from_cur_alloc_region(cur_alloc_region,
-                                                   word_size,
-                                                   false /* with_heap_lock */);
-    assert_heap_not_locked();
-    if (result != NULL) {
-      return result;
-    }
-  }
+  assert(!isHumongous(word_size), "attempt_allocation() should not "
+         "be called for humongous allocation requests");
 
-  // Our attempt to allocate lock-free failed as the current
-  // allocation region is either NULL or full. So, we'll now take the
-  // Heap_lock and retry.
-  Heap_lock->lock();
-
-  HeapWord* result = attempt_allocation_locked(word_size);
-  if (result != NULL) {
-    assert_heap_not_locked();
-    return result;
+  HeapWord* result = _mutator_alloc_region.attempt_allocation(word_size,
+                                                      false /* bot_updates */);
+  if (result == NULL) {
+    result = attempt_allocation_slow(word_size, gc_count_before_ret);
   }
-
-  assert_heap_locked();
-  return NULL;
-}
-
-inline void
-G1CollectedHeap::retire_cur_alloc_region_common(HeapRegion* cur_alloc_region) {
-  assert_heap_locked_or_at_safepoint(true /* should_be_vm_thread */);
-  assert(cur_alloc_region != NULL && cur_alloc_region == _cur_alloc_region,
-         "pre-condition of the call");
-  assert(cur_alloc_region->is_young(),
-         "we only support young current alloc regions");
-
-  // The region is guaranteed to be young
-  g1_policy()->add_region_to_incremental_cset_lhs(cur_alloc_region);
-  _summary_bytes_used += cur_alloc_region->used();
-