changeset 2523:bad27cd3f646

Merge
author asaha
date Thu, 21 Apr 2011 08:12:46 -0700
parents f0914807c671 (current diff) 611e19a16519 (diff)
children 5e00ed79c8bb
files
diffstat 130 files changed, 3596 insertions(+), 1751 deletions(-) [+]
line wrap: on
line diff
--- a/agent/src/share/classes/sun/jvm/hotspot/HelloWorld.java	Wed Apr 20 07:43:25 2011 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/HelloWorld.java	Thu Apr 21 08:12:46 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2001, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -55,7 +55,7 @@
     synchronized(lock) {
       if (useMethodInvoke) {
         try {
-          Method method = HelloWorld.class.getMethod("e", null);
+          Method method = HelloWorld.class.getMethod("e");
           Integer result = (Integer) method.invoke(null, new Object[0]);
           return result.intValue();
         }
--- a/agent/src/share/classes/sun/jvm/hotspot/jdi/ByteValueImpl.java	Wed Apr 20 07:43:25 2011 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/jdi/ByteValueImpl.java	Thu Apr 21 08:12:46 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -52,12 +52,10 @@
         return intValue();
     }
 
-    public int compareTo(Object obj) {
-        byte other = ((ByteValue)obj).value();
-        return value() - other;
+    public int compareTo(ByteValue byteVal) {
+        return value() - byteVal.value();
     }
 
-
     public Type type() {
         return vm.theByteType();
     }
--- a/agent/src/share/classes/sun/jvm/hotspot/jdi/CharValueImpl.java	Wed Apr 20 07:43:25 2011 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/jdi/CharValueImpl.java	Thu Apr 21 08:12:46 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -52,9 +52,8 @@
         return intValue();
     }
 
-    public int compareTo(Object obj) {
-        char other = ((CharValue)obj).value();
-        return value() - other;
+    public int compareTo(CharValue charVal) {
+        return value() - charVal.value();
     }
 
     public Type type() {
--- a/agent/src/share/classes/sun/jvm/hotspot/jdi/ConnectorImpl.java	Wed Apr 20 07:43:25 2011 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/jdi/ConnectorImpl.java	Thu Apr 21 08:12:46 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2004, 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
@@ -186,7 +186,7 @@
         // assert isVMVersionMismatch(throwable), "not a VMVersionMismatch"
         Class expClass = throwable.getClass();
         Method targetVersionMethod = expClass.getMethod("getTargetVersion", new Class[0]);
-        return (String) targetVersionMethod.invoke(throwable, null);
+        return (String) targetVersionMethod.invoke(throwable);
     }
 
     /** If the causal chain has a sun.jvm.hotspot.runtime.VMVersionMismatchException,
--- a/agent/src/share/classes/sun/jvm/hotspot/jdi/DoubleValueImpl.java	Wed Apr 20 07:43:25 2011 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/jdi/DoubleValueImpl.java	Thu Apr 21 08:12:46 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -45,8 +45,8 @@
         }
     }
 
-    public int compareTo(Object obj) {
-        double other = ((DoubleValue)obj).value();
+    public int compareTo(DoubleValue doubleVal) {
+        double other = doubleVal.value();
         if (value() < other) {
             return -1;
         } else if (value() == other) {
--- a/agent/src/share/classes/sun/jvm/hotspot/jdi/FieldImpl.java	Wed Apr 20 07:43:25 2011 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/jdi/FieldImpl.java	Thu Apr 21 08:12:46 2011 -0700
@@ -145,8 +145,7 @@
     }
 
     // From interface Comparable
-    public int compareTo(Object object) {
-        Field field = (Field)object;
+    public int compareTo(Field field) {
         ReferenceTypeImpl declaringType = (ReferenceTypeImpl)declaringType();
         int rc = declaringType.compareTo(field.declaringType());
         if (rc == 0) {
--- a/agent/src/share/classes/sun/jvm/hotspot/jdi/FloatValueImpl.java	Wed Apr 20 07:43:25 2011 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/jdi/FloatValueImpl.java	Thu Apr 21 08:12:46 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -52,8 +52,8 @@
         return intValue();
     }
 
-    public int compareTo(Object obj) {
-        float other = ((FloatValue)obj).value();
+    public int compareTo(FloatValue floatVal) {
+        float other = floatVal.value();
         if (value() < other) {
             return -1;
         } else if (value() == other) {
--- a/agent/src/share/classes/sun/jvm/hotspot/jdi/IntegerValueImpl.java	Wed Apr 20 07:43:25 2011 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/jdi/IntegerValueImpl.java	Thu Apr 21 08:12:46 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -52,9 +52,8 @@
         return intValue();
     }
 
-    public int compareTo(Object obj) {
-        int other = ((IntegerValue)obj).value();
-        return value() - other;
+    public int compareTo(IntegerValue integerVal) {
+        return value() - integerVal.value();
     }
 
     public Type type() {
--- a/agent/src/share/classes/sun/jvm/hotspot/jdi/LocalVariableImpl.java	Wed Apr 20 07:43:25 2011 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/jdi/LocalVariableImpl.java	Thu Apr 21 08:12:46 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2004, 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
@@ -67,8 +67,8 @@
         return (int)method.hashCode() + slot();
     }
 
-    public int compareTo(Object object) {
-        LocalVariableImpl other = (LocalVariableImpl)object;
+    public int compareTo(LocalVariable localVar) {
+        LocalVariableImpl other = (LocalVariableImpl) localVar;
         int rc = method.compareTo(other.method);
         if (rc == 0) {
             rc = slot() - other.slot();
--- a/agent/src/share/classes/sun/jvm/hotspot/jdi/LocationImpl.java	Wed Apr 20 07:43:25 2011 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/jdi/LocationImpl.java	Thu Apr 21 08:12:46 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -78,8 +78,7 @@
         return method().hashCode() + (int)codeIndex();
     }
 
-    public int compareTo(Object object) {
-        LocationImpl other = (LocationImpl)object;
+    public int compareTo(Location other) {
         int rc = method().compareTo(other.method());
         if (rc == 0) {
             long diff = codeIndex() - other.codeIndex();
--- a/agent/src/share/classes/sun/jvm/hotspot/jdi/LongValueImpl.java	Wed Apr 20 07:43:25 2011 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/jdi/LongValueImpl.java	Thu Apr 21 08:12:46 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -52,8 +52,8 @@
         return intValue();
     }
 
-    public int compareTo(Object obj) {
-        long other = ((LongValue)obj).value();
+    public int compareTo(LongValue longVal) {
+        long other = longVal.value();
         if (value() < other) {
             return -1;
         } else if (value() == other) {
--- a/agent/src/share/classes/sun/jvm/hotspot/jdi/MethodImpl.java	Wed Apr 20 07:43:25 2011 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/jdi/MethodImpl.java	Thu Apr 21 08:12:46 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2005, 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
@@ -200,8 +200,7 @@
     }
 
     // From interface Comparable
-    public int compareTo(Object object) {
-      Method method = (Method)object;
+    public int compareTo(Method method) {
         ReferenceTypeImpl declaringType = (ReferenceTypeImpl)declaringType();
          int rc = declaringType.compareTo(method.declaringType());
          if (rc == 0) {
--- a/agent/src/share/classes/sun/jvm/hotspot/jdi/ReferenceTypeImpl.java	Wed Apr 20 07:43:25 2011 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/jdi/ReferenceTypeImpl.java	Thu Apr 21 08:12:46 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2005, 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
@@ -99,7 +99,7 @@
         return saKlass.hashCode();
     }
 
-    public int compareTo(Object object) {
+    public int compareTo(ReferenceType refType) {
         /*
          * Note that it is critical that compareTo() == 0
          * implies that equals() == true. Otherwise, TreeSet
@@ -108,7 +108,7 @@
          * (Classes of the same name loaded by different class loaders
          * or in different VMs must not return 0).
          */
-        ReferenceTypeImpl other = (ReferenceTypeImpl)object;
+        ReferenceTypeImpl other = (ReferenceTypeImpl)refType;
         int comp = name().compareTo(other.name());
         if (comp == 0) {
             Oop rf1 = ref();
--- a/agent/src/share/classes/sun/jvm/hotspot/jdi/ShortValueImpl.java	Wed Apr 20 07:43:25 2011 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/jdi/ShortValueImpl.java	Thu Apr 21 08:12:46 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -52,9 +52,8 @@
         return intValue();
     }
 
-    public int compareTo(Object obj) {
-        short other = ((ShortValue)obj).value();
-        return value() - other;
+    public int compareTo(ShortValue shortVal) {
+        return value() - shortVal.value();
     }
 
     public Type type() {
--- a/agent/src/share/classes/sun/jvm/hotspot/jdi/VirtualMachineImpl.java	Wed Apr 20 07:43:25 2011 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/jdi/VirtualMachineImpl.java	Thu Apr 21 08:12:46 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2006, 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
@@ -798,12 +798,11 @@
     }
 
     public String description() {
-        String[] versionParts = {"" + vmmgr.majorInterfaceVersion(),
-                                 "" + vmmgr.minorInterfaceVersion(),
-                                 name()};
         return java.text.MessageFormat.format(java.util.ResourceBundle.
                                               getBundle("com.sun.tools.jdi.resources.jdi").getString("version_format"),
-                                              versionParts);
+                                              "" + vmmgr.majorInterfaceVersion(),
+                                              "" + vmmgr.minorInterfaceVersion(),
+                                              name());
     }
 
     public String version() {
--- a/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPool.java	Wed Apr 20 07:43:25 2011 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPool.java	Thu Apr 21 08:12:46 2011 -0700
@@ -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/runtime/ClassConstants.java	Wed Apr 20 07:43:25 2011 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java	Thu Apr 21 08:12:46 2011 -0700
@@ -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/tools/jcore/ClassWriter.java	Wed Apr 20 07:43:25 2011 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java	Thu Apr 21 08:12:46 2011 -0700
@@ -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/ui/classbrowser/HTMLGenerator.java	Wed Apr 20 07:43:25 2011 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java	Thu Apr 21 08:12:46 2011 -0700
@@ -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	Wed Apr 20 07:43:25 2011 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/utilities/ConstantTag.java	Thu Apr 21 08:12:46 2011 -0700
@@ -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/make/hotspot_version	Wed Apr 20 07:43:25 2011 -0700
+++ b/make/hotspot_version	Thu Apr 21 08:12:46 2011 -0700
@@ -35,7 +35,7 @@
 
 HS_MAJOR_VER=21
 HS_MINOR_VER=0
-HS_BUILD_NUMBER=08
+HS_BUILD_NUMBER=09
 
 JDK_MAJOR_VER=1
 JDK_MINOR_VER=7
--- a/make/linux/makefiles/sa.make	Wed Apr 20 07:43:25 2011 -0700
+++ b/make/linux/makefiles/sa.make	Thu Apr 21 08:12:46 2011 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -97,8 +97,8 @@
 	$(foreach file,$(AGENT_FILES1),$(shell echo $(file) >> $(AGENT_FILES1_LIST)))
 	$(foreach file,$(AGENT_FILES2),$(shell echo $(file) >> $(AGENT_FILES2_LIST)))
 	
-	$(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) -source 1.4 -target 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) @$(AGENT_FILES1_LIST)
-	$(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) -source 1.4 -target 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) @$(AGENT_FILES2_LIST)
+	$(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) @$(AGENT_FILES1_LIST)
+	$(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) @$(AGENT_FILES2_LIST)
 	
 	$(QUIETLY) $(REMOTE) $(COMPILE.RMIC)  -classpath $(SA_CLASSDIR) -d $(SA_CLASSDIR) sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer
 	$(QUIETLY) echo "$(SA_BUILD_VERSION_PROP)" > $(SA_PROPERTIES)
--- a/make/linux/makefiles/vm.make	Wed Apr 20 07:43:25 2011 -0700
+++ b/make/linux/makefiles/vm.make	Thu Apr 21 08:12:46 2011 -0700
@@ -142,13 +142,15 @@
 COMPILER2_PATHS += $(HS_COMMON_SRC)/share/vm/libadt
 COMPILER2_PATHS += $(GENERATED)/adfiles
 
+SHARK_PATHS := $(GAMMADIR)/src/share/vm/shark
+
 # Include dirs per type.
 Src_Dirs/CORE      := $(CORE_PATHS)
 Src_Dirs/COMPILER1 := $(CORE_PATHS) $(COMPILER1_PATHS)
 Src_Dirs/COMPILER2 := $(CORE_PATHS) $(COMPILER2_PATHS)
 Src_Dirs/TIERED    := $(CORE_PATHS) $(COMPILER1_PATHS) $(COMPILER2_PATHS)
 Src_Dirs/ZERO      := $(CORE_PATHS)
-Src_Dirs/SHARK     := $(CORE_PATHS)
+Src_Dirs/SHARK     := $(CORE_PATHS) $(SHARK_PATHS)
 Src_Dirs := $(Src_Dirs/$(TYPE))
 
 COMPILER2_SPECIFIC_FILES := opto libadt bcEscapeAnalyzer.cpp chaitin\* c2_\* runtime_\*
--- a/make/solaris/makefiles/sa.make	Wed Apr 20 07:43:25 2011 -0700
+++ b/make/solaris/makefiles/sa.make	Thu Apr 21 08:12:46 2011 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -88,8 +88,8 @@
 	$(foreach file,$(AGENT_FILES1),$(shell echo $(file) >> $(AGENT_FILES1_LIST)))
 	$(foreach file,$(AGENT_FILES2),$(shell echo $(file) >> $(AGENT_FILES2_LIST)))
 	
-	$(QUIETLY) $(COMPILE.JAVAC) -source 1.4 -target 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) @$(AGENT_FILES1_LIST)
-	$(QUIETLY) $(COMPILE.JAVAC) -source 1.4 -target 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) @$(AGENT_FILES2_LIST)
+	$(QUIETLY) $(COMPILE.JAVAC) -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) @$(AGENT_FILES1_LIST)
+	$(QUIETLY) $(COMPILE.JAVAC) -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) @$(AGENT_FILES2_LIST)
 	
 	$(QUIETLY) $(COMPILE.RMIC)  -classpath $(SA_CLASSDIR) -d $(SA_CLASSDIR) sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer
 	$(QUIETLY) echo "$(SA_BUILD_VERSION_PROP)" > $(SA_PROPERTIES)
--- a/make/windows/makefiles/sa.make	Wed Apr 20 07:43:25 2011 -0700
+++ b/make/windows/makefiles/sa.make	Thu Apr 21 08:12:46 2011 -0700
@@ -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
@@ -55,9 +55,9 @@
 $(GENERATED)\sa-jdi.jar: $(AGENT_FILES1:/=\) $(AGENT_FILES2:/=\)
 	@if not exist $(SA_CLASSDIR) mkdir $(SA_CLASSDIR)
 	@echo ...Building sa-jdi.jar
-	@echo ...$(COMPILE_JAVAC) -source 1.4 -target 1.4 -classpath $(SA_CLASSPATH) -d $(SA_CLASSDIR) ....
-	@$(COMPILE_JAVAC) -source 1.4 -target 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) $(AGENT_FILES1:/=\)
-	@$(COMPILE_JAVAC) -source 1.4 -target 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) $(AGENT_FILES2:/=\)
+	@echo ...$(COMPILE_JAVAC) -classpath $(SA_CLASSPATH) -d $(SA_CLASSDIR) ....
+	@$(COMPILE_JAVAC) -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) $(AGENT_FILES1:/=\)
+	@$(COMPILE_JAVAC) -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) $(AGENT_FILES2:/=\)
 	$(COMPILE_RMIC) -classpath $(SA_CLASSDIR) -d $(SA_CLASSDIR) sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer
 	$(QUIETLY) echo $(SA_BUILD_VERSION_PROP)> $(SA_PROPERTIES)
 	$(QUIETLY) rm -f $(SA_CLASSDIR)/sun/jvm/hotspot/utilities/soql/sa.js
--- a/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -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	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -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/x86/vm/assembler_x86.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/cpu/x86/vm/assembler_x86.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -2317,7 +2317,7 @@
 }
 
 void Assembler::prefetchr(Address src) {
-  NOT_LP64(assert(VM_Version::supports_3dnow(), "must support"));
+  NOT_LP64(assert(VM_Version::supports_3dnow_prefetch(), "must support"));
   InstructionMark im(this);
   prefetch_prefix(src);
   emit_byte(0x0D);
@@ -2349,7 +2349,7 @@
 }
 
 void Assembler::prefetchw(Address src) {
-  NOT_LP64(assert(VM_Version::supports_3dnow(), "must support"));
+  NOT_LP64(assert(VM_Version::supports_3dnow_prefetch(), "must support"));
   InstructionMark im(this);
   prefetch_prefix(src);
   emit_byte(0x0D);
@@ -7941,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);
   }
@@ -8396,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) {
--- a/src/cpu/x86/vm/assembler_x86.hpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/cpu/x86/vm/assembler_x86.hpp	Thu Apr 21 08:12:46 2011 -0700
@@ -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)) {}
 
 };
 
@@ -1701,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
--- a/src/cpu/x86/vm/c1_CodeStubs_x86.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/cpu/x86/vm/c1_CodeStubs_x86.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -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	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -1401,7 +1401,7 @@
       default:
         ShouldNotReachHere(); break;
     }
-  } else if (VM_Version::supports_3dnow()) {
+  } else if (VM_Version::supports_3dnow_prefetch()) {
     __ prefetchr(from_addr);
   }
 }
@@ -1424,7 +1424,7 @@
       default:
         ShouldNotReachHere(); break;
     }
-  } else if (VM_Version::supports_3dnow()) {
+  } else if (VM_Version::supports_3dnow_prefetch()) {
     __ prefetchw(from_addr);
   }
 }
@@ -3102,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
@@ -3123,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
@@ -3141,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);
@@ -3153,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));
@@ -3167,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());
@@ -3226,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));
@@ -3242,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
@@ -3291,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);
 
@@ -3311,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/vm_version_x86.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/cpu/x86/vm/vm_version_x86.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -348,7 +348,7 @@
   }
 
   char buf[256];
-  jio_snprintf(buf, sizeof(buf), "(%u cores per cpu, %u threads per core) family %d model %d stepping %d%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
+  jio_snprintf(buf, sizeof(buf), "(%u cores per cpu, %u threads per core) family %d model %d stepping %d%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
                cores_per_cpu(), threads_per_core(),
                cpu_family(), _model, _stepping,
                (supports_cmov() ? ", cmov" : ""),
@@ -363,8 +363,7 @@
                (supports_sse4_2() ? ", sse4.2" : ""),
                (supports_popcnt() ? ", popcnt" : ""),
                (supports_mmx_ext() ? ", mmxext" : ""),
-               (supports_3dnow()   ? ", 3dnow"  : ""),
-               (supports_3dnow2()  ? ", 3dnowext" : ""),
+               (supports_3dnow_prefetch() ? ", 3dnowpref" : ""),
                (supports_lzcnt()   ? ", lzcnt": ""),
                (supports_sse4a()   ? ", sse4a": ""),
                (supports_ht() ? ", ht": ""));
@@ -522,13 +521,13 @@
   // set valid Prefetch instruction
   if( ReadPrefetchInstr < 0 ) ReadPrefetchInstr = 0;
   if( ReadPrefetchInstr > 3 ) ReadPrefetchInstr = 3;
-  if( ReadPrefetchInstr == 3 && !supports_3dnow() ) ReadPrefetchInstr = 0;
-  if( !supports_sse() && supports_3dnow() ) ReadPrefetchInstr = 3;
+  if( ReadPrefetchInstr == 3 && !supports_3dnow_prefetch() ) ReadPrefetchInstr = 0;
+  if( !supports_sse() && supports_3dnow_prefetch() ) ReadPrefetchInstr = 3;
 
   if( AllocatePrefetchInstr < 0 ) AllocatePrefetchInstr = 0;
   if( AllocatePrefetchInstr > 3 ) AllocatePrefetchInstr = 3;
-  if( AllocatePrefetchInstr == 3 && !supports_3dnow() ) AllocatePrefetchInstr=0;
-  if( !supports_sse() && supports_3dnow() ) AllocatePrefetchInstr = 3;
+  if( AllocatePrefetchInstr == 3 && !supports_3dnow_prefetch() ) AllocatePrefetchInstr=0;
+  if( !supports_sse() && supports_3dnow_prefetch() ) AllocatePrefetchInstr = 3;
 
   // Allocation prefetch settings
   intx cache_line_size = L1_data_cache_line_size();
@@ -576,10 +575,10 @@
                   logical_processors_per_package());
     tty->print_cr("UseSSE=%d",UseSSE);
     tty->print("Allocation: ");
-    if (AllocatePrefetchStyle <= 0 || UseSSE == 0 && !supports_3dnow()) {
+    if (AllocatePrefetchStyle <= 0 || UseSSE == 0 && !supports_3dnow_prefetch()) {
       tty->print_cr("no prefetching");
     } else {
-      if (UseSSE == 0 && supports_3dnow()) {
+      if (UseSSE == 0 && supports_3dnow_prefetch()) {
         tty->print("PREFETCHW");
       } else if (UseSSE >= 1) {
         if (AllocatePrefetchInstr == 0) {
--- a/src/cpu/x86/vm/vm_version_x86.hpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/cpu/x86/vm/vm_version_x86.hpp	Thu Apr 21 08:12:46 2011 -0700
@@ -188,7 +188,8 @@
      CPU_FXSR   = (1 << 2),
      CPU_HT     = (1 << 3),
      CPU_MMX    = (1 << 4),
-     CPU_3DNOW  = (1 << 5), // 3DNow comes from cpuid 0x80000001 (EDX)
+     CPU_3DNOW_PREFETCH  = (1 << 5), // Processor supports 3dnow prefetch and prefetchw instructions
+                                     // may not necessarily support other 3dnow instructions
      CPU_SSE    = (1 << 6),
      CPU_SSE2   = (1 << 7),
      CPU_SSE3   = (1 << 8), // SSE3 comes from cpuid 1 (ECX)
@@ -328,8 +329,9 @@
 
     // AMD features.
     if (is_amd()) {
-      if (_cpuid_info.ext_cpuid1_edx.bits.tdnow != 0)
-        result |= CPU_3DNOW;
+      if ((_cpuid_info.ext_cpuid1_edx.bits.tdnow != 0) ||
+          (_cpuid_info.ext_cpuid1_ecx.bits.prefetchw != 0))
+        result |= CPU_3DNOW_PREFETCH;
       if (_cpuid_info.ext_cpuid1_ecx.bits.lzcnt != 0)
         result |= CPU_LZCNT;
       if (_cpuid_info.ext_cpuid1_ecx.bits.sse4a != 0)
@@ -446,9 +448,8 @@
   //
   // AMD features
   //
-  static bool supports_3dnow()    { return (_cpuFeatures & CPU_3DNOW) != 0; }
+  static bool supports_3dnow_prefetch()    { return (_cpuFeatures & CPU_3DNOW_PREFETCH) != 0; }
   static bool supports_mmx_ext()  { return is_amd() && _cpuid_info.ext_cpuid1_edx.bits.mmx_amd != 0; }
-  static bool supports_3dnow2()   { return is_amd() && _cpuid_info.ext_cpuid1_edx.bits.tdnow2 != 0; }
   static bool supports_lzcnt()    { return (_cpuFeatures & CPU_LZCNT) != 0; }
   static bool supports_sse4a()    { return (_cpuFeatures & CPU_SSE4A) != 0; }
 
--- a/src/cpu/x86/vm/x86_32.ad	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/cpu/x86/vm/x86_32.ad	Thu Apr 21 08:12:46 2011 -0700
@@ -3423,7 +3423,7 @@
          masm.movptr(boxReg, tmpReg);                   // consider: LEA box, [tmp-2] 
 
          // Using a prefetchw helps avoid later RTS->RTO upgrades and cache probes
-         if ((EmitSync & 2048) && VM_Version::supports_3dnow() && os::is_MP()) {
+         if ((EmitSync & 2048) && VM_Version::supports_3dnow_prefetch() && os::is_MP()) {
             // prefetchw [eax + Offset(_owner)-2]
             masm.prefetchw(Address(rax, ObjectMonitor::owner_offset_in_bytes()-2));
          }
@@ -3467,7 +3467,7 @@
          masm.movptr(boxReg, tmpReg) ; 
 
          // Using a prefetchw helps avoid later RTS->RTO upgrades and cache probes
-         if ((EmitSync & 2048) && VM_Version::supports_3dnow() && os::is_MP()) {
+         if ((EmitSync & 2048) && VM_Version::supports_3dnow_prefetch() && os::is_MP()) {
             // prefetchw [eax + Offset(_owner)-2]
             masm.prefetchw(Address(rax, ObjectMonitor::owner_offset_in_bytes()-2));
          }
@@ -3614,7 +3614,7 @@
       // See also http://gee.cs.oswego.edu/dl/jmm/cookbook.html.
 
       masm.get_thread (boxReg) ;
-      if ((EmitSync & 4096) && VM_Version::supports_3dnow() && os::is_MP()) {
+      if ((EmitSync & 4096) && VM_Version::supports_3dnow_prefetch() && os::is_MP()) {
         // prefetchw [ebx + Offset(_owner)-2]
         masm.prefetchw(Address(rbx, ObjectMonitor::owner_offset_in_bytes()-2));
       }
@@ -7333,7 +7333,7 @@
 // Must be safe to execute with invalid address (cannot fault).
 
 instruct prefetchr0( memory mem ) %{
-  predicate(UseSSE==0 && !VM_Version::supports_3dnow());
+  predicate(UseSSE==0 && !VM_Version::supports_3dnow_prefetch());
   match(PrefetchRead mem);
   ins_cost(0);
   size(0);
@@ -7343,7 +7343,7 @@
 %}
 
 instruct prefetchr( memory mem ) %{
-  predicate(UseSSE==0 && VM_Version::supports_3dnow() || ReadPrefetchInstr==3);
+  predicate(UseSSE==0 && VM_Version::supports_3dnow_prefetch() || ReadPrefetchInstr==3);
   match(PrefetchRead mem);
   ins_cost(100);
 
@@ -7387,7 +7387,7 @@
 %}
 
 instruct prefetchw0( memory mem ) %{
-  predicate(UseSSE==0 && !VM_Version::supports_3dnow());
+  predicate(UseSSE==0 && !VM_Version::supports_3dnow_prefetch());
   match(PrefetchWrite mem);
   ins_cost(0);
   size(0);
@@ -7397,7 +7397,7 @@
 %}
 
 instruct prefetchw( memory mem ) %{
-  predicate(UseSSE==0 && VM_Version::supports_3dnow() || AllocatePrefetchInstr==3);
+  predicate(UseSSE==0 && VM_Version::supports_3dnow_prefetch() || AllocatePrefetchInstr==3);
   match( PrefetchWrite mem );
   ins_cost(100);
 
--- a/src/cpu/zero/vm/bytecodeInterpreter_zero.hpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/cpu/zero/vm/bytecodeInterpreter_zero.hpp	Thu Apr 21 08:12:46 2011 -0700
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2007, 2008 Red Hat, Inc.
+ * Copyright 2007, 2008, 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
@@ -150,4 +150,22 @@
 #define SET_LOCALS_LONG_FROM_ADDR(addr, offset) (((VMJavaVal64*)&locals[-((offset)+1)])->l = \
                                                 ((VMJavaVal64*)(addr))->l)
 
+// VMSlots implementation
+
+#define VMSLOTS_SLOT(offset)    ((intptr_t*)&vmslots[(offset)])
+#define VMSLOTS_ADDR(offset)    ((address)vmslots[(offset)])
+#define VMSLOTS_INT(offset)     (*((jint*)&vmslots[(offset)]))
+#define VMSLOTS_FLOAT(offset)   (*((jfloat*)&vmslots[(offset)]))
+#define VMSLOTS_OBJECT(offset)  ((oop)vmslots[(offset)])
+#define VMSLOTS_DOUBLE(offset)  (((VMJavaVal64*)&vmslots[(offset) - 1])->d)
+#define VMSLOTS_LONG(offset)    (((VMJavaVal64*)&vmslots[(offset) - 1])->l)
+
+#define SET_VMSLOTS_SLOT(value, offset)   (*(intptr_t*)&vmslots[(offset)] = *(intptr_t *)(value))
+#define SET_VMSLOTS_ADDR(value, offset)   (*((address *)&vmslots[(offset)]) = (value))
+#define SET_VMSLOTS_INT(value, offset)    (*((jint *)&vmslots[(offset)]) = (value))
+#define SET_VMSLOTS_FLOAT(value, offset)  (*((jfloat *)&vmslots[(offset)]) = (value))
+#define SET_VMSLOTS_OBJECT(value, offset) (*((oop *)&vmslots[(offset)]) = (value))
+#define SET_VMSLOTS_DOUBLE(value, offset) (((VMJavaVal64*)&vmslots[(offset) - 1])->d = (value))
+#define SET_VMSLOTS_LONG(value, offset)   (((VMJavaVal64*)&vmslots[(offset) - 1])->l = (value))
+
 #endif // CPU_ZERO_VM_BYTECODEINTERPRETER_ZERO_HPP
--- a/src/cpu/zero/vm/cppInterpreter_zero.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/cpu/zero/vm/cppInterpreter_zero.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2003, 2011, 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
@@ -56,10 +56,13 @@
 #define fixup_after_potential_safepoint()       \
   method = istate->method()
 
-#define CALL_VM_NOCHECK(func)                   \
+#define CALL_VM_NOCHECK_NOFIX(func)             \
   thread->set_last_Java_frame();                \
   func;                                         \
-  thread->reset_last_Java_frame();              \
+  thread->reset_last_Java_frame();
+
+#define CALL_VM_NOCHECK(func)                   \
+  CALL_VM_NOCHECK_NOFIX(func)                   \
   fixup_after_potential_safepoint()
 
 int CppInterpreter::normal_entry(methodOop method, intptr_t UNUSED, TRAPS) {
@@ -177,6 +180,25 @@
         method, istate->osr_entry(), istate->osr_buf(), THREAD);
       return;
     }
+    else if (istate->msg() == BytecodeInterpreter::call_method_handle) {
+      oop method_handle = istate->callee();
+
+      // Trim back the stack to put the parameters at the top
+      stack->set_sp(istate->stack() + 1);
+
+      // Make the call
+      process_method_handle(method_handle, THREAD);
+      fixup_after_potential_safepoint();
+
+      // Convert the result
+      istate->set_stack(stack->sp() - 1);
+
+      // Restore the stack
+      stack->set_sp(istate->stack_limit() + 1);
+
+      // Resume the interpreter
+      istate->set_msg(BytecodeInterpreter::method_resume);
+    }
     else {
       ShouldNotReachHere();
     }
@@ -607,6 +629,549 @@
   return 0;
 }
 
+int CppInterpreter::method_handle_entry(methodOop method,
+                                        intptr_t UNUSED, TRAPS) {
+  JavaThread *thread = (JavaThread *) THREAD;
+  ZeroStack *stack = thread->zero_stack();
+  int argument_slots = method->size_of_parameters();
+  int result_slots = type2size[result_type_of(method)];
+  intptr_t *vmslots = stack->sp();
+  intptr_t *unwind_sp = vmslots + argument_slots;
+
+  // Find the MethodType
+  address p = (address) method;
+  for (jint* pc = method->method_type_offsets_chain(); (*pc) != -1; pc++) {
+    p = *(address*)(p + (*pc));
+  }
+  oop method_type = (oop) p;
+
+  // The MethodHandle is in the slot after the arguments
+  oop form = java_lang_invoke_MethodType::form(method_type);
+  int num_vmslots = java_lang_invoke_MethodTypeForm::vmslots(form);
+  assert(argument_slots == num_vmslots + 1, "should be");
+  oop method_handle = VMSLOTS_OBJECT(num_vmslots);
+
+  // InvokeGeneric requires some extra shuffling
+  oop mhtype = java_lang_invoke_MethodHandle::type(method_handle);
+  bool is_exact = mhtype == method_type;
+  if (!is_exact) {
+    if (method->intrinsic_id() == vmIntrinsics::_invokeExact) {
+      CALL_VM_NOCHECK_NOFIX(
+        InterpreterRuntime::throw_WrongMethodTypeException(
+          thread, method_type, mhtype));
+      // NB all oops trashed!
+      assert(HAS_PENDING_EXCEPTION, "should do");
+      stack->set_sp(unwind_sp);
+      return 0;
+    }
+    assert(method->intrinsic_id() == vmIntrinsics::_invokeGeneric, "should be");
+
+    // Load up an adapter from the calling type
+    // NB the x86 code for this (in methodHandles_x86.cpp, search for
+    // "genericInvoker") is really really odd.  I'm hoping it's trying
+    // to accomodate odd VM/class library combinations I can ignore.
+    oop adapter = java_lang_invoke_MethodTypeForm::genericInvoker(form);
+    if (adapter == NULL) {
+      CALL_VM_NOCHECK_NOFIX(
+        InterpreterRuntime::throw_WrongMethodTypeException(
+          thread, method_type, mhtype));
+      // NB all oops trashed!
+      assert(HAS_PENDING_EXCEPTION, "should do");
+      stack->set_sp(unwind_sp);
+      return 0;
+    }
+
+    // Adapters are shared among form-families of method-type.  The
+    // type being called is passed as a trusted first argument so that
+    // the adapter knows the actual types of its arguments and return
+    // values.
+    insert_vmslots(num_vmslots + 1, 1, THREAD);
+    if (HAS_PENDING_EXCEPTION) {
+      // NB all oops trashed!
+      stack->set_sp(unwind_sp);
+      return 0;
+    }
+
+    vmslots = stack->sp();
+    num_vmslots++;
+    SET_VMSLOTS_OBJECT(method_type, num_vmslots);
+
+    method_handle = adapter;
+  }
+
+  // Start processing
+  process_method_handle(method_handle, THREAD);
+  if (HAS_PENDING_EXCEPTION)
+    result_slots = 0;
+
+  // If this is an invokeExact then the eventual callee will not
+  // have unwound the method handle argument so we have to do it.
+  // If a result is being returned the it will be above the method
+  // handle argument we're unwinding.
+  if (is_exact) {
+    intptr_t result[2];
+    for (int i = 0; i < result_slots; i++)
+      result[i] = stack->pop();
+    stack->pop();
+    for (int i = result_slots - 1; i >= 0; i--)
+      stack->push(result[i]);
+  }
+
+  // Check
+  assert(stack->sp() == unwind_sp - result_slots, "should be");
+
+  // No deoptimized frames on the stack
+  return 0;
+}
+
+void CppInterpreter::process_method_handle(oop method_handle, TRAPS) {
+  JavaThread *thread = (JavaThread *) THREAD;
+  ZeroStack *stack = thread->zero_stack();
+  intptr_t *vmslots = stack->sp();
+
+  bool direct_to_method = false;
+  BasicType src_rtype = T_ILLEGAL;
+  BasicType dst_rtype = T_ILLEGAL;
+
+  MethodHandleEntry *entry =
+    java_lang_invoke_MethodHandle::vmentry(method_handle);
+  MethodHandles::EntryKind entry_kind =
+    (MethodHandles::EntryKind) (((intptr_t) entry) & 0xffffffff);
+
+  methodOop method = NULL;
+  switch (entry_kind) {
+  case MethodHandles::_invokestatic_mh:
+    direct_to_method = true;
+    break;
+
+  case MethodHandles::_invokespecial_mh:
+  case MethodHandles::_invokevirtual_mh:
+  case MethodHandles::_invokeinterface_mh:
+    {
+      oop receiver =
+        VMSLOTS_OBJECT(
+          java_lang_invoke_MethodHandle::vmslots(method_handle) - 1);
+      if (receiver == NULL) {
+          stack->set_sp(calculate_unwind_sp(stack, method_handle));
+          CALL_VM_NOCHECK_NOFIX(
+            throw_exception(
+              thread, vmSymbols::java_lang_NullPointerException()));
+          // NB all oops trashed!
+          assert(HAS_PENDING_EXCEPTION, "should do");
+          return;
+      }
+      if (entry_kind != MethodHandles::_invokespecial_mh) {
+        int index = java_lang_invoke_DirectMethodHandle::vmindex(method_handle);
+        instanceKlass* rcvrKlass =
+          (instanceKlass *) receiver->klass()->klass_part();
+        if (entry_kind == MethodHandles::_invokevirtual_mh) {
+          method = (methodOop) rcvrKlass->start_of_vtable()[index];
+        }
+        else {
+          oop iclass = java_lang_invoke_MethodHandle::vmtarget(method_handle);
+          itableOffsetEntry* ki =
+            (itableOffsetEntry *) rcvrKlass->start_of_itable();
+          int i, length = rcvrKlass->itable_length();
+          for (i = 0; i < length; i++, ki++ ) {
+            if (ki->interface_klass() == iclass)
+              break;
+          }
+          if (i == length) {
+            stack->set_sp(calculate_unwind_sp(stack, method_handle));
+            CALL_VM_NOCHECK_NOFIX(
+              throw_exception(
+                thread, vmSymbols::java_lang_IncompatibleClassChangeError()));
+            // NB all oops trashed!
+            assert(HAS_PENDING_EXCEPTION, "should do");
+            return;
+          }
+          itableMethodEntry* im = ki->first_method_entry(receiver->klass());
+          method = im[index].method();
+          if (method == NULL) {
+            stack->set_sp(calculate_unwind_sp(stack, method_handle));
+            CALL_VM_NOCHECK_NOFIX(
+              throw_exception(
+                thread, vmSymbols::java_lang_AbstractMethodError()));
+            // NB all oops trashed!
+            assert(HAS_PENDING_EXCEPTION, "should do");
+            return;
+          }
+        }
+      }
+    }
+    direct_to_method = true;
+    break;
+
+  case MethodHandles::_bound_ref_direct_mh:
+  case MethodHandles::_bound_int_direct_mh:
+  case MethodHandles::_bound_long_direct_mh:
+    direct_to_method = true;
+    // fall through
+  case MethodHandles::_bound_ref_mh:
+  case MethodHandles::_bound_int_mh:
+  case MethodHandles::_bound_long_mh:
+    {
+      BasicType arg_type  = T_ILLEGAL;
+      int       arg_mask  = -1;
+      int       arg_slots = -1;
+      MethodHandles::get_ek_bound_mh_info(
+        entry_kind, arg_type, arg_mask, arg_slots);
+      int arg_slot =
+        java_lang_invoke_BoundMethodHandle::vmargslot(method_handle);
+
+      // Create the new slot(s)
+      intptr_t *unwind_sp = calculate_unwind_sp(stack, method_handle);
+      insert_vmslots(arg_slot, arg_slots, THREAD);
+      if (HAS_PENDING_EXCEPTION) {
+        // all oops trashed
+        stack->set_sp(unwind_sp);
+        return;
+      }
+      vmslots = stack->sp();
+
+      // Store bound argument into new stack slot
+      oop arg = java_lang_invoke_BoundMethodHandle::argument(method_handle);
+      if (arg_type == T_OBJECT) {
+        assert(arg_slots == 1, "should be");
+        SET_VMSLOTS_OBJECT(arg, arg_slot);
+      }
+      else {
+        jvalue arg_value;
+        arg_type = java_lang_boxing_object::get_value(arg, &arg_value);
+        switch (arg_type) {
+        case T_BOOLEAN:
+          SET_VMSLOTS_INT(arg_value.z, arg_slot);
+          break;
+        case T_CHAR:
+          SET_VMSLOTS_INT(arg_value.c, arg_slot);
+          break;
+        case T_BYTE:
+          SET_VMSLOTS_INT(arg_value.b, arg_slot);
+          break;
+        case T_SHORT:
+          SET_VMSLOTS_INT(arg_value.s, arg_slot);
+          break;
+        case T_INT:
+          SET_VMSLOTS_INT(arg_value.i, arg_slot);
+          break;
+        case T_FLOAT:
+          SET_VMSLOTS_FLOAT(arg_value.f, arg_slot);
+          break;
+        case T_LONG:
+          SET_VMSLOTS_LONG(arg_value.j, arg_slot + 1);
+          break;
+        case T_DOUBLE:
+          SET_VMSLOTS_DOUBLE(arg_value.d, arg_slot + 1);
+          break;
+        default:
+          tty->print_cr("unhandled type %s", type2name(arg_type));
+          ShouldNotReachHere();
+        }
+      }
+    }
+    break;
+
+  case MethodHandles::_adapter_retype_only:
+  case MethodHandles::_adapter_retype_raw:
+    src_rtype = result_type_of_handle(
+      java_lang_invoke_MethodHandle::vmtarget(method_handle));
+    dst_rtype = result_type_of_handle(method_handle);
+    break;
+
+  case MethodHandles::_adapter_check_cast:
+    {
+      int arg_slot =
+        java_lang_invoke_AdapterMethodHandle::vmargslot(method_handle);
+      oop arg = VMSLOTS_OBJECT(arg_slot);
+      if (arg != NULL) {
+        klassOop objKlassOop = arg->klass();
+        klassOop klassOf = java_lang_Class::as_klassOop(
+          java_lang_invoke_AdapterMethodHandle::argument(method_handle));
+
+        if (objKlassOop != klassOf &&
+            !objKlassOop->klass_part()->is_subtype_of(klassOf)) {
+          ResourceMark rm(THREAD);
+          const char* objName = Klass::cast(objKlassOop)->external_name();
+          const char* klassName = Klass::cast(klassOf)->external_name();
+          char* message = SharedRuntime::generate_class_cast_message(
+            objName, klassName);
+
+          stack->set_sp(calculate_unwind_sp(stack, method_handle));
+          CALL_VM_NOCHECK_NOFIX(
+            throw_exception(
+              thread, vmSymbols::java_lang_ClassCastException(), message));
+          // NB all oops trashed!
+          assert(HAS_PENDING_EXCEPTION, "should do");
+          return;
+        }
+      }
+    }
+    break;
+
+  case MethodHandles::_adapter_dup_args:
+    {
+      int arg_slot =
+        java_lang_invoke_AdapterMethodHandle::vmargslot(method_handle);
+      int conv =
+        java_lang_invoke_AdapterMethodHandle::conversion(method_handle);
+      int num_slots = -MethodHandles::adapter_conversion_stack_move(conv);
+      assert(num_slots > 0, "should be");
+
+      // Create the new slot(s)
+      intptr_t *unwind_sp = calculate_unwind_sp(stack, method_handle);
+      stack->overflow_check(num_slots, THREAD);
+      if (HAS_PENDING_EXCEPTION) {
+        // all oops trashed
+        stack->set_sp(unwind_sp);
+        return;
+      }
+
+      // Duplicate the arguments
+      for (int i = num_slots - 1; i >= 0; i--)
+        stack->push(*VMSLOTS_SLOT(arg_slot + i));
+
+      vmslots = stack->sp(); // unused, but let the compiler figure that out
+    }
+    break;
+
+  case MethodHandles::_adapter_drop_args:
+    {
+      int arg_slot =
+        java_lang_invoke_AdapterMethodHandle::vmargslot(method_handle);
+      int conv =
+        java_lang_invoke_AdapterMethodHandle::conversion(method_handle);
+      int num_slots = MethodHandles::adapter_conversion_stack_move(conv);
+      assert(num_slots > 0, "should be");
+
+      remove_vmslots(arg_slot, num_slots, THREAD); // doesn't trap
+      vmslots = stack->sp(); // unused, but let the compiler figure that out
+    }
+    break;
+
+  case MethodHandles::_adapter_opt_swap_1:
+  case MethodHandles::_adapter_opt_swap_2:
+  case MethodHandles::_adapter_opt_rot_1_up:
+  case MethodHandles::_adapter_opt_rot_1_down:
+  case MethodHandles::_adapter_opt_rot_2_up:
+  case MethodHandles::_adapter_opt_rot_2_down:
+    {
+      int arg1 =
+        java_lang_invoke_AdapterMethodHandle::vmargslot(method_handle);
+      int conv =
+        java_lang_invoke_AdapterMethodHandle::conversion(method_handle);
+      int arg2 = MethodHandles::adapter_conversion_vminfo(conv);
+
+      int swap_bytes = 0, rotate = 0;
+      MethodHandles::get_ek_adapter_opt_swap_rot_info(
+        entry_kind, swap_bytes, rotate);
+      int swap_slots = swap_bytes >> LogBytesPerWord;
+
+      intptr_t tmp;
+      switch (rotate) {
+      case 0: // swap
+        for (int i = 0; i < swap_slots; i++) {
+          tmp = *VMSLOTS_SLOT(arg1 + i);
+          SET_VMSLOTS_SLOT(VMSLOTS_SLOT(arg2 + i), arg1 + i);
+          SET_VMSLOTS_SLOT(&tmp, arg2 + i);
+        }
+        break;
+
+      case 1: // up
+        assert(arg1 - swap_slots > arg2, "should be");
+
+        tmp = *VMSLOTS_SLOT(arg1);
+        for (int i = arg1 - swap_slots; i >= arg2; i--)
+          SET_VMSLOTS_SLOT(VMSLOTS_SLOT(i), i + swap_slots);
+        SET_VMSLOTS_SLOT(&tmp, arg2);
+
+        break;
+
+      case -1: // down
+        assert(arg2 - swap_slots > arg1, "should be");
+
+        tmp = *VMSLOTS_SLOT(arg1);
+        for (int i = arg1 + swap_slots; i <= arg2; i++)
+          SET_VMSLOTS_SLOT(VMSLOTS_SLOT(i), i - swap_slots);
+        SET_VMSLOTS_SLOT(&tmp, arg2);
+        break;
+
+      default:
+        ShouldNotReachHere();
+      }
+    }
+    break;
+
+  case MethodHandles::_adapter_opt_i2l:
+    {
+      int arg_slot =
+        java_lang_invoke_AdapterMethodHandle::vmargslot(method_handle);
+      int arg = VMSLOTS_INT(arg_slot);
+      intptr_t *unwind_sp = calculate_unwind_sp(stack, method_handle);
+      insert_vmslots(arg_slot, 1, THREAD);
+      if (HAS_PENDING_EXCEPTION) {
+        // all oops trashed
+        stack->set_sp(unwind_sp);
+        return;
+      }
+      vmslots = stack->sp();
+      arg_slot++;
+      SET_VMSLOTS_LONG(arg, arg_slot);
+    }
+    break;
+
+  case MethodHandles::_adapter_opt_unboxi:
+  case MethodHandles::_adapter_opt_unboxl:
+    {
+      int arg_slot =
+        java_lang_invoke_AdapterMethodHandle::vmargslot(method_handle);
+      oop arg = VMSLOTS_OBJECT(arg_slot);
+      jvalue arg_value;
+      BasicType arg_type = java_lang_boxing_object::get_value(arg, &arg_value);
+      if (arg_type == T_LONG || arg_type == T_DOUBLE) {
+        intptr_t *unwind_sp = calculate_unwind_sp(stack, method_handle);
+        insert_vmslots(arg_slot, 1, THREAD);
+        if (HAS_PENDING_EXCEPTION) {
+          // all oops trashed
+          stack->set_sp(unwind_sp);
+          return;
+        }
+        vmslots = stack->sp();
+        arg_slot++;
+      }
+      switch (arg_type) {
+      case T_BOOLEAN:
+        SET_VMSLOTS_INT(arg_value.z, arg_slot);
+        break;
+      case T_CHAR:
+        SET_VMSLOTS_INT(arg_value.c, arg_slot);
+        break;
+      case T_BYTE:
+        SET_VMSLOTS_INT(arg_value.b, arg_slot);
+        break;
+      case T_SHORT:
+        SET_VMSLOTS_INT(arg_value.s, arg_slot);
+        break;
+      case T_INT:
+        SET_VMSLOTS_INT(arg_value.i, arg_slot);
+        break;
+      case T_FLOAT:
+        SET_VMSLOTS_FLOAT(arg_value.f, arg_slot);
+        break;
+      case T_LONG:
+        SET_VMSLOTS_LONG(arg_value.j, arg_slot);
+        break;
+      case T_DOUBLE:
+        SET_VMSLOTS_DOUBLE(arg_value.d, arg_slot);
+        break;
+      default:
+        tty->print_cr("unhandled type %s", type2name(arg_type));
+        ShouldNotReachHere();
+      }
+    }
+    break;
+
+  default:
+    tty->print_cr("unhandled entry_kind %s",
+                  MethodHandles::entry_name(entry_kind));
+    ShouldNotReachHere();
+  }
+
+  // Continue along the chain
+  if (direct_to_method) {
+    if (method == NULL) {
+      method =
+        (methodOop) java_lang_invoke_MethodHandle::vmtarget(method_handle);
+    }
+    address entry_point = method->from_interpreted_entry();
+    Interpreter::invoke_method(method, entry_point, THREAD);
+  }
+  else {
+    process_method_handle(
+      java_lang_invoke_MethodHandle::vmtarget(method_handle), THREAD);
+  }
+  // NB all oops now trashed
+
+  // Adapt the result type, if necessary
+  if (src_rtype != dst_rtype && !HAS_PENDING_EXCEPTION) {
+    switch (dst_rtype) {
+    case T_VOID:
+      for (int i = 0; i < type2size[src_rtype]; i++)
+        stack->pop();
+      return;
+
+    case T_INT:
+      switch (src_rtype) {
+      case T_VOID:
+        stack->overflow_check(1, CHECK);
+        stack->push(0);
+        return;
+
+      case T_BOOLEAN:
+      case T_CHAR:
+      case T_BYTE:
+      case T_SHORT:
+        return;
+      }
+    }
+
+    tty->print_cr("unhandled conversion:");
+    tty->print_cr("src_rtype = %s", type2name(src_rtype));
+    tty->print_cr("dst_rtype = %s", type2name(dst_rtype));
+    ShouldNotReachHere();
+  }
+}
+
+// The new slots will be inserted before slot insert_before.
+// Slots < insert_before will have the same slot number after the insert.
+// Slots >= insert_before will become old_slot + num_slots.
+void CppInterpreter::insert_vmslots(int insert_before, int num_slots, TRAPS) {
+  JavaThread *thread = (JavaThread *) THREAD;
+  ZeroStack *stack = thread->zero_stack();
+
+  // Allocate the space
+  stack->overflow_check(num_slots, CHECK);
+  stack->alloc(num_slots * wordSize);
+  intptr_t *vmslots = stack->sp();
+
+  // Shuffle everything up
+  for (int i = 0; i < insert_before; i++)
+    SET_VMSLOTS_SLOT(VMSLOTS_SLOT(i + num_slots), i);
+}
+
+void CppInterpreter::remove_vmslots(int first_slot, int num_slots, TRAPS) {
+  JavaThread *thread = (JavaThread *) THREAD;
+  ZeroStack *stack = thread->zero_stack();
+  intptr_t *vmslots = stack->sp();
+
+  // Move everything down
+  for (int i = first_slot - 1; i >= 0; i--)
+    SET_VMSLOTS_SLOT(VMSLOTS_SLOT(i), i + num_slots);
+
+  // Deallocate the space
+  stack->set_sp(stack->sp() + num_slots);
+}
+
+BasicType CppInterpreter::result_type_of_handle(oop method_handle) {
+  oop method_type = java_lang_invoke_MethodHandle::type(method_handle);
+  oop return_type = java_lang_invoke_MethodType::rtype(method_type);
+  return java_lang_Class::as_BasicType(return_type, (klassOop *) NULL);
+}
+
+intptr_t* CppInterpreter::calculate_unwind_sp(ZeroStack* stack,
+                                              oop method_handle) {
+  oop method_type = java_lang_invoke_MethodHandle::type(method_handle);
+  oop form = java_lang_invoke_MethodType::form(method_type);
+  int argument_slots = java_lang_invoke_MethodTypeForm::vmslots(form);
+
+  return stack->sp() + argument_slots;
+}
+
+IRT_ENTRY(void, CppInterpreter::throw_exception(JavaThread* thread,
+                                                Symbol*     name,
+                                                char*       message))
+  THROW_MSG(name, message);
+IRT_END
+
 InterpreterFrame *InterpreterFrame::build(const methodOop method, TRAPS) {
   JavaThread *thread = (JavaThread *) THREAD;
   ZeroStack *stack = thread->zero_stack();
--- a/src/cpu/zero/vm/cppInterpreter_zero.hpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/cpu/zero/vm/cppInterpreter_zero.hpp	Thu Apr 21 08:12:46 2011 -0700
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2007, 2008, 2010 Red Hat, Inc.
+ * Copyright 2007, 2008, 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
@@ -36,12 +36,22 @@
   static int native_entry(methodOop method, intptr_t UNUSED, TRAPS);
   static int accessor_entry(methodOop method, intptr_t UNUSED, TRAPS);
   static int empty_entry(methodOop method, intptr_t UNUSED, TRAPS);
+  static int method_handle_entry(methodOop method, intptr_t UNUSED, TRAPS);
 
  public:
   // Main loop of normal_entry
   static void main_loop(int recurse, TRAPS);
 
  private:
+  // Helpers for method_handle_entry
+  static void process_method_handle(oop method_handle, TRAPS);
+  static void insert_vmslots(int insert_before, int num_slots, TRAPS);
+  static void remove_vmslots(int first_slot, int num_slots, TRAPS);
+  static BasicType result_type_of_handle(oop method_handle);
+  static intptr_t* calculate_unwind_sp(ZeroStack* stack, oop method_handle);
+  static void throw_exception(JavaThread* thread, Symbol* name,char *msg=NULL);
+
+ private:
   // Fast result type determination
   static BasicType result_type_of(methodOop method);
 
--- a/src/cpu/zero/vm/globals_zero.hpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/cpu/zero/vm/globals_zero.hpp	Thu Apr 21 08:12:46 2011 -0700
@@ -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/interpreter_zero.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/cpu/zero/vm/interpreter_zero.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -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
@@ -49,6 +49,9 @@
 #ifdef COMPILER1
 #include "c1/c1_Runtime1.hpp"
 #endif
+#ifdef CC_INTERP
+#include "interpreter/cppInterpreter.hpp"
+#endif
 
 address AbstractInterpreterGenerator::generate_slow_signature_handler() {
   _masm->advance(1);
@@ -64,11 +67,15 @@
 }
 
 address InterpreterGenerator::generate_abstract_entry() {
-  return ShouldNotCallThisEntry();
+  return generate_entry((address) ShouldNotCallThisEntry());
 }
 
 address InterpreterGenerator::generate_method_handle_entry() {
-  return ShouldNotCallThisEntry();
+#ifdef CC_INTERP
+  return generate_entry((address) CppInterpreter::method_handle_entry);
+#else
+  return generate_entry((address) ShouldNotCallThisEntry());
+#endif // CC_INTERP
 }
 
 bool AbstractInterpreter::can_be_compiled(methodHandle m) {
--- a/src/cpu/zero/vm/methodHandles_zero.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/cpu/zero/vm/methodHandles_zero.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2009, 2010 Red Hat, Inc.
+ * Copyright 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
@@ -29,10 +29,21 @@
 #include "prims/methodHandles.hpp"
 
 int MethodHandles::adapter_conversion_ops_supported_mask() {
-  ShouldNotCallThis();
+  return ((1<<java_lang_invoke_AdapterMethodHandle::OP_RETYPE_ONLY)
+         |(1<<java_lang_invoke_AdapterMethodHandle::OP_RETYPE_RAW)
+         |(1<<java_lang_invoke_AdapterMethodHandle::OP_CHECK_CAST)
+         |(1<<java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_PRIM)
+         |(1<<java_lang_invoke_AdapterMethodHandle::OP_REF_TO_PRIM)
+         |(1<<java_lang_invoke_AdapterMethodHandle::OP_SWAP_ARGS)
+         |(1<<java_lang_invoke_AdapterMethodHandle::OP_ROT_ARGS)
+         |(1<<java_lang_invoke_AdapterMethodHandle::OP_DUP_ARGS)
+         |(1<<java_lang_invoke_AdapterMethodHandle::OP_DROP_ARGS)
+         //|(1<<java_lang_invoke_AdapterMethodHandle::OP_SPREAD_ARGS) //BUG!
+         );
+  // FIXME: MethodHandlesTest gets a crash if we enable OP_SPREAD_ARGS.
 }
 
 void MethodHandles::generate_method_handle_stub(MacroAssembler*          masm,
                                                 MethodHandles::EntryKind ek) {
-  ShouldNotCallThis();
+  init_entry(ek, (MethodHandleEntry *) ek);
 }
--- a/src/cpu/zero/vm/relocInfo_zero.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/cpu/zero/vm/relocInfo_zero.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -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	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/cpu/zero/vm/sharedRuntime_zero.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -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/os_linux.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/os/linux/vm/os_linux.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -2648,45 +2648,39 @@
 // writing thread stacks don't use growable mappings (i.e. those
 // creeated with MAP_GROWSDOWN), and aren't marked "[stack]", so this
 // only applies to the main thread.
-static bool
-get_stack_bounds(uintptr_t *bottom, uintptr_t *top)
-{
-  FILE *f = fopen("/proc/self/maps", "r");
-  if (f == NULL)
+
+static
+bool get_stack_bounds(uintptr_t *bottom, uintptr_t *top) {
+
+  char buf[128];
+  int fd, sz;
+
+  if ((fd = ::open("/proc/self/maps", O_RDONLY)) < 0) {
     return false;
-
-  while (!feof(f)) {
-    size_t dummy;
-    char *str = NULL;
-    ssize_t len = getline(&str, &dummy, f);
-    if (len == -1) {
-      fclose(f);
-      return false;
-    }
-
-    if (len > 0 && str[len-1] == '\n') {
-      str[len-1] = 0;
-      len--;
-    }
-
-    static const char *stack_str = "[stack]";
-    if (len > (ssize_t)strlen(stack_str)
-       && (strcmp(str + len - strlen(stack_str), stack_str) == 0)) {
-      if (sscanf(str, "%" SCNxPTR "-%" SCNxPTR, bottom, top) == 2) {
-        uintptr_t sp = (uintptr_t)__builtin_frame_address(0);
-        if (sp >= *bottom && sp <= *top) {
-          free(str);
-          fclose(f);
-          return true;
+  }
+
+  const char kw[] = "[stack]";
+  const int kwlen = sizeof(kw)-1;
+
+  // Address part of /proc/self/maps couldn't be more than 128 bytes
+  while ((sz = os::get_line_chars(fd, buf, sizeof(buf))) > 0) {
+     if (sz > kwlen && ::memcmp(buf+sz-kwlen, kw, kwlen) == 0) {
+        // Extract addresses
+        if (sscanf(buf, "%" SCNxPTR "-%" SCNxPTR, bottom, top) == 2) {
+           uintptr_t sp = (uintptr_t) __builtin_frame_address(0);
+           if (sp >= *bottom && sp <= *top) {
+              ::close(fd);
+              return true;
+           }
         }
-      }
-    }
-    free(str);
+     }
   }
-  fclose(f);
+
+ ::close(fd);
   return false;
 }
 
+
 // If the (growable) stack mapping already extends beyond the point
 // where we're going to put our guard pages, truncate the mapping at
 // that point by munmap()ping it.  This ensures that when we later
--- a/src/share/tools/ProjectCreator/WinGammaPlatformVC10.java	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/tools/ProjectCreator/WinGammaPlatformVC10.java	Thu Apr 21 08:12:46 2011 -0700
@@ -497,6 +497,9 @@
             addAttr(rv, "TargetMachine", "MachineX64");
         }
 
+        // We always want the /DEBUG option to get full symbol information in the pdb files
+        addAttr(rv, "GenerateDebugInformation", "true");
+
         return rv;
     }
 
@@ -504,8 +507,7 @@
     Vector getDebugLinkerFlags() {
         Vector rv = new Vector();
 
-        // /DEBUG option
-        addAttr(rv, "GenerateDebugInformation", "true");
+        // Empty now that /DEBUG option is used by all configs
 
         return rv;
     }
--- a/src/share/vm/c1/c1_GraphBuilder.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/c1/c1_GraphBuilder.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -2824,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;
   }
 
@@ -2836,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();
   }
 
--- a/src/share/vm/c1/c1_Instruction.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/c1/c1_Instruction.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -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	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/c1/c1_Instruction.hpp	Thu Apr 21 08:12:46 2011 -0700
@@ -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	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/c1/c1_LIR.hpp	Thu Apr 21 08:12:46 2011 -0700
@@ -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	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/c1/c1_LIRAssembler.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -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_LIRGenerator.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/c1/c1_LIRGenerator.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -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_Optimizer.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/c1/c1_Optimizer.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -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	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/c1/c1_Runtime1.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -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	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/c1/c1_Runtime1.hpp	Thu Apr 21 08:12:46 2011 -0700
@@ -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/ci/ciInstance.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/ci/ciInstance.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -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/ciMethodHandle.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/ci/ciMethodHandle.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -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/ciTypeFlow.hpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/ci/ciTypeFlow.hpp	Thu Apr 21 08:12:46 2011 -0700
@@ -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/classfile/classFileParser.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/classfile/classFileParser.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -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);
@@ -492,7 +483,6 @@
               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;
         }
@@ -578,6 +560,7 @@
         }
         break;
       }
+      case JVM_CONSTANT_InvokeDynamic:
       case JVM_CONSTANT_Fieldref:
       case JVM_CONSTANT_Methodref:
       case JVM_CONSTANT_InterfaceMethodref: {
@@ -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");
@@ -3194,15 +3175,6 @@
     if (EnableInvokeDynamic && class_name == vmSymbols::java_lang_invoke_MethodHandle() && class_loader.is_null()) {
       java_lang_invoke_MethodHandle_fix_pre(cp, fields, &fac, CHECK_(nullHandle));
     }
-    if (AllowTransitionalJSR292 &&
-        EnableInvokeDynamic && class_name == vmSymbols::java_dyn_MethodHandle() && class_loader.is_null()) {
-      java_lang_invoke_MethodHandle_fix_pre(cp, fields, &fac, CHECK_(nullHandle));
-    }
-    if (AllowTransitionalJSR292 &&
-        EnableInvokeDynamic && class_name == vmSymbols::sun_dyn_MethodHandleImpl() && class_loader.is_null()) {
-      // allow vmentry field in MethodHandleImpl also
-      java_lang_invoke_MethodHandle_fix_pre(cp, fields, &fac, CHECK_(nullHandle));
-    }
 
     // Add a fake "discovered" field if it is not present
     // for compatibility with earlier jdk's.
--- a/src/share/vm/classfile/javaClasses.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/classfile/javaClasses.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -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,
@@ -1453,32 +1431,41 @@
       }
     }
 #ifdef ASSERT
-  assert(st_method() == method && st.bci() == bci,
-         "Wrong stack trace");
-  st.next();
-  // vframeStream::method isn't GC-safe so store off a copy
-  // of the methodOop in case we GC.
-  if (!st.at_end()) {
-    st_method = st.method();
-  }
+    assert(st_method() == method && st.bci() == bci,
+           "Wrong stack trace");
+    st.next();
+    // vframeStream::method isn't GC-safe so store off a copy
+    // of the methodOop in case we GC.
+    if (!st.at_end()) {
+      st_method = st.method();
+    }
 #endif
+
+    // the format of the stacktrace will be:
+    // - 1 or more fillInStackTrace frames for the exception class (skipped)
+    // - 0 or more <init> methods for the exception class (skipped)
+    // - rest of the stack
+
     if (!skip_fillInStackTrace_check) {
-      // check "fillInStackTrace" only once, so we negate the flag
-      // after the first time check.
-      skip_fillInStackTrace_check = true;
-      if (method->name() == vmSymbols::fillInStackTrace_name()) {
+      if ((method->name() == vmSymbols::fillInStackTrace_name() ||
+           method->name() == vmSymbols::fillInStackTrace0_name()) &&
+          throwable->is_a(method->method_holder())) {
         continue;
       }
+      else {
+        skip_fillInStackTrace_check = true; // gone past them all
+      }
     }
-    // skip <init> methods of the exceptions klass. If there is <init> methods
-    // that belongs to a superclass of the exception  we are going to skipping
-    // them in stack trace. This is simlar to classic VM.
     if (!skip_throwableInit_check) {
+      assert(skip_fillInStackTrace_check, "logic error in backtrace filtering");
+
+      // skip <init> methods of the exception class and superclasses
+      // This is simlar to classic VM.
       if (method->name() == vmSymbols::object_initializer_name() &&
           throwable->is_a(method->method_holder())) {
         continue;
       } else {
-        // if no "Throwable.init()" method found, we stop checking it next time.
+        // there are none or we've seen them all - either way stop checking
         skip_throwableInit_check = true;
       }
     }
@@ -2333,7 +2320,6 @@
   klassOop k = SystemDictionary::MethodHandle_klass();
   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);
--- a/src/share/vm/classfile/stackMapFrame.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/classfile/stackMapFrame.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -208,8 +208,10 @@
   return true;
 }
 
-bool StackMapFrame::is_assignable_to(const StackMapFrame* target, TRAPS) const {
-  if (_max_locals != target->max_locals() || _stack_size != target->stack_size()) {
+bool StackMapFrame::is_assignable_to(
+    const StackMapFrame* target, bool is_exception_handler, TRAPS) const {
+  if (_max_locals != target->max_locals() ||
+      _stack_size != target->stack_size()) {
     return false;
   }
   // Only need to compare type elements up to target->locals() or target->stack().
@@ -222,7 +224,7 @@
   bool match_flags = (_flags | target->flags()) == target->flags();
 
   return match_locals && match_stack &&
-    (match_flags || has_flag_match_exception(target));
+    (match_flags || (is_exception_handler && has_flag_match_exception(target)));
 }
 
 VerificationType StackMapFrame::pop_stack_ex(VerificationType type, TRAPS) {
--- a/src/share/vm/classfile/stackMapFrame.hpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/classfile/stackMapFrame.hpp	Thu Apr 21 08:12:46 2011 -0700
@@ -134,7 +134,8 @@
   void copy_stack(const StackMapFrame* src);
 
   // Return true if this stack map frame is assignable to target.
-  bool is_assignable_to(const StackMapFrame* target, TRAPS) const;
+  bool is_assignable_to(const StackMapFrame* target,
+                        bool is_exception_handler, TRAPS) const;
 
   // Push type into stack type array.
   inline void push_stack(VerificationType type, TRAPS) {
--- a/src/share/vm/classfile/stackMapTable.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/classfile/stackMapTable.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -98,10 +98,13 @@
   bool result = true;
   StackMapFrame *stackmap_frame = _frame_array[frame_index];
   if (match) {
+    // when checking handler target, match == true && update == false
+    bool is_exception_handler = !update;
     // Has direct control flow from last instruction, need to match the two
     // frames.
     result = frame->is_assignable_to(
-      stackmap_frame, CHECK_VERIFY_(frame->verifier(), false));
+      stackmap_frame, is_exception_handler,
+      CHECK_VERIFY_(frame->verifier(), false));
   }
   if (update) {
     // Use the frame in stackmap table as current frame
--- a/src/share/vm/classfile/systemDictionary.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/classfile/systemDictionary.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -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 (!EnableInvokeDynamic)  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) {
@@ -2409,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,
@@ -2498,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());
 
@@ -2513,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.
@@ -2569,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());
 }
@@ -2607,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()
@@ -2698,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	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/classfile/systemDictionary.hpp	Thu Apr 21 08:12:46 2011 -0700
@@ -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 */          \
                                                                               \
@@ -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/verifier.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/classfile/verifier.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -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/vmSymbols.hpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/classfile/vmSymbols.hpp	Thu Apr 21 08:12:46 2011 -0700
@@ -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) )                           \
                                                                                                   \
@@ -330,6 +301,7 @@
   template(dispatch_name,                             "dispatch")                                 \
   template(getSystemClassLoader_name,                 "getSystemClassLoader")                     \
   template(fillInStackTrace_name,                     "fillInStackTrace")                         \
+  template(fillInStackTrace0_name,                    "fillInStackTrace0")                        \
   template(getCause_name,                             "getCause")                                 \
   template(initCause_name,                            "initCause")                                \
   template(setProperty_name,                          "setProperty")                              \
@@ -910,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/codeCache.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/code/codeCache.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -964,3 +964,14 @@
             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 {
+    MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
+    return _heap->largest_free_block();
+  }
+}
--- a/src/share/vm/code/codeCache.hpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/code/codeCache.hpp	Thu Apr 21 08:12:46 2011 -0700
@@ -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/relocInfo.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/code/relocInfo.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -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	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/code/relocInfo.hpp	Thu Apr 21 08:12:46 2011 -0700
@@ -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/compiler/compileBroker.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/compiler/compileBroker.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -847,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);
   }
@@ -1118,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.
@@ -1736,8 +1736,14 @@
   UseInterpreter = true;
   if (UseCompiler || AlwaysCompileLoopMethods ) {
     if (xtty != NULL) {
+      stringStream s;
+      // Dump code cache state into a buffer before locking the tty,
+      // because log_state() will use locks causing lock conflicts.
+      CodeCache::log_state(&s);
+      // Lock to prevent tearing
+      ttyLocker ttyl;
       xtty->begin_elem("code_cache_full");
-      CodeCache::log_state(xtty);
+      xtty->print(s.as_string());
       xtty->stamp();
       xtty->end_elem();
     }
--- a/src/share/vm/interpreter/bytecodeInterpreter.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/interpreter/bytecodeInterpreter.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -554,7 +554,7 @@
 
 /* 0xB0 */ &&opc_areturn,     &&opc_return,         &&opc_getstatic,    &&opc_putstatic,
 /* 0xB4 */ &&opc_getfield,    &&opc_putfield,       &&opc_invokevirtual,&&opc_invokespecial,
-/* 0xB8 */ &&opc_invokestatic,&&opc_invokeinterface,&&opc_default,      &&opc_new,
+/* 0xB8 */ &&opc_invokestatic,&&opc_invokeinterface,&&opc_invokedynamic,&&opc_new,
 /* 0xBC */ &&opc_newarray,    &&opc_anewarray,      &&opc_arraylength,  &&opc_athrow,
 
 /* 0xC0 */ &&opc_checkcast,   &&opc_instanceof,     &&opc_monitorenter, &&opc_monitorexit,
@@ -568,7 +568,7 @@
 /* 0xDC */ &&opc_default,     &&opc_default,        &&opc_default,      &&opc_default,
 
 /* 0xE0 */ &&opc_default,     &&opc_default,        &&opc_default,      &&opc_default,
-/* 0xE4 */ &&opc_default,     &&opc_return_register_finalizer,        &&opc_default,      &&opc_default,
+/* 0xE4 */ &&opc_default,     &&opc_fast_aldc,      &&opc_fast_aldc_w,  &&opc_return_register_finalizer,
 /* 0xE8 */ &&opc_default,     &&opc_default,        &&opc_default,      &&opc_default,
 /* 0xEC */ &&opc_default,     &&opc_default,        &&opc_default,      &&opc_default,
 
@@ -1718,8 +1718,7 @@
         }
         // Need to throw illegal monitor state exception
         CALL_VM(InterpreterRuntime::throw_illegal_monitor_state_exception(THREAD), handle_exception);
-        // Should never reach here...
-        assert(false, "Should have thrown illegal monitor exception");
+        ShouldNotReachHere();
       }
 
       /* All of the non-quick opcodes. */
@@ -2147,6 +2146,74 @@
           UPDATE_PC_AND_TOS_AND_CONTINUE(3, 2);
         }
 
+      CASE(_fast_aldc_w):
+      CASE(_fast_aldc): {
+        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(InterpreterRuntime::throw_IncompatibleClassChangeError(THREAD),
+                  handle_exception);
+          ShouldNotReachHere();
+        }
+
+        u2 index;
+        int incr;
+        if (opcode == Bytecodes::_fast_aldc) {
+          index = pc[1];
+          incr = 2;
+        } else {
+          index = Bytes::get_native_u2(pc+1);
+          incr = 3;
+        }
+
+        // We are resolved if the f1 field contains a non-null object (CallSite, etc.)
+        // This kind of CP cache entry does not need to match the flags byte, because
+        // there is a 1-1 relation between bytecode type and CP entry type.
+        ConstantPoolCacheEntry* cache = cp->entry_at(index);
+        if (cache->is_f1_null()) {
+          CALL_VM(InterpreterRuntime::resolve_ldc(THREAD, (Bytecodes::Code) opcode),
+                  handle_exception);
+        }
+
+        VERIFY_OOP(cache->f1());
+        SET_STACK_OBJECT(cache->f1(), 0);
+        UPDATE_PC_AND_TOS_AND_CONTINUE(incr, 1);
+      }
+
+      CASE(_invokedynamic): {
+        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(InterpreterRuntime::throw_IncompatibleClassChangeError(THREAD),
+                  handle_exception);
+          ShouldNotReachHere();
+        }
+
+        int index = Bytes::get_native_u4(pc+1);
+
+        // We are resolved if the f1 field contains a non-null object (CallSite, etc.)
+        // This kind of CP cache entry does not need to match the flags byte, because
+        // there is a 1-1 relation between bytecode type and CP entry type.
+        assert(constantPoolCacheOopDesc::is_secondary_index(index), "incorrect format");
+        ConstantPoolCacheEntry* cache = cp->secondary_entry_at(index);
+        if (cache->is_f1_null()) {
+          CALL_VM(InterpreterRuntime::resolve_invokedynamic(THREAD),
+                  handle_exception);
+        }
+
+        VERIFY_OOP(cache->f1());
+        oop method_handle = java_lang_invoke_CallSite::target(cache->f1());
+        CHECK_NULL(method_handle);
+
+        istate->set_msg(call_method_handle);
+        istate->set_callee((methodOop) method_handle);
+        istate->set_bcp_advance(5);
+
+        UPDATE_PC_AND_RETURN(0); // I'll be back...
+      }
+
       CASE(_invokeinterface): {
         u2 index = Bytes::get_native_u2(pc+1);
 
--- a/src/share/vm/interpreter/bytecodeInterpreter.hpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/interpreter/bytecodeInterpreter.hpp	Thu Apr 21 08:12:46 2011 -0700
@@ -107,6 +107,7 @@
          rethrow_exception,         // unwinding and throwing exception
          // requests to frame manager from C++ interpreter
          call_method,               // request for new frame from interpreter, manager responds with method_entry
+         call_method_handle,        // like the above, except the callee is a method handle
          return_from_method,        // request from interpreter to unwind, manager responds with method_continue
          more_monitors,             // need a new monitor
          throwing_exception,        // unwind stack and rethrow
--- a/src/share/vm/interpreter/bytecodeTracer.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/interpreter/bytecodeTracer.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -345,7 +345,6 @@
     break;
   case JVM_CONSTANT_NameAndType:
   case JVM_CONSTANT_InvokeDynamic:
-  case JVM_CONSTANT_InvokeDynamicTrans:
     has_klass = false;
     break;
   default:
--- a/src/share/vm/interpreter/interpreterRuntime.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/interpreter/interpreterRuntime.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -369,10 +369,7 @@
   }
 
   // create exception
-  Symbol* java_lang_invoke_WrongMethodTypeException = vmSymbols::java_lang_invoke_WrongMethodTypeException();
-  if (AllowTransitionalJSR292)
-    java_lang_invoke_WrongMethodTypeException = SystemDictionaryHandles::WrongMethodTypeException_klass()->name();
-  THROW_MSG(java_lang_invoke_WrongMethodTypeException, message);
+  THROW_MSG(vmSymbols::java_lang_invoke_WrongMethodTypeException(), message);
 }
 IRT_END
 
--- a/src/share/vm/interpreter/linkResolver.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/interpreter/linkResolver.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -221,9 +221,7 @@
       // Make sure the Java part of the runtime has been booted up.
       klassOop natives = SystemDictionary::MethodHandleNatives_klass();
       if (natives == NULL || instanceKlass::cast(natives)->is_not_initialized()) {
-        Symbol* natives_name = vmSymbols::java_lang_invoke_MethodHandleNatives();
-        if (natives != NULL && AllowTransitionalJSR292)  natives_name = Klass::cast(natives)->name();
-        SystemDictionary::resolve_or_fail(natives_name,
+        SystemDictionary::resolve_or_fail(vmSymbols::java_lang_invoke_MethodHandleNatives(),
                                           Handle(),
                                           Handle(),
                                           true,
--- a/src/share/vm/interpreter/rewriter.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/interpreter/rewriter.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -52,7 +52,6 @@
       case JVM_CONSTANT_MethodHandle      : // fall through
       case JVM_CONSTANT_MethodType        : // fall through
       case JVM_CONSTANT_InvokeDynamic     : // fall through
-      case JVM_CONSTANT_InvokeDynamicTrans: // fall through
         add_cp_cache_entry(i);
         break;
     }
@@ -62,7 +61,6 @@
             "all cp cache indexes fit in a u2");
 
   _have_invoke_dynamic = ((tag_mask & (1 << JVM_CONSTANT_InvokeDynamic)) != 0);
-  _have_invoke_dynamic |= ((tag_mask & (1 << JVM_CONSTANT_InvokeDynamicTrans)) != 0);
 }
 
 
@@ -81,16 +79,10 @@
       if (pool_index >= 0 &&
           _pool->tag_at(pool_index).is_invoke_dynamic()) {
         int bsm_index = _pool->invoke_dynamic_bootstrap_method_ref_index_at(pool_index);
-        if (bsm_index != 0) {
-          assert(_pool->tag_at(bsm_index).is_method_handle(), "must be a MH constant");
-          // There is a CP cache entry holding the BSM for these calls.
-          int bsm_cache_index = cp_entry_to_cp_cache(bsm_index);
-          cache->entry_at(i)->initialize_bootstrap_method_index_in_cache(bsm_cache_index);
-        } else {
-          // There is no CP cache entry holding the BSM for these calls.
-          // We will need to look for a class-global BSM, later.
-          guarantee(AllowTransitionalJSR292, "");
-        }
+        assert(_pool->tag_at(bsm_index).is_method_handle(), "must be a MH constant");
+        // There is a CP cache entry holding the BSM for these calls.
+        int bsm_cache_index = cp_entry_to_cp_cache(bsm_index);
+        cache->entry_at(i)->initialize_bootstrap_method_index_in_cache(bsm_cache_index);
       }
     }
   }
--- a/src/share/vm/oops/constantPoolKlass.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/oops/constantPoolKlass.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -381,7 +381,6 @@
       case JVM_CONSTANT_MethodType :
         st->print("signature_index=%d", cp->method_type_index_at(index));
         break;
-      case JVM_CONSTANT_InvokeDynamicTrans :
       case JVM_CONSTANT_InvokeDynamic :
         {
           st->print("bootstrap_method_index=%d", cp->invoke_dynamic_bootstrap_method_ref_index_at(index));
--- a/src/share/vm/oops/constantPoolOop.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/oops/constantPoolOop.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -284,17 +284,13 @@
     if (constantPoolCacheOopDesc::is_secondary_index(which)) {
       // Invokedynamic index.
       int pool_index = cache()->main_entry_at(which)->constant_pool_index();
-      if (!AllowTransitionalJSR292 || tag_at(pool_index).is_invoke_dynamic())
-        pool_index = invoke_dynamic_name_and_type_ref_index_at(pool_index);
+      pool_index = invoke_dynamic_name_and_type_ref_index_at(pool_index);
       assert(tag_at(pool_index).is_name_and_type(), "");
       return pool_index;
     }
     // change byte-ordering and go via cache
     i = remap_instruction_operand_from_cache(which);
   } else {
-    if (AllowTransitionalJSR292 && tag_at(which).is_name_and_type())
-      // invokedynamic index is a simple name-and-type
-      return which;
     if (tag_at(which).is_invoke_dynamic()) {
       int pool_index = invoke_dynamic_name_and_type_ref_index_at(which);
       assert(tag_at(pool_index).is_name_and_type(), "");
@@ -953,7 +949,6 @@
   } break;
 
   case JVM_CONSTANT_InvokeDynamic:
-  case JVM_CONSTANT_InvokeDynamicTrans:
   {
     int k1 = invoke_dynamic_bootstrap_method_ref_index_at(index1);
     int k2 = cp2->invoke_dynamic_bootstrap_method_ref_index_at(index2);
@@ -1227,13 +1222,6 @@
     to_cp->method_handle_index_at_put(to_i, k1, k2);
   } break;
 
-  case JVM_CONSTANT_InvokeDynamicTrans:
-  {
-    int k1 = from_cp->invoke_dynamic_bootstrap_method_ref_index_at(from_i);
-    int k2 = from_cp->invoke_dynamic_name_and_type_ref_index_at(from_i);
-    to_cp->invoke_dynamic_trans_at_put(to_i, k1, k2);
-  } break;
-
   case JVM_CONSTANT_InvokeDynamic:
   {
     int k1 = from_cp->invoke_dynamic_bootstrap_specifier_index(from_i);
@@ -1459,7 +1447,6 @@
       return 5;
 
     case JVM_CONSTANT_InvokeDynamic:
-    case JVM_CONSTANT_InvokeDynamicTrans:
       // u1 tag, u2 bsm, u2 nt
       return 5;
 
@@ -1674,7 +1661,6 @@
         DBG(printf("JVM_CONSTANT_MethodType: %hd", idx1));
         break;
       }
-      case JVM_CONSTANT_InvokeDynamicTrans:
       case JVM_CONSTANT_InvokeDynamic: {
         *bytes = tag;
         idx1 = extract_low_short_from_int(*int_at_addr(idx));
--- a/src/share/vm/oops/constantPoolOop.hpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/oops/constantPoolOop.hpp	Thu Apr 21 08:12:46 2011 -0700
@@ -244,12 +244,6 @@
     *int_at_addr(which) = ((jint) name_and_type_index<<16) | bootstrap_specifier_index;
   }
 
-  void invoke_dynamic_trans_at_put(int which, int bootstrap_method_index, int name_and_type_index) {
-    tag_at_put(which, JVM_CONSTANT_InvokeDynamicTrans);
-    *int_at_addr(which) = ((jint) name_and_type_index<<16) | bootstrap_method_index;
-    assert(AllowTransitionalJSR292, "");
-  }
-
   // Temporary until actual use
   void unresolved_string_at_put(int which, Symbol* s) {
     release_tag_at_put(which, JVM_CONSTANT_UnresolvedString);
@@ -570,15 +564,11 @@
   };
   int invoke_dynamic_bootstrap_method_ref_index_at(int which) {
     assert(tag_at(which).is_invoke_dynamic(), "Corrupted constant pool");
-    if (tag_at(which).value() == JVM_CONSTANT_InvokeDynamicTrans)
-      return extract_low_short_from_int(*int_at_addr(which));
     int op_base = invoke_dynamic_operand_base(which);
     return operands()->short_at(op_base + _indy_bsm_offset);
   }
   int invoke_dynamic_argument_count_at(int which) {
     assert(tag_at(which).is_invoke_dynamic(), "Corrupted constant pool");
-    if (tag_at(which).value() == JVM_CONSTANT_InvokeDynamicTrans)
-      return 0;
     int op_base = invoke_dynamic_operand_base(which);
     int argc = operands()->short_at(op_base + _indy_argc_offset);
     DEBUG_ONLY(int end_offset = op_base + _indy_argv_offset + argc;
--- a/src/share/vm/oops/cpCacheOop.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/oops/cpCacheOop.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -185,7 +185,7 @@
         this->print(tty, 0);
       }
       assert(method->can_be_statically_bound(), "must be a MH invoker method");
-      assert(AllowTransitionalJSR292 || _f2 >= constantPoolOopDesc::CPCACHE_INDEX_TAG, "BSM index initialized");
+      assert(_f2 >= constantPoolOopDesc::CPCACHE_INDEX_TAG, "BSM index initialized");
       // SystemDictionary::find_method_handle_invoke only caches
       // methods which signature classes are on the boot classpath,
       // otherwise the newly created method is returned.  To avoid
--- a/src/share/vm/oops/instanceKlass.hpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/oops/instanceKlass.hpp	Thu Apr 21 08:12:46 2011 -0700
@@ -191,8 +191,6 @@
   typeArrayOop    _inner_classes;
   // Implementors of this interface (not valid if it overflows)
   klassOop        _implementors[implementors_limit];
-  // invokedynamic bootstrap method (a java.lang.invoke.MethodHandle)
-  oop             _bootstrap_method;  // AllowTransitionalJSR292 ONLY
   // Annotations for this class, or null if none.
   typeArrayOop    _class_annotations;
   // Annotation objects (byte arrays) for fields, or null if no annotations.
@@ -526,10 +524,6 @@
                                     u2 method_index)  { _enclosing_method_class_index  = class_index;
                                                         _enclosing_method_method_index = method_index; }
 
-  // JSR 292 support
-  oop bootstrap_method() const                        { return _bootstrap_method; }  // AllowTransitionalJSR292 ONLY
-  void set_bootstrap_method(oop mh)                   { oop_store(&_bootstrap_method, mh); }
-
   // jmethodID support
   static jmethodID get_jmethod_id(instanceKlassHandle ik_h,
                      methodHandle method_h);
@@ -793,7 +787,6 @@
   oop* adr_signers() const           { return (oop*)&this->_signers;}
   oop* adr_inner_classes() const     { return (oop*)&this->_inner_classes;}
   oop* adr_implementors() const      { return (oop*)&this->_implementors[0];}
-  oop* adr_bootstrap_method() const  { return (oop*)&this->_bootstrap_method;}  // AllowTransitionalJSR292 ONLY
   oop* adr_methods_jmethod_ids() const             { return (oop*)&this->_methods_jmethod_ids;}
   oop* adr_methods_cached_itable_indices() const   { return (oop*)&this->_methods_cached_itable_indices;}
   oop* adr_class_annotations() const   { return (oop*)&this->_class_annotations;}
--- a/src/share/vm/oops/instanceKlassKlass.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/oops/instanceKlassKlass.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -105,7 +105,6 @@
   MarkSweep::mark_and_push(ik->adr_protection_domain());
   MarkSweep::mark_and_push(ik->adr_host_klass());
   MarkSweep::mark_and_push(ik->adr_signers());
-  MarkSweep::mark_and_push(ik->adr_bootstrap_method());
   MarkSweep::mark_and_push(ik->adr_class_annotations());
   MarkSweep::mark_and_push(ik->adr_fields_annotations());
   MarkSweep::mark_and_push(ik->adr_methods_annotations());
@@ -142,7 +141,6 @@
   PSParallelCompact::mark_and_push(cm, ik->adr_protection_domain());
   PSParallelCompact::mark_and_push(cm, ik->adr_host_klass());
   PSParallelCompact::mark_and_push(cm, ik->adr_signers());
-  PSParallelCompact::mark_and_push(cm, ik->adr_bootstrap_method());
   PSParallelCompact::mark_and_push(cm, ik->adr_class_annotations());
   PSParallelCompact::mark_and_push(cm, ik->adr_fields_annotations());
   PSParallelCompact::mark_and_push(cm, ik->adr_methods_annotations());
@@ -185,7 +183,6 @@
   for (int i = 0; i < instanceKlass::implementors_limit; i++) {
     blk->do_oop(&ik->adr_implementors()[i]);
   }
-  blk->do_oop(ik->adr_bootstrap_method());
   blk->do_oop(ik->adr_class_annotations());
   blk->do_oop(ik->adr_fields_annotations());
   blk->do_oop(ik->adr_methods_annotations());
@@ -239,8 +236,6 @@
   for (int i = 0; i < instanceKlass::implementors_limit; i++) {
     if (mr.contains(&adr[i])) blk->do_oop(&adr[i]);
   }
-  adr = ik->adr_bootstrap_method();
-  if (mr.contains(adr)) blk->do_oop(adr);
   adr = ik->adr_class_annotations();
   if (mr.contains(adr)) blk->do_oop(adr);
   adr = ik->adr_fields_annotations();
@@ -281,7 +276,6 @@
   for (int i = 0; i < instanceKlass::implementors_limit; i++) {
     MarkSweep::adjust_pointer(&ik->adr_implementors()[i]);
   }
-  MarkSweep::adjust_pointer(ik->adr_bootstrap_method());
   MarkSweep::adjust_pointer(ik->adr_class_annotations());
   MarkSweep::adjust_pointer(ik->adr_fields_annotations());
   MarkSweep::adjust_pointer(ik->adr_methods_annotations());
@@ -317,11 +311,6 @@
     pm->claim_or_forward_depth(sg_addr);
   }
 
-  oop* bsm_addr = ik->adr_bootstrap_method();
-  if (PSScavenge::should_scavenge(bsm_addr)) {
-    pm->claim_or_forward_depth(bsm_addr);
-  }
-
   klassKlass::oop_push_contents(pm, obj);
 }
 
@@ -420,7 +409,6 @@
     ik->set_breakpoints(NULL);
     ik->init_previous_versions();
     ik->set_generic_signature(NULL);
-    ik->set_bootstrap_method(NULL);
     ik->release_set_methods_jmethod_ids(NULL);
     ik->release_set_methods_cached_itable_indices(NULL);
     ik->set_class_annotations(NULL);
@@ -542,11 +530,6 @@
     } // pvw is cleaned up
   } // rm is cleaned up
 
-  if (ik->bootstrap_method() != NULL) {
-    st->print(BULLET"bootstrap method:  ");
-    ik->bootstrap_method()->print_value_on(st);
-    st->cr();
-  }
   if (ik->generic_signature() != NULL) {
     st->print(BULLET"generic signature: ");
     ik->generic_signature()->print_value_on(st);
--- a/src/share/vm/oops/methodOop.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/oops/methodOop.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -852,11 +852,11 @@
 bool methodOopDesc::is_method_handle_invoke_name(vmSymbols::SID name_sid) {
   switch (name_sid) {
   case vmSymbols::VM_SYMBOL_ENUM_NAME(invokeExact_name):
-  case vmSymbols::VM_SYMBOL_ENUM_NAME(invokeGeneric_name):
+  case vmSymbols::VM_SYMBOL_ENUM_NAME(invoke_name):
     return true;
   }
-  if ((AllowTransitionalJSR292 || AllowInvokeForInvokeGeneric)
-      && name_sid == vmSymbols::VM_SYMBOL_ENUM_NAME(invoke_name))
+  if (AllowInvokeGeneric
+      && name_sid == vmSymbols::VM_SYMBOL_ENUM_NAME(invokeGeneric_name))
     return true;
   return false;
 }
@@ -921,6 +921,10 @@
     tty->cr();
   }
 
+  // invariant:   cp->symbol_at_put is preceded by a refcount increment (more usually a lookup)
+  name->increment_refcount();
+  signature->increment_refcount();
+
   constantPoolHandle cp;
   {
     constantPoolOop cp_oop = oopFactory::new_constantPool(_imcp_limit, IsSafeConc, CHECK_(empty));
@@ -1092,7 +1096,6 @@
   if (name_id == vmSymbols::NO_SID)  return;
   vmSymbols::SID   sig_id = vmSymbols::find_sid(signature());
   if (klass_id != vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_MethodHandle)
-      && !(klass_id == vmSymbols::VM_SYMBOL_ENUM_NAME(java_dyn_MethodHandle) && AllowTransitionalJSR292)
       && sig_id == vmSymbols::NO_SID)  return;
   jshort flags = access_flags().as_short();
 
@@ -1118,20 +1121,17 @@
     break;
 
   // Signature-polymorphic methods: MethodHandle.invoke*, InvokeDynamic.*.
-  case vmSymbols::VM_SYMBOL_ENUM_NAME(java_dyn_MethodHandle):  // AllowTransitionalJSR292 ONLY
   case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_MethodHandle):
     if (is_static() || !is_native())  break;
     switch (name_id) {
     case vmSymbols::VM_SYMBOL_ENUM_NAME(invokeGeneric_name):
+      if (!AllowInvokeGeneric)  break;
+    case vmSymbols::VM_SYMBOL_ENUM_NAME(invoke_name):
       id = vmIntrinsics::_invokeGeneric;
       break;
     case vmSymbols::VM_SYMBOL_ENUM_NAME(invokeExact_name):
       id = vmIntrinsics::_invokeExact;
       break;
-    case vmSymbols::VM_SYMBOL_ENUM_NAME(invoke_name):
-      if (AllowInvokeForInvokeGeneric)   id = vmIntrinsics::_invokeGeneric;
-      else if (AllowTransitionalJSR292)  id = vmIntrinsics::_invokeExact;
-      break;
     }
     break;
   case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_InvokeDynamic):
--- a/src/share/vm/opto/callGenerator.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/opto/callGenerator.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -978,31 +978,19 @@
   return head;
 }
 
-WarmCallInfo* WarmCallInfo::_always_hot  = NULL;
-WarmCallInfo* WarmCallInfo::_always_cold = NULL;
+WarmCallInfo WarmCallInfo::_always_hot(WarmCallInfo::MAX_VALUE(), WarmCallInfo::MAX_VALUE(),
+                                       WarmCallInfo::MIN_VALUE(), WarmCallInfo::MIN_VALUE());
+WarmCallInfo WarmCallInfo::_always_cold(WarmCallInfo::MIN_VALUE(), WarmCallInfo::MIN_VALUE(),
+                                        WarmCallInfo::MAX_VALUE(), WarmCallInfo::MAX_VALUE());
 
 WarmCallInfo* WarmCallInfo::always_hot() {
-  if (_always_hot == NULL) {
-    static double bits[sizeof(WarmCallInfo) / sizeof(double) + 1] = {0};
-    WarmCallInfo* ci = (WarmCallInfo*) bits;
-    ci->_profit = ci->_count = MAX_VALUE();
-    ci->_work   = ci->_size  = MIN_VALUE();
-    _always_hot = ci;
-  }
-  assert(_always_hot->is_hot(), "must always be hot");
-  return _always_hot;
+  assert(_always_hot.is_hot(), "must always be hot");
+  return &_always_hot;
 }
 
 WarmCallInfo* WarmCallInfo::always_cold() {
-  if (_always_cold == NULL) {
-    static double bits[sizeof(WarmCallInfo) / sizeof(double) + 1] = {0};
-    WarmCallInfo* ci = (WarmCallInfo*) bits;
-    ci->_profit = ci->_count = MIN_VALUE();
-    ci->_work   = ci->_size  = MAX_VALUE();
-    _always_cold = ci;
-  }
-  assert(_always_cold->is_cold(), "must always be cold");
-  return _always_cold;
+  assert(_always_cold.is_cold(), "must always be cold");
+  return &_always_cold;
 }
 
 
--- a/src/share/vm/opto/callGenerator.hpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/opto/callGenerator.hpp	Thu Apr 21 08:12:46 2011 -0700
@@ -215,8 +215,20 @@
   WarmCallInfo*  next() const          { return _next; }
   void       set_next(WarmCallInfo* n) { _next = n; }
 
-  static WarmCallInfo* _always_hot;
-  static WarmCallInfo* _always_cold;
+  static WarmCallInfo _always_hot;
+  static WarmCallInfo _always_cold;
+
+  // Constructor intitialization of always_hot and always_cold
+  WarmCallInfo(float c, float p, float w, float s) {
+    _call = NULL;
+    _hot_cg = NULL;
+    _next = NULL;
+    _count = c;
+    _profit = p;
+    _work = w;
+    _size = s;
+    _heat = 0;
+  }
 
  public:
   // Because WarmInfo objects live over the entire lifetime of the
--- a/src/share/vm/opto/cfgnode.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/opto/cfgnode.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -1349,9 +1349,17 @@
 static void split_once(PhaseIterGVN *igvn, Node *phi, Node *val, Node *n, Node *newn) {
   igvn->hash_delete(n);         // Remove from hash before hacking edges
 
+  Node* predicate_proj = NULL;
   uint j = 1;
-  for( uint i = phi->req()-1; i > 0; i-- ) {
-    if( phi->in(i) == val ) {   // Found a path with val?
+  for (uint i = phi->req()-1; i > 0; i--) {
+    if (phi->in(i) == val) {   // Found a path with val?
+      if (n->is_Region()) {
+        Node* proj = PhaseIdealLoop::find_predicate(n->in(i));
+        if (proj != NULL) {
+          assert(predicate_proj == NULL, "only one predicate entry expected");
+          predicate_proj = proj;
+        }
+      }
       // Add to NEW Region/Phi, no DU info
       newn->set_req( j++, n->in(i) );
       // Remove from OLD Region/Phi
@@ -1362,6 +1370,12 @@
   // Register the new node but do not transform it.  Cannot transform until the
   // entire Region/Phi conglomerate has been hacked as a single huge transform.
   igvn->register_new_node_with_optimizer( newn );
+
+  // Clone loop predicates
+  if (predicate_proj != NULL) {
+    newn = igvn->clone_loop_predicates(predicate_proj, newn);
+  }
+
   // Now I can point to the new node.
   n->add_req(newn);
   igvn->_worklist.push(n);
--- a/src/share/vm/opto/compile.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/opto/compile.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -1632,7 +1632,6 @@
     igvn.replace_node(n, n->in(1));
   }
   assert(predicate_count()==0, "should be clean!");
-  igvn.optimize();
 }
 
 //------------------------------Optimize---------------------------------------
@@ -1689,7 +1688,7 @@
   if((loop_opts_cnt > 0) && (has_loops() || has_split_ifs())) {
     {
       TracePhase t2("idealLoop", &_t_idealLoop, true);
-      PhaseIdealLoop ideal_loop( igvn, true, UseLoopPredicate);
+      PhaseIdealLoop ideal_loop( igvn, true );
       loop_opts_cnt--;
       if (major_progress()) print_method("PhaseIdealLoop 1", 2);
       if (failing())  return;
@@ -1697,7 +1696,7 @@
     // Loop opts pass if partial peeling occurred in previous pass
     if(PartialPeelLoop && major_progress() && (loop_opts_cnt > 0)) {
       TracePhase t3("idealLoop", &_t_idealLoop, true);
-      PhaseIdealLoop ideal_loop( igvn, false, UseLoopPredicate);
+      PhaseIdealLoop ideal_loop( igvn, false );
       loop_opts_cnt--;
       if (major_progress()) print_method("PhaseIdealLoop 2", 2);
       if (failing())  return;
@@ -1705,7 +1704,7 @@
     // Loop opts pass for loop-unrolling before CCP
     if(major_progress() && (loop_opts_cnt > 0)) {
       TracePhase t4("idealLoop", &_t_idealLoop, true);
-      PhaseIdealLoop ideal_loop( igvn, false, UseLoopPredicate);
+      PhaseIdealLoop ideal_loop( igvn, false );
       loop_opts_cnt--;
       if (major_progress()) print_method("PhaseIdealLoop 3", 2);
     }
@@ -1743,21 +1742,13 @@
   // peeling, unrolling, etc.
   if(loop_opts_cnt > 0) {
     debug_only( int cnt = 0; );
-    bool loop_predication = UseLoopPredicate;
     while(major_progress() && (loop_opts_cnt > 0)) {
       TracePhase t2("idealLoop", &_t_idealLoop, true);
       assert( cnt++ < 40, "infinite cycle in loop optimization" );
-      PhaseIdealLoop ideal_loop( igvn, true, loop_predication);
+      PhaseIdealLoop ideal_loop( igvn, true);
       loop_opts_cnt--;
       if (major_progress()) print_method("PhaseIdealLoop iterations", 2);
       if (failing())  return;
-      // Perform loop predication optimization during first iteration after CCP.
-      // After that switch it off and cleanup unused loop predicates.
-      if (loop_predication) {
-        loop_predication = false;
-        cleanup_loop_predicates(igvn);
-        if (failing())  return;
-      }
     }
   }
 
--- a/src/share/vm/opto/compile.hpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/opto/compile.hpp	Thu Apr 21 08:12:46 2011 -0700
@@ -489,6 +489,9 @@
   // remove the opaque nodes that protect the predicates so that the unused checks and
   // uncommon traps will be eliminated from the graph.
   void cleanup_loop_predicates(PhaseIterGVN &igvn);
+  bool is_predicate_opaq(Node * n) {
+    return _predicate_opaqs->contains(n);
+  }
 
   // Compilation environment.
   Arena*            comp_arena()                { return &_comp_arena; }
--- a/src/share/vm/opto/doCall.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/opto/doCall.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -63,6 +63,7 @@
                                        JVMState* jvms, bool allow_inline,
                                        float prof_factor) {
   CallGenerator* cg;
+  guarantee(call_method != NULL, "failed method resolution");
 
   // Dtrace currently doesn't work unless all calls are vanilla
   if (env()->dtrace_method_probes()) {
@@ -130,8 +131,9 @@
 
         // Get an adapter for the MethodHandle.
         ciMethod* target_method = method_handle->get_method_handle_adapter();
-
-        CallGenerator* hit_cg = this->call_generator(target_method, vtable_index, false, jvms, true, prof_factor);
+        CallGenerator* hit_cg = NULL;
+        if (target_method != NULL)
+          hit_cg = this->call_generator(target_method, vtable_index, false, jvms, true, prof_factor);
         if (hit_cg != NULL && hit_cg->is_inline())
           return hit_cg;
       }
@@ -152,8 +154,9 @@
 
       // Get an adapter for the MethodHandle.
       ciMethod* target_method = method_handle->get_invokedynamic_adapter();
-
-      CallGenerator* hit_cg = this->call_generator(target_method, vtable_index, false, jvms, true, prof_factor);
+      CallGenerator* hit_cg = NULL;
+      if (target_method != NULL)
+        hit_cg = this->call_generator(target_method, vtable_index, false, jvms, true, prof_factor);
       if (hit_cg != NULL && hit_cg->is_inline()) {
         CallGenerator* miss_cg = CallGenerator::for_dynamic_call(call_method);
         return CallGenerator::for_predicted_dynamic_call(method_handle, miss_cg, hit_cg, prof_factor);
--- a/src/share/vm/opto/escape.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/opto/escape.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -594,7 +594,7 @@
 
 //
 // Create a new version of orig_phi if necessary. Returns either the newly
-// created phi or an existing phi.  Sets create_new to indicate wheter  a new
+// created phi or an existing phi.  Sets create_new to indicate whether a new
 // phi was created.  Cache the last newly created phi in the node map.
 //
 PhiNode *ConnectionGraph::create_split_phi(PhiNode *orig_phi, int alias_idx, GrowableArray<PhiNode *>  &orig_phi_worklist, PhaseGVN  *igvn, bool &new_created) {
@@ -649,7 +649,7 @@
 }
 
 //
-// Return a new version  of Memory Phi "orig_phi" with the inputs having the
+// Return a new version of Memory Phi "orig_phi" with the inputs having the
 // specified alias index.
 //
 PhiNode *ConnectionGraph::split_memory_phi(PhiNode *orig_phi, int alias_idx, GrowableArray<PhiNode *>  &orig_phi_worklist, PhaseGVN  *igvn) {
@@ -828,11 +828,15 @@
       break;  // hit one of our sentinels
     if (result->is_Mem()) {
       const Type *at = phase->type(result->in(MemNode::Address));
-      if (at != Type::TOP) {
-        assert (at->isa_ptr() != NULL, "pointer type required.");
-        int idx = C->get_alias_index(at->is_ptr());
-        if (idx == alias_idx)
-          break;
+      if (at == Type::TOP)
+        break; // Dead
+      assert (at->isa_ptr() != NULL, "pointer type required.");
+      int idx = C->get_alias_index(at->is_ptr());
+      if (idx == alias_idx)
+        break; // Found
+      if (!is_instance && (at->isa_oopptr() == NULL ||
+                           !at->is_oopptr()->is_known_instance())) {
+        break; // Do not skip store to general memory slice.
       }
       result = result->in(MemNode::Memory);
     }
@@ -902,13 +906,13 @@
     PhiNode *mphi = result->as_Phi();
     assert(mphi->bottom_type() == Type::MEMORY, "memory phi required");
     const TypePtr *t = mphi->adr_type();
-    if (C->get_alias_index(t) != alias_idx) {
-      // Create a new Phi with the specified alias index type.
-      result = split_memory_phi(mphi, alias_idx, orig_phis, phase);
-    } else if (!is_instance) {
+    if (!is_instance) {
       // Push all non-instance Phis on the orig_phis worklist to update inputs
       // during Phase 4 if needed.
       orig_phis.append_if_missing(mphi);
+    } else if (C->get_alias_index(t) != alias_idx) {
+      // Create a new Phi with the specified alias index type.
+      result = split_memory_phi(mphi, alias_idx, orig_phis, phase);
     }
   }
   // the result is either MemNode, PhiNode, InitializeNode.
--- a/src/share/vm/opto/graphKit.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/opto/graphKit.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -3385,10 +3385,15 @@
 #define __ ideal.
 
 void GraphKit::sync_kit(IdealKit& ideal) {
+  set_all_memory(__ merged_memory());
+  set_i_o(__ i_o());
+  set_control(__ ctrl());
+}
+
+void GraphKit::final_sync(IdealKit& ideal) {
   // Final sync IdealKit and graphKit.
   __ drain_delay_transform();
-  set_all_memory(__ merged_memory());
-  set_control(__ ctrl());
+  sync_kit(ideal);
 }
 
 // vanilla/CMS post barrier
@@ -3435,7 +3440,7 @@
   // (Else it's an array (or unknown), and we want more precise card marks.)
   assert(adr != NULL, "");
 
-  IdealKit ideal(gvn(), control(), merged_memory(), true);
+  IdealKit ideal(this, true);
 
   // Convert the pointer to an int prior to doing math on it
   Node* cast = __ CastPX(__ ctrl(), adr);
@@ -3461,7 +3466,7 @@
   }
 
   // Final sync IdealKit and GraphKit.
-  sync_kit(ideal);
+  final_sync(ideal);
 }
 
 // G1 pre/post barriers
@@ -3471,7 +3476,7 @@
                                     Node* val,
                                     const TypeOopPtr* val_type,
                                     BasicType bt) {
-  IdealKit ideal(gvn(), control(), merged_memory(), true);
+  IdealKit ideal(this, true);
 
   Node* tls = __ thread(); // ThreadLocalStorage
 
@@ -3548,7 +3553,7 @@
   } __ end_if();  // (!marking)
 
   // Final sync IdealKit and GraphKit.
-  sync_kit(ideal);
+  final_sync(ideal);
 }
 
 //
@@ -3614,7 +3619,7 @@
   // (Else it's an array (or unknown), and we want more precise card marks.)
   assert(adr != NULL, "");
 
-  IdealKit ideal(gvn(), control(), merged_memory(), true);
+  IdealKit ideal(this, true);
 
   Node* tls = __ thread(); // ThreadLocalStorage
 
@@ -3688,6 +3693,6 @@
   }
 
   // Final sync IdealKit and GraphKit.
-  sync_kit(ideal);
+  final_sync(ideal);
 }
 #undef __
--- a/src/share/vm/opto/graphKit.hpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/opto/graphKit.hpp	Thu Apr 21 08:12:46 2011 -0700
@@ -662,7 +662,9 @@
             && Universe::heap()->can_elide_tlab_store_barriers());
   }
 
+  // Sync Ideal and Graph kits.
   void sync_kit(IdealKit& ideal);
+  void final_sync(IdealKit& ideal);
 
   // vanilla/CMS post barrier
   void write_barrier_post(Node *store, Node* obj,
--- a/src/share/vm/opto/idealKit.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/opto/idealKit.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -38,15 +38,16 @@
 const uint IdealKit::first_var = TypeFunc::Parms + 1;
 
 //----------------------------IdealKit-----------------------------------------
-IdealKit::IdealKit(PhaseGVN &gvn, Node* control, Node* mem, bool delay_all_transforms, bool has_declarations) :
-  _gvn(gvn), C(gvn.C) {
-  _initial_ctrl = control;
-  _initial_memory = mem;
+IdealKit::IdealKit(GraphKit* gkit, bool delay_all_transforms, bool has_declarations) :
+  _gvn(gkit->gvn()), C(gkit->C) {
+  _initial_ctrl = gkit->control();
+  _initial_memory = gkit->merged_memory();
+  _initial_i_o = gkit->i_o();
   _delay_all_transforms = delay_all_transforms;
   _var_ct = 0;
   _cvstate = NULL;
   // We can go memory state free or else we need the entire memory state
-  assert(mem == NULL || mem->Opcode() == Op_MergeMem, "memory must be pre-split");
+  assert(_initial_memory == NULL || _initial_memory->Opcode() == Op_MergeMem, "memory must be pre-split");
   int init_size = 5;
   _pending_cvstates = new (C->node_arena()) GrowableArray<Node*>(C->node_arena(), init_size, 0, 0);
   _delay_transform  = new (C->node_arena()) GrowableArray<Node*>(C->node_arena(), init_size, 0, 0);
@@ -56,6 +57,13 @@
   }
 }
 
+//----------------------------sync_kit-----------------------------------------
+void IdealKit::sync_kit(GraphKit* gkit) {
+  set_all_memory(gkit->merged_memory());
+  set_i_o(gkit->i_o());
+  set_ctrl(gkit->control());
+}
+
 //-------------------------------if_then-------------------------------------
 // Create:  if(left relop right)
 //          /  \
@@ -156,16 +164,14 @@
 // onto the stack.
 void IdealKit::loop(GraphKit* gkit, int nargs, IdealVariable& iv, Node* init, BoolTest::mask relop, Node* limit, float prob, float cnt) {
   assert((state() & (BlockS|LoopS|IfThenS|ElseS)), "bad state for new loop");
-
-  // Sync IdealKit and graphKit.
-  gkit->set_all_memory(this->merged_memory());
-  gkit->set_control(this->ctrl());
-  // Add loop predicate.
-  gkit->add_predicate(nargs);
-  // Update IdealKit memory.
-  this->set_all_memory(gkit->merged_memory());
-  this->set_ctrl(gkit->control());
-
+  if (UseLoopPredicate) {
+    // Sync IdealKit and graphKit.
+    gkit->sync_kit(*this);
+    // Add loop predicate.
+    gkit->add_predicate(nargs);
+    // Update IdealKit memory.
+    sync_kit(gkit);
+  }
   set(iv, init);
   Node* head = make_label(1);
   bind(head);
@@ -280,6 +286,7 @@
   _cvstate = new_cvstate();   // initialize current cvstate
   set_ctrl(_initial_ctrl);    // initialize control in current cvstate
   set_all_memory(_initial_memory);// initialize memory in current cvstate
+  set_i_o(_initial_i_o);      // initialize i_o in current cvstate
   DEBUG_ONLY(_state->push(BlockS));
 }
 
@@ -421,6 +428,9 @@
   // Get the region for the join state
   Node* join_region = join->in(TypeFunc::Control);
   assert(join_region != NULL, "join region must exist");
+  if (join->in(TypeFunc::I_O) == NULL ) {
+    join->set_req(TypeFunc::I_O,  merging->in(TypeFunc::I_O));
+  }
   if (join->in(TypeFunc::Memory) == NULL ) {
     join->set_req(TypeFunc::Memory,  merging->in(TypeFunc::Memory));
     return;
@@ -467,6 +477,20 @@
       mms.set_memory(phi);
     }
   }
+
+  Node* join_io    = join->in(TypeFunc::I_O);
+  Node* merging_io = merging->in(TypeFunc::I_O);
+  if (join_io != merging_io) {
+    PhiNode* phi;
+    if (join_io->is_Phi() && join_io->as_Phi()->region() == join_region) {
+      phi = join_io->as_Phi();
+    } else {
+      phi = PhiNode::make(join_region, join_io, Type::ABIO);
+      phi = (PhiNode*) delay_transform(phi);
+      join->set_req(TypeFunc::I_O, phi);
+    }
+    phi->set_req(slot, merging_io);
+  }
 }
 
 
@@ -477,7 +501,8 @@
                               const char *leaf_name,
                               Node* parm0,
                               Node* parm1,
-                              Node* parm2) {
+                              Node* parm2,
+                              Node* parm3) {
 
   // We only handle taking in RawMem and modifying RawMem
   const TypePtr* adr_type = TypeRawPtr::BOTTOM;
@@ -498,6 +523,7 @@
   if (parm0 != NULL)  call->init_req(TypeFunc::Parms+0, parm0);
   if (parm1 != NULL)  call->init_req(TypeFunc::Parms+1, parm1);
   if (parm2 != NULL)  call->init_req(TypeFunc::Parms+2, parm2);
+  if (parm3 != NULL)  call->init_req(TypeFunc::Parms+3, parm3);
 
   // Node *c = _gvn.transform(call);
   call = (CallNode *) _gvn.transform(call);
@@ -516,3 +542,51 @@
   assert(C->alias_type(call->adr_type()) == C->alias_type(adr_type),
          "call node must be constructed correctly");
 }
+
+
+void IdealKit::make_leaf_call_no_fp(const TypeFunc *slow_call_type,
+                              address slow_call,
+                              const char *leaf_name,
+                              const TypePtr* adr_type,
+                              Node* parm0,
+                              Node* parm1,
+                              Node* parm2,
+                              Node* parm3) {
+
+  // We only handle taking in RawMem and modifying RawMem
+  uint adr_idx = C->get_alias_index(adr_type);
+
+  // Slow-path leaf call
+  int size = slow_call_type->domain()->cnt();
+  CallNode *call =  (CallNode*)new (C, size) CallLeafNoFPNode( slow_call_type, slow_call, leaf_name, adr_type);
+
+  // Set fixed predefined input arguments
+  call->init_req( TypeFunc::Control, ctrl() );
+  call->init_req( TypeFunc::I_O    , top() )     ;   // does no i/o
+  // Narrow memory as only memory input
+  call->init_req( TypeFunc::Memory , memory(adr_idx));
+  call->init_req( TypeFunc::FramePtr, top() /* frameptr() */ );
+  call->init_req( TypeFunc::ReturnAdr, top() );
+
+  if (parm0 != NULL)  call->init_req(TypeFunc::Parms+0, parm0);
+  if (parm1 != NULL)  call->init_req(TypeFunc::Parms+1, parm1);
+  if (parm2 != NULL)  call->init_req(TypeFunc::Parms+2, parm2);
+  if (parm3 != NULL)  call->init_req(TypeFunc::Parms+3, parm3);
+
+  // Node *c = _gvn.transform(call);
+  call = (CallNode *) _gvn.transform(call);
+  Node *c = call; // dbx gets confused with call call->dump()
+
+  // Slow leaf call has no side-effects, sets few values
+
+  set_ctrl(transform( new (C, 1) ProjNode(call,TypeFunc::Control) ));
+
+  // Make memory for the call
+  Node* mem = _gvn.transform( new (C, 1) ProjNode(call, TypeFunc::Memory) );
+
+  // Set the RawPtr memory state only.
+  set_memory(mem, adr_idx);
+
+  assert(C->alias_type(call->adr_type()) == C->alias_type(adr_type),
+         "call node must be constructed correctly");
+}
--- a/src/share/vm/opto/idealKit.hpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/opto/idealKit.hpp	Thu Apr 21 08:12:46 2011 -0700
@@ -108,6 +108,7 @@
   bool _delay_all_transforms;              // flag forcing all transforms to be delayed
   Node* _initial_ctrl;                     // saves initial control until variables declared
   Node* _initial_memory;                   // saves initial memory  until variables declared
+  Node* _initial_i_o;                      // saves initial i_o  until variables declared
 
   PhaseGVN& gvn() const { return _gvn; }
   // Create a new cvstate filled with nulls
@@ -142,17 +143,21 @@
   Node* memory(uint alias_idx);
 
  public:
-  IdealKit(PhaseGVN &gvn, Node* control, Node* memory, bool delay_all_transforms = false, bool has_declarations = false);
+  IdealKit(GraphKit* gkit, bool delay_all_transforms = false, bool has_declarations = false);
   ~IdealKit() {
     stop();
     drain_delay_transform();
   }
+  void sync_kit(GraphKit* gkit);
+
   // Control
   Node* ctrl()                          { return _cvstate->in(TypeFunc::Control); }
   void set_ctrl(Node* ctrl)             { _cvstate->set_req(TypeFunc::Control, ctrl); }
   Node* top()                           { return C->top(); }
   MergeMemNode* merged_memory()         { return _cvstate->in(TypeFunc::Memory)->as_MergeMem(); }
   void set_all_memory(Node* mem)        { _cvstate->set_req(TypeFunc::Memory, mem); }
+  Node* i_o()                           { return _cvstate->in(TypeFunc::I_O); }
+  void set_i_o(Node* c)                 { _cvstate->set_req(TypeFunc::I_O, c); }
   void set(IdealVariable& v, Node* rhs) { _cvstate->set_req(first_var + v.id(), rhs); }
   Node* value(IdealVariable& v)         { return _cvstate->in(first_var + v.id()); }
   void dead(IdealVariable& v)           { set(v, (Node*)NULL); }
@@ -239,7 +244,18 @@
                       const char *leaf_name,
                       Node* parm0,
                       Node* parm1 = NULL,
-                      Node* parm2 = NULL);
+                      Node* parm2 = NULL,
+                      Node* parm3 = NULL);
+
+  void make_leaf_call_no_fp(const TypeFunc *slow_call_type,
+                            address slow_call,
+                            const char *leaf_name,
+                            const TypePtr* adr_type,
+                            Node* parm0,
+                            Node* parm1,
+                            Node* parm2,
+                            Node* parm3);
+
 };
 
 #endif // SHARE_VM_OPTO_IDEALKIT_HPP
--- a/src/share/vm/opto/ifnode.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/opto/ifnode.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -27,6 +27,7 @@
 #include "opto/addnode.hpp"
 #include "opto/cfgnode.hpp"
 #include "opto/connode.hpp"
+#include "opto/loopnode.hpp"
 #include "opto/phaseX.hpp"
 #include "opto/runtime.hpp"
 #include "opto/subnode.hpp"
@@ -222,22 +223,35 @@
 
   // Make a region merging constants and a region merging the rest
   uint req_c = 0;
+  Node* predicate_proj = NULL;
   for (uint ii = 1; ii < r->req(); ii++) {
-    if( phi->in(ii) == con1 ) {
+    if (phi->in(ii) == con1) {
       req_c++;
     }
+    Node* proj = PhaseIdealLoop::find_predicate(r->in(ii));
+    if (proj != NULL) {
+      assert(predicate_proj == NULL, "only one predicate entry expected");
+      predicate_proj = proj;
+    }
   }
+  Node* predicate_c = NULL;
+  Node* predicate_x = NULL;
+
   Node *region_c = new (igvn->C, req_c + 1) RegionNode(req_c + 1);
   Node *phi_c    = con1;
   uint  len      = r->req();
-  Node *region_x = new (igvn->C, len - req_c + 1) RegionNode(len - req_c + 1);
+  Node *region_x = new (igvn->C, len - req_c) RegionNode(len - req_c);
   Node *phi_x    = PhiNode::make_blank(region_x, phi);
   for (uint i = 1, i_c = 1, i_x = 1; i < len; i++) {
-    if( phi->in(i) == con1 ) {
+    if (phi->in(i) == con1) {
       region_c->init_req( i_c++, r  ->in(i) );
+      if (r->in(i) == predicate_proj)
+        predicate_c = predicate_proj;
     } else {
       region_x->init_req( i_x,   r  ->in(i) );
       phi_x   ->init_req( i_x++, phi->in(i) );
+      if (r->in(i) == predicate_proj)
+        predicate_x = predicate_proj;
     }
   }
 
@@ -277,8 +291,20 @@
   // Make the true/false arms
   Node *iff_c_t = phase->transform(new (igvn->C, 1) IfTrueNode (iff_c));
   Node *iff_c_f = phase->transform(new (igvn->C, 1) IfFalseNode(iff_c));
+  if (predicate_c != NULL) {
+    assert(predicate_x == NULL, "only one predicate entry expected");
+    // Clone loop predicates to each path
+    iff_c_t = igvn->clone_loop_predicates(predicate_c, iff_c_t);
+    iff_c_f = igvn->clone_loop_predicates(predicate_c, iff_c_f);
+  }
   Node *iff_x_t = phase->transform(new (igvn->C, 1) IfTrueNode (iff_x));
   Node *iff_x_f = phase->transform(new (igvn->C, 1) IfFalseNode(iff_x));
+  if (predicate_x != NULL) {
+    assert(predicate_c == NULL, "only one predicate entry expected");
+    // Clone loop predicates to each path
+    iff_x_t = igvn->clone_loop_predicates(predicate_x, iff_x_t);
+    iff_x_f = igvn->clone_loop_predicates(predicate_x, iff_x_f);
+  }
 
   // Merge the TRUE paths
   Node *region_s = new (igvn->C, 3) RegionNode(3);
--- a/src/share/vm/opto/library_call.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/opto/library_call.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -1120,7 +1120,7 @@
   const TypeAry* target_array_type = TypeAry::make(TypeInt::CHAR, TypeInt::make(0, target_length, Type::WidenMin));
   const TypeAryPtr* target_type = TypeAryPtr::make(TypePtr::BotPTR, target_array_type, target_array->klass(), true, Type::OffsetBot);
 
-  IdealKit kit(gvn(), control(), merged_memory(), false, true);
+  IdealKit kit(this, false, true);
 #define __ kit.
   Node* zero             = __ ConI(0);
   Node* one              = __ ConI(1);
@@ -1171,7 +1171,7 @@
   __ bind(return_);
 
   // Final sync IdealKit and GraphKit.
-  sync_kit(kit);
+  final_sync(kit);
   Node* result = __ value(rtn);
 #undef __
   C->set_has_loops(true);
@@ -2318,22 +2318,20 @@
         // of it. So we need to emit code to conditionally do the proper type of
         // store.
 
-        IdealKit ideal(gvn(), control(),  merged_memory());
+        IdealKit ideal(this);
 #define __ ideal.
         // QQQ who knows what probability is here??
         __ if_then(heap_base_oop, BoolTest::ne, null(), PROB_UNLIKELY(0.999)); {
           // Sync IdealKit and graphKit.
-          set_all_memory( __ merged_memory());
-          set_control(__ ctrl());
+          sync_kit(ideal);
           Node* st = store_oop_to_unknown(control(), heap_base_oop, adr, adr_type, val, type);
           // Update IdealKit memory.
-          __ set_all_memory(merged_memory());
-          __ set_ctrl(control());
+          __ sync_kit(this);
         } __ else_(); {
           __ store(__ ctrl(), adr, val, type, alias_type->index(), is_volatile);
         } __ end_if();
         // Final sync IdealKit and GraphKit.
-        sync_kit(ideal);
+        final_sync(ideal);
 #undef __
       }
     }
@@ -4294,81 +4292,6 @@
   return true;
 }
 
-
-// constants for computing the copy function
-enum {
-  COPYFUNC_UNALIGNED = 0,
-  COPYFUNC_ALIGNED = 1,                 // src, dest aligned to HeapWordSize
-  COPYFUNC_CONJOINT = 0,
-  COPYFUNC_DISJOINT = 2                 // src != dest, or transfer can descend
-};
-
-// Note:  The condition "disjoint" applies also for overlapping copies
-// where an descending copy is permitted (i.e., dest_offset <= src_offset).
-static address
-select_arraycopy_function(BasicType t, bool aligned, bool disjoint, const char* &name, bool dest_uninitialized) {
-  int selector =
-    (aligned  ? COPYFUNC_ALIGNED  : COPYFUNC_UNALIGNED) +
-    (disjoint ? COPYFUNC_DISJOINT : COPYFUNC_CONJOINT);
-
-#define RETURN_STUB(xxx_arraycopy) { \
-  name = #xxx_arraycopy; \
-  return StubRoutines::xxx_arraycopy(); }
-
-#define RETURN_STUB_PARM(xxx_arraycopy, parm) {           \
-  name = #xxx_arraycopy; \
-  return StubRoutines::xxx_arraycopy(parm); }
-
-  switch (t) {
-  case T_BYTE:
-  case T_BOOLEAN:
-    switch (selector) {
-    case COPYFUNC_CONJOINT | COPYFUNC_UNALIGNED:  RETURN_STUB(jbyte_arraycopy);
-    case COPYFUNC_CONJOINT | COPYFUNC_ALIGNED:    RETURN_STUB(arrayof_jbyte_arraycopy);
-    case COPYFUNC_DISJOINT | COPYFUNC_UNALIGNED:  RETURN_STUB(jbyte_disjoint_arraycopy);
-    case COPYFUNC_DISJOINT | COPYFUNC_ALIGNED:    RETURN_STUB(arrayof_jbyte_disjoint_arraycopy);
-    }
-  case T_CHAR:
-  case T_SHORT:
-    switch (selector) {
-    case COPYFUNC_CONJOINT | COPYFUNC_UNALIGNED:  RETURN_STUB(jshort_arraycopy);
-    case COPYFUNC_CONJOINT | COPYFUNC_ALIGNED:    RETURN_STUB(arrayof_jshort_arraycopy);
-    case COPYFUNC_DISJOINT | COPYFUNC_UNALIGNED:  RETURN_STUB(jshort_disjoint_arraycopy);
-    case COPYFUNC_DISJOINT | COPYFUNC_ALIGNED:    RETURN_STUB(arrayof_jshort_disjoint_arraycopy);
-    }
-  case T_INT:
-  case T_FLOAT:
-    switch (selector) {
-    case COPYFUNC_CONJOINT | COPYFUNC_UNALIGNED:  RETURN_STUB(jint_arraycopy);
-    case COPYFUNC_CONJOINT | COPYFUNC_ALIGNED:    RETURN_STUB(arrayof_jint_arraycopy);
-    case COPYFUNC_DISJOINT | COPYFUNC_UNALIGNED:  RETURN_STUB(jint_disjoint_arraycopy);
-    case COPYFUNC_DISJOINT | COPYFUNC_ALIGNED:    RETURN_STUB(arrayof_jint_disjoint_arraycopy);
-    }
-  case T_DOUBLE:
-  case T_LONG:
-    switch (selector) {
-    case COPYFUNC_CONJOINT | COPYFUNC_UNALIGNED:  RETURN_STUB(jlong_arraycopy);
-    case COPYFUNC_CONJOINT | COPYFUNC_ALIGNED:    RETURN_STUB(arrayof_jlong_arraycopy);
-    case COPYFUNC_DISJOINT | COPYFUNC_UNALIGNED:  RETURN_STUB(jlong_disjoint_arraycopy);
-    case COPYFUNC_DISJOINT | COPYFUNC_ALIGNED:    RETURN_STUB(arrayof_jlong_disjoint_arraycopy);
-    }
-  case T_ARRAY:
-  case T_OBJECT:
-    switch (selector) {
-    case COPYFUNC_CONJOINT | COPYFUNC_UNALIGNED:  RETURN_STUB_PARM(oop_arraycopy, dest_uninitialized);
-    case COPYFUNC_CONJOINT | COPYFUNC_ALIGNED:    RETURN_STUB_PARM(arrayof_oop_arraycopy, dest_uninitialized);
-    case COPYFUNC_DISJOINT | COPYFUNC_UNALIGNED:  RETURN_STUB_PARM(oop_disjoint_arraycopy, dest_uninitialized);
-    case COPYFUNC_DISJOINT | COPYFUNC_ALIGNED:    RETURN_STUB_PARM(arrayof_oop_disjoint_arraycopy, dest_uninitialized);
-    }
-  default:
-    ShouldNotReachHere();
-    return NULL;
-  }
-
-#undef RETURN_STUB
-#undef RETURN_STUB_PARM
-}
-
 //------------------------------basictype2arraycopy----------------------------
 address LibraryCallKit::basictype2arraycopy(BasicType t,
                                             Node* src_offset,
@@ -4401,7 +4324,7 @@
     disjoint = true;
   }
 
-  return select_arraycopy_function(t, aligned, disjoint, name, dest_uninitialized);
+  return StubRoutines::select_arraycopy_function(t, aligned, disjoint, name, dest_uninitialized);
 }
 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/opto/loopPredicate.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -0,0 +1,960 @@
+/*
+ * 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 "opto/loopnode.hpp"
+#include "opto/addnode.hpp"
+#include "opto/callnode.hpp"
+#include "opto/connode.hpp"
+#include "opto/loopnode.hpp"
+#include "opto/mulnode.hpp"
+#include "opto/rootnode.hpp"
+#include "opto/subnode.hpp"
+
+/*
+ * The general idea of Loop Predication is to insert a predicate on the entry
+ * path to a loop, and raise a uncommon trap if the check of the condition fails.
+ * The condition checks are promoted from inside the loop body, and thus
+ * the checks inside the loop could be eliminated. Currently, loop predication
+ * optimization has been applied to remove array range check and loop invariant
+ * checks (such as null checks).
+*/
+
+//-------------------------------is_uncommon_trap_proj----------------------------
+// Return true if proj is the form of "proj->[region->..]call_uct"
+bool PhaseIdealLoop::is_uncommon_trap_proj(ProjNode* proj, Deoptimization::DeoptReason reason) {
+  int path_limit = 10;
+  assert(proj, "invalid argument");
+  Node* out = proj;
+  for (int ct = 0; ct < path_limit; ct++) {
+    out = out->unique_ctrl_out();
+    if (out == NULL)
+      return false;
+    if (out->is_CallStaticJava()) {
+      int req = out->as_CallStaticJava()->uncommon_trap_request();
+      if (req != 0) {
+        Deoptimization::DeoptReason trap_reason = Deoptimization::trap_request_reason(req);
+        if (trap_reason == reason || reason == Deoptimization::Reason_none) {
+           return true;
+        }
+      }
+      return false; // don't do further after call
+    }
+    if (out->Opcode() != Op_Region)
+      return false;
+  }
+  return false;
+}
+
+//-------------------------------is_uncommon_trap_if_pattern-------------------------
+// Return true  for "if(test)-> proj -> ...
+//                          |
+//                          V
+//                      other_proj->[region->..]call_uct"
+//
+// "must_reason_predicate" means the uct reason must be Reason_predicate
+bool PhaseIdealLoop::is_uncommon_trap_if_pattern(ProjNode *proj, Deoptimization::DeoptReason reason) {
+  Node *in0 = proj->in(0);
+  if (!in0->is_If()) return false;
+  // Variation of a dead If node.
+  if (in0->outcnt() < 2)  return false;
+  IfNode* iff = in0->as_If();
+
+  // we need "If(Conv2B(Opaque1(...)))" pattern for reason_predicate
+  if (reason != Deoptimization::Reason_none) {
+    if (iff->in(1)->Opcode() != Op_Conv2B ||
+       iff->in(1)->in(1)->Opcode() != Op_Opaque1) {
+      return false;
+    }
+  }
+
+  ProjNode* other_proj = iff->proj_out(1-proj->_con)->as_Proj();
+  if (is_uncommon_trap_proj(other_proj, reason)) {
+    assert(reason == Deoptimization::Reason_none ||
+           Compile::current()->is_predicate_opaq(iff->in(1)->in(1)), "should be on the list");
+    return true;
+  }
+  return false;
+}
+
+//-------------------------------register_control-------------------------
+void PhaseIdealLoop::register_control(Node* n, IdealLoopTree *loop, Node* pred) {
+  assert(n->is_CFG(), "must be control node");
+  _igvn.register_new_node_with_optimizer(n);
+  loop->_body.push(n);
+  set_loop(n, loop);
+  // When called from beautify_loops() idom is not constructed yet.
+  if (_idom != NULL) {
+    set_idom(n, pred, dom_depth(pred));
+  }
+}
+
+//------------------------------create_new_if_for_predicate------------------------
+// create a new if above the uct_if_pattern for the predicate to be promoted.
+//
+//          before                                after
+//        ----------                           ----------
+//           ctrl                                 ctrl
+//            |                                     |
+//            |                                     |
+//            v                                     v
+//           iff                                 new_iff
+//          /    \                                /      \
+//         /      \                              /        \
+//        v        v                            v          v
+//  uncommon_proj cont_proj                   if_uct     if_cont
+// \      |        |                           |          |
+//  \     |        |                           |          |
+//   v    v        v                           |          v
+//     rgn       loop                          |         iff
+//      |                                      |        /     \
+//      |                                      |       /       \
+//      v                                      |      v         v
+// uncommon_trap                               | uncommon_proj cont_proj
+//                                           \  \    |           |
+//                                            \  \   |           |
+//                                             v  v  v           v
+//                                               rgn           loop
+//                                                |
+//                                                |
+//                                                v
+//                                           uncommon_trap
+//
+//
+// We will create a region to guard the uct call if there is no one there.
+// The true projecttion (if_cont) of the new_iff is returned.
+// This code is also used to clone predicates to clonned loops.
+ProjNode* PhaseIdealLoop::create_new_if_for_predicate(ProjNode* cont_proj, Node* new_entry,
+                                                      Deoptimization::DeoptReason reason) {
+  assert(is_uncommon_trap_if_pattern(cont_proj, reason), "must be a uct if pattern!");
+  IfNode* iff = cont_proj->in(0)->as_If();
+
+  ProjNode *uncommon_proj = iff->proj_out(1 - cont_proj->_con);
+  Node     *rgn   = uncommon_proj->unique_ctrl_out();
+  assert(rgn->is_Region() || rgn->is_Call(), "must be a region or call uct");
+
+  uint proj_index = 1; // region's edge corresponding to uncommon_proj
+  if (!rgn->is_Region()) { // create a region to guard the call
+    assert(rgn->is_Call(), "must be call uct");
+    CallNode* call = rgn->as_Call();
+    IdealLoopTree* loop = get_loop(call);
+    rgn = new (C, 1) RegionNode(1);
+    rgn->add_req(uncommon_proj);
+    register_control(rgn, loop, uncommon_proj);
+    _igvn.hash_delete(call);
+    call->set_req(0, rgn);
+    // When called from beautify_loops() idom is not constructed yet.
+    if (_idom != NULL) {
+      set_idom(call, rgn, dom_depth(rgn));
+    }
+  } else {
+    // Find region's edge corresponding to uncommon_proj
+    for (; proj_index < rgn->req(); proj_index++)
+      if (rgn->in(proj_index) == uncommon_proj) break;
+    assert(proj_index < rgn->req(), "sanity");
+  }
+
+  Node* entry = iff->in(0);
+  if (new_entry != NULL) {
+    // Clonning the predicate to new location.
+    entry = new_entry;
+  }
+  // Create new_iff
+  IdealLoopTree* lp = get_loop(entry);
+  IfNode *new_iff = iff->clone()->as_If();
+  new_iff->set_req(0, entry);
+  register_control(new_iff, lp, entry);
+  Node *if_cont = new (C, 1) IfTrueNode(new_iff);
+  Node *if_uct  = new (C, 1) IfFalseNode(new_iff);
+  if (cont_proj->is_IfFalse()) {
+    // Swap
+    Node* tmp = if_uct; if_uct = if_cont; if_cont = tmp;
+  }
+  register_control(if_cont, lp, new_iff);
+  register_control(if_uct, get_loop(rgn), new_iff);
+
+  // if_uct to rgn
+  _igvn.hash_delete(rgn);
+  rgn->add_req(if_uct);
+  // When called from beautify_loops() idom is not constructed yet.
+  if (_idom != NULL) {
+    Node* ridom = idom(rgn);
+    Node* nrdom = dom_lca(ridom, new_iff);
+    set_idom(rgn, nrdom, dom_depth(rgn));
+  }
+
+  // If rgn has phis add new edges which has the same
+  // value as on original uncommon_proj pass.
+  assert(rgn->in(rgn->req() -1) == if_uct, "new edge should be last");
+  bool has_phi = false;
+  for (DUIterator_Fast imax, i = rgn->fast_outs(imax); i < imax; i++) {
+    Node* use = rgn->fast_out(i);
+    if (use->is_Phi() && use->outcnt() > 0) {
+      assert(use->in(0) == rgn, "");
+      _igvn.hash_delete(use);
+      use->add_req(use->in(proj_index));
+      _igvn._worklist.push(use);
+      has_phi = true;
+    }
+  }
+  assert(!has_phi || rgn->req() > 3, "no phis when region is created");
+
+  if (new_entry == NULL) {
+    // Attach if_cont to iff
+    _igvn.hash_delete(iff);
+    iff->set_req(0, if_cont);
+    if (_idom != NULL) {
+      set_idom(iff, if_cont, dom_depth(iff));
+    }
+  }
+  return if_cont->as_Proj();
+}
+
+//------------------------------create_new_if_for_predicate------------------------
+// Create a new if below new_entry for the predicate to be cloned (IGVN optimization)
+ProjNode* PhaseIterGVN::create_new_if_for_predicate(ProjNode* cont_proj, Node* new_entry,
+                                                    Deoptimization::DeoptReason reason) {
+  assert(new_entry != 0, "only used for clone predicate");
+  assert(PhaseIdealLoop::is_uncommon_trap_if_pattern(cont_proj, reason), "must be a uct if pattern!");
+  IfNode* iff = cont_proj->in(0)->as_If();
+
+  ProjNode *uncommon_proj = iff->proj_out(1 - cont_proj->_con);
+  Node     *rgn   = uncommon_proj->unique_ctrl_out();
+  assert(rgn->is_Region() || rgn->is_Call(), "must be a region or call uct");
+
+  uint proj_index = 1; // region's edge corresponding to uncommon_proj
+  if (!rgn->is_Region()) { // create a region to guard the call
+    assert(rgn->is_Call(), "must be call uct");
+    CallNode* call = rgn->as_Call();
+    rgn = new (C, 1) RegionNode(1);
+    register_new_node_with_optimizer(rgn);
+    rgn->add_req(uncommon_proj);
+    hash_delete(call);
+    call->set_req(0, rgn);
+  } else {
+    // Find region's edge corresponding to uncommon_proj
+    for (; proj_index < rgn->req(); proj_index++)
+      if (rgn->in(proj_index) == uncommon_proj) break;
+    assert(proj_index < rgn->req(), "sanity");
+  }
+
+  // Create new_iff in new location.
+  IfNode *new_iff = iff->clone()->as_If();
+  new_iff->set_req(0, new_entry);
+
+  register_new_node_with_optimizer(new_iff);
+  Node *if_cont = new (C, 1) IfTrueNode(new_iff);
+  Node *if_uct  = new (C, 1) IfFalseNode(new_iff);
+  if (cont_proj->is_IfFalse()) {
+    // Swap
+    Node* tmp = if_uct; if_uct = if_cont; if_cont = tmp;
+  }
+  register_new_node_with_optimizer(if_cont);
+  register_new_node_with_optimizer(if_uct);
+
+  // if_uct to rgn
+  hash_delete(rgn);
+  rgn->add_req(if_uct);
+
+  // If rgn has phis add corresponding new edges which has the same
+  // value as on original uncommon_proj pass.
+  assert(rgn->in(rgn->req() -1) == if_uct, "new edge should be last");
+  bool has_phi = false;
+  for (DUIterator_Fast imax, i = rgn->fast_outs(imax); i < imax; i++) {
+    Node* use = rgn->fast_out(i);
+    if (use->is_Phi() && use->outcnt() > 0) {
+      hash_delete(use);
+      use->add_req(use->in(proj_index));
+      _worklist.push(use);
+      has_phi = true;
+    }
+  }
+  assert(!has_phi || rgn->req() > 3, "no phis when region is created");
+
+  return if_cont->as_Proj();
+}
+
+//--------------------------clone_predicate-----------------------
+ProjNode* PhaseIdealLoop::clone_predicate(ProjNode* predicate_proj, Node* new_entry,
+                                          Deoptimization::DeoptReason reason,
+                                          PhaseIdealLoop* loop_phase,
+                                          PhaseIterGVN* igvn) {
+  ProjNode* new_predicate_proj;
+  if (loop_phase != NULL) {
+    new_predicate_proj = loop_phase->create_new_if_for_predicate(predicate_proj, new_entry, reason);
+  } else {
+    new_predicate_proj =       igvn->create_new_if_for_predicate(predicate_proj, new_entry, reason);
+  }
+  IfNode* iff = new_predicate_proj->in(0)->as_If();
+  Node* ctrl  = iff->in(0);
+
+  // Match original condition since predicate's projections could be swapped.
+  assert(predicate_proj->in(0)->in(1)->in(1)->Opcode()==Op_Opaque1, "must be");
+  Node* opq = new (igvn->C, 2) Opaque1Node(igvn->C, predicate_proj->in(0)->in(1)->in(1)->in(1));
+  igvn->C->add_predicate_opaq(opq);
+
+  Node* bol = new (igvn->C, 2) Conv2BNode(opq);
+  if (loop_phase != NULL) {
+    loop_phase->register_new_node(opq, ctrl);
+    loop_phase->register_new_node(bol, ctrl);
+  } else {
+    igvn->register_new_node_with_optimizer(opq);
+    igvn->register_new_node_with_optimizer(bol);
+  }
+  igvn->hash_delete(iff);
+  iff->set_req(1, bol);
+  return new_predicate_proj;
+}
+
+//--------------------------move_predicate-----------------------
+// Cut predicate from old place and move it to new.
+ProjNode* PhaseIdealLoop::move_predicate(ProjNode* predicate_proj, Node* new_entry,
+                                         Deoptimization::DeoptReason reason,
+                                         PhaseIdealLoop* loop_phase,
+                                         PhaseIterGVN* igvn) {
+  assert(new_entry != NULL, "must be");
+  assert(predicate_proj->in(0)->in(1)->in(1)->Opcode()==Op_Opaque1, "must be");
+  IfNode* iff = predicate_proj->in(0)->as_If();
+  Node* old_entry = iff->in(0);
+
+  // Cut predicate from old place.
+  Node* old = predicate_proj;
+  igvn->_worklist.push(old);
+  for (DUIterator_Last imin, i = old->last_outs(imin); i >= imin; ) {
+    Node* use = old->last_out(i);  // for each use...
+    igvn->hash_delete(use);
+    igvn->_worklist.push(use);
+    // Update use-def info
+    uint uses_found = 0;
+    for (uint j = 0; j < use->req(); j++) {
+      if (use->in(j) == old) {
+        use->set_req(j, old_entry);
+        uses_found++;
+        if (loop_phase != NULL) {
+          if (use->is_CFG()) {
+            // When called from beautify_loops() idom is not constructed yet.
+            if (loop_phase->_idom != NULL)
+              loop_phase->set_idom(use, old_entry, loop_phase->dom_depth(use));
+          } else {
+            loop_phase->set_ctrl(use, old_entry);
+          }
+        }
+      }
+    }
+    i -= uses_found;    // we deleted 1 or more copies of this edge
+  }
+
+  // Move predicate.
+  igvn->hash_delete(iff);
+  iff->set_req(0, new_entry);
+  igvn->_worklist.push(iff);
+
+  if (loop_phase != NULL) {
+    // Fix up idom and ctrl.
+    loop_phase->set_ctrl(iff->in(1), new_entry);
+    loop_phase->set_ctrl(iff->in(1)->in(1), new_entry);
+    // When called from beautify_loops() idom is not constructed yet.
+    if (loop_phase->_idom != NULL)
+      loop_phase->set_idom(iff, new_entry, loop_phase->dom_depth(iff));
+  }
+
+  return predicate_proj;
+}
+
+//--------------------------clone_loop_predicates-----------------------
+// Interface from IGVN
+Node* PhaseIterGVN::clone_loop_predicates(Node* old_entry, Node* new_entry) {
+  return PhaseIdealLoop::clone_loop_predicates(old_entry, new_entry, false, NULL, this);
+}
+Node* PhaseIterGVN::move_loop_predicates(Node* old_entry, Node* new_entry) {
+  return PhaseIdealLoop::clone_loop_predicates(old_entry, new_entry, true, NULL, this);
+}
+
+// Interface from PhaseIdealLoop
+Node* PhaseIdealLoop::clone_loop_predicates(Node* old_entry, Node* new_entry) {
+  return clone_loop_predicates(old_entry, new_entry, false, this, &this->_igvn);
+}
+Node* PhaseIdealLoop::move_loop_predicates(Node* old_entry, Node* new_entry) {
+  return clone_loop_predicates(old_entry, new_entry, true, this, &this->_igvn);
+}
+
+// Clone loop predicates to cloned loops (peeled, unswitched, split_if).
+Node* PhaseIdealLoop::clone_loop_predicates(Node* old_entry, Node* new_entry,
+                                                bool move_predicates,
+                                                PhaseIdealLoop* loop_phase,
+                                                PhaseIterGVN* igvn) {
+#ifdef ASSERT
+  if (new_entry == NULL || !(new_entry->is_Proj() || new_entry->is_Region() || new_entry->is_SafePoint())) {
+    if (new_entry != NULL)
+      new_entry->dump();
+    assert(false, "not IfTrue, IfFalse, Region or SafePoint");
+  }
+#endif
+  // Search original predicates
+  Node* entry = old_entry;
+  if (UseLoopPredicate) {
+    ProjNode* predicate_proj = find_predicate_insertion_point(entry, Deoptimization::Reason_predicate);
+    if (predicate_proj != NULL) { // right pattern that can be used by loop predication
+      assert(entry->in(0)->in(1)->in(1)->Opcode()==Op_Opaque1, "must be");
+      if (move_predicates) {
+        new_entry =  move_predicate(predicate_proj, new_entry,
+                                    Deoptimization::Reason_predicate,
+                                    loop_phase, igvn);
+        assert(new_entry == predicate_proj, "old predicate fall through projection");
+      } else {
+        // clone predicate
+        new_entry = clone_predicate(predicate_proj, new_entry,
+                                    Deoptimization::Reason_predicate,
+                                    loop_phase, igvn);
+        assert(new_entry != NULL && new_entry->is_Proj(), "IfTrue or IfFalse after clone predicate");
+      }
+      if (TraceLoopPredicate) {
+        tty->print_cr("Loop Predicate %s: ", move_predicates ? "moved" : "cloned");
+        debug_only( new_entry->in(0)->dump(); )
+      }
+    }
+  }
+  return new_entry;
+}
+
+//--------------------------eliminate_loop_predicates-----------------------
+void PhaseIdealLoop::eliminate_loop_predicates(Node* entry) {
+  if (UseLoopPredicate) {
+    ProjNode* predicate_proj = find_predicate_insertion_point(entry, Deoptimization::Reason_predicate);
+    if (predicate_proj != NULL) { // right pattern that can be used by loop predication
+      Node* n = entry->in(0)->in(1)->in(1);
+      assert(n->Opcode()==Op_Opaque1, "must be");
+      // Remove Opaque1 node from predicates list.
+      // IGVN will remove this predicate check.
+      _igvn.replace_node(n, n->in(1));
+    }
+  }
+}
+
+//--------------------------skip_loop_predicates------------------------------
+// Skip related predicates.
+Node* PhaseIdealLoop::skip_loop_predicates(Node* entry) {
+  Node* predicate = NULL;
+  if (UseLoopPredicate) {
+    predicate = find_predicate_insertion_point(entry, Deoptimization::Reason_predicate);
+    if (predicate != NULL) { // right pattern that can be used by loop predication
+      assert(entry->is_Proj() && entry->in(0)->in(1)->in(1)->Opcode()==Op_Opaque1, "must be");
+      IfNode* iff = entry->in(0)->as_If();
+      ProjNode* uncommon_proj = iff->proj_out(1 - entry->as_Proj()->_con);
+      Node* rgn = uncommon_proj->unique_ctrl_out();
+      assert(rgn->is_Region() || rgn->is_Call(), "must be a region or call uct");
+      entry = entry->in(0)->in(0);
+      while (entry != NULL && entry->is_Proj() && entry->in(0)->is_If()) {
+        uncommon_proj = entry->in(0)->as_If()->proj_out(1 - entry->as_Proj()->_con);
+        if (uncommon_proj->unique_ctrl_out() != rgn)
+          break;
+        entry = entry->in(0)->in(0);
+      }
+    }
+  }
+  return entry;
+}
+
+//--------------------------find_predicate_insertion_point-------------------
+// Find a good location to insert a predicate
+ProjNode* PhaseIdealLoop::find_predicate_insertion_point(Node* start_c, Deoptimization::DeoptReason reason) {
+  if (start_c == NULL || !start_c->is_Proj())
+    return NULL;
+  if (is_uncommon_trap_if_pattern(start_c->as_Proj(), reason)) {
+    return start_c->as_Proj();
+  }
+  return NULL;
+}
+
+//--------------------------find_predicate------------------------------------
+// Find a predicate
+Node* PhaseIdealLoop::find_predicate(Node* entry) {
+  Node* predicate = NULL;
+  if (UseLoopPredicate) {
+    predicate = find_predicate_insertion_point(entry, Deoptimization::Reason_predicate);
+    if (predicate != NULL) { // right pattern that can be used by loop predication
+      assert(entry->in(0)->in(1)->in(1)->Opcode()==Op_Opaque1, "must be");
+      return entry;
+    }
+  }
+  return NULL;
+}
+
+//------------------------------Invariance-----------------------------------
+// Helper class for loop_predication_impl to compute invariance on the fly and
+// clone invariants.
+class Invariance : public StackObj {
+  VectorSet _visited, _invariant;
+  Node_Stack _stack;
+  VectorSet _clone_visited;
+  Node_List _old_new; // map of old to new (clone)
+  IdealLoopTree* _lpt;
+  PhaseIdealLoop* _phase;
+
+  // Helper function to set up the invariance for invariance computation
+  // If n is a known invariant, set up directly. Otherwise, look up the
+  // the possibility to push n onto the stack for further processing.
+  void visit(Node* use, Node* n) {
+    if (_lpt->is_invariant(n)) { // known invariant
+      _invariant.set(n->_idx);
+    } else if (!n->is_CFG()) {
+      Node *n_ctrl = _phase->ctrl_or_self(n);
+      Node *u_ctrl = _phase->ctrl_or_self(use); // self if use is a CFG
+      if (_phase->is_dominator(n_ctrl, u_ctrl)) {
+        _stack.push(n, n->in(0) == NULL ? 1 : 0);
+      }
+    }
+  }
+
+  // Compute invariance for "the_node" and (possibly) all its inputs recursively
+  // on the fly
+  void compute_invariance(Node* n) {
+    assert(_visited.test(n->_idx), "must be");
+    visit(n, n);
+    while (_stack.is_nonempty()) {
+      Node*  n = _stack.node();
+      uint idx = _stack.index();
+      if (idx == n->req()) { // all inputs are processed
+        _stack.pop();
+        // n is invariant if it's inputs are all invariant
+        bool all_inputs_invariant = true;
+        for (uint i = 0; i < n->req(); i++) {
+          Node* in = n->in(i);
+          if (in == NULL) continue;
+          assert(_visited.test(in->_idx), "must have visited input");
+          if (!_invariant.test(in->_idx)) { // bad guy
+            all_inputs_invariant = false;
+            break;
+          }
+        }
+        if (all_inputs_invariant) {
+          _invariant.set(n->_idx); // I am a invariant too
+        }
+      } else { // process next input
+        _stack.set_index(idx + 1);
+        Node* m = n->in(idx);
+        if (m != NULL && !_visited.test_set(m->_idx)) {
+          visit(n, m);
+        }
+      }
+    }
+  }
+
+  // Helper function to set up _old_new map for clone_nodes.
+  // If n is a known invariant, set up directly ("clone" of n == n).
+  // Otherwise, push n onto the stack for real cloning.
+  void clone_visit(Node* n) {
+    assert(_invariant.test(n->_idx), "must be invariant");
+    if (_lpt->is_invariant(n)) { // known invariant
+      _old_new.map(n->_idx, n);
+    } else { // to be cloned
+      assert(!n->is_CFG(), "should not see CFG here");
+      _stack.push(n, n->in(0) == NULL ? 1 : 0);
+    }
+  }
+
+  // Clone "n" and (possibly) all its inputs recursively
+  void clone_nodes(Node* n, Node* ctrl) {
+    clone_visit(n);
+    while (_stack.is_nonempty()) {
+      Node*  n = _stack.node();
+      uint idx = _stack.index();
+      if (idx == n->req()) { // all inputs processed, clone n!
+        _stack.pop();
+        // clone invariant node
+        Node* n_cl = n->clone();
+        _old_new.map(n->_idx, n_cl);
+        _phase->register_new_node(n_cl, ctrl);
+        for (uint i = 0; i < n->req(); i++) {
+          Node* in = n_cl->in(i);
+          if (in == NULL) continue;
+          n_cl->set_req(i, _old_new[in->_idx]);
+        }
+      } else { // process next input
+        _stack.set_index(idx + 1);
+        Node* m = n->in(idx);
+        if (m != NULL && !_clone_visited.test_set(m->_idx)) {
+          clone_visit(m); // visit the input
+        }
+      }
+    }
+  }
+
+ public:
+  Invariance(Arena* area, IdealLoopTree* lpt) :
+    _lpt(lpt), _phase(lpt->_phase),
+    _visited(area), _invariant(area), _stack(area, 10 /* guess */),
+    _clone_visited(area), _old_new(area)
+  {}
+
+  // Map old to n for invariance computation and clone
+  void map_ctrl(Node* old, Node* n) {
+    assert(old->is_CFG() && n->is_CFG(), "must be");
+    _old_new.map(old->_idx, n); // "clone" of old is n
+    _invariant.set(old->_idx);  // old is invariant
+    _clone_visited.set(old->_idx);
+  }
+
+  // Driver function to compute invariance
+  bool is_invariant(Node* n) {
+    if (!_visited.test_set(n->_idx))
+      compute_invariance(n);
+    return (_invariant.test(n->_idx) != 0);
+  }
+
+  // Driver function to clone invariant
+  Node* clone(Node* n, Node* ctrl) {
+    assert(ctrl->is_CFG(), "must be");
+    assert(_invariant.test(n->_idx), "must be an invariant");
+    if (!_clone_visited.test(n->_idx))
+      clone_nodes(n, ctrl);
+    return _old_new[n->_idx];
+  }
+};
+
+//------------------------------is_range_check_if -----------------------------------
+// Returns true if the predicate of iff is in "scale*iv + offset u< load_range(ptr)" format
+// Note: this function is particularly designed for loop predication. We require load_range
+//       and offset to be loop invariant computed on the fly by "invar"
+bool IdealLoopTree::is_range_check_if(IfNode *iff, PhaseIdealLoop *phase, Invariance& invar) const {
+  if (!is_loop_exit(iff)) {
+    return false;
+  }
+  if (!iff->in(1)->is_Bool()) {
+    return false;
+  }
+  const BoolNode *bol = iff->in(1)->as_Bool();
+  if (bol->_test._test != BoolTest::lt) {
+    return false;
+  }
+  if (!bol->in(1)->is_Cmp()) {
+    return false;
+  }
+  const CmpNode *cmp = bol->in(1)->as_Cmp();
+  if (cmp->Opcode() != Op_CmpU) {
+    return false;
+  }
+  Node* range = cmp->in(2);
+  if (range->Opcode() != Op_LoadRange) {
+    const TypeInt* tint = phase->_igvn.type(range)->isa_int();
+    if (!OptimizeFill || tint == NULL || tint->empty() || tint->_lo < 0) {
+      // Allow predication on positive values that aren't LoadRanges.
+      // This allows optimization of loops where the length of the
+      // array is a known value and doesn't need to be loaded back
+      // from the array.
+      return false;
+    }
+  }
+  if (!invar.is_invariant(range)) {
+    return false;
+  }
+  Node *iv     = _head->as_CountedLoop()->phi();
+  int   scale  = 0;
+  Node *offset = NULL;
+  if (!phase->is_scaled_iv_plus_offset(cmp->in(1), iv, &scale, &offset)) {
+    return false;
+  }
+  if (offset && !invar.is_invariant(offset)) { // offset must be invariant
+    return false;
+  }
+  return true;
+}
+
+//------------------------------rc_predicate-----------------------------------
+// Create a range check predicate
+//
+// for (i = init; i < limit; i += stride) {
+//    a[scale*i+offset]
+// }
+//
+// Compute max(scale*i + offset) for init <= i < limit and build the predicate
+// as "max(scale*i + offset) u< a.length".
+//
+// There are two cases for max(scale*i + offset):
+// (1) stride*scale > 0
+//   max(scale*i + offset) = scale*(limit-stride) + offset
+// (2) stride*scale < 0
+//   max(scale*i + offset) = scale*init + offset
+BoolNode* PhaseIdealLoop::rc_predicate(Node* ctrl,
+                                       int scale, Node* offset,
+                                       Node* init, Node* limit, Node* stride,
+                                       Node* range, bool upper) {
+  DEBUG_ONLY(ttyLocker ttyl);
+  if (TraceLoopPredicate) tty->print("rc_predicate ");
+
+  Node* max_idx_expr  = init;
+  int stride_con = stride->get_int();
+  if ((stride_con > 0) == (scale > 0) == upper) {
+    max_idx_expr = new (C, 3) SubINode(limit, stride);
+    register_new_node(max_idx_expr, ctrl);
+    if (TraceLoopPredicate) tty->print("(limit - stride) ");
+  } else {
+    if (TraceLoopPredicate) tty->print("init ");
+  }
+
+  if (scale != 1) {
+    ConNode* con_scale = _igvn.intcon(scale);
+    max_idx_expr = new (C, 3) MulINode(max_idx_expr, con_scale);
+    register_new_node(max_idx_expr, ctrl);
+    if (TraceLoopPredicate) tty->print("* %d ", scale);
+  }
+
+  if (offset && (!offset->is_Con() || offset->get_int() != 0)){
+    max_idx_expr = new (C, 3) AddINode(max_idx_expr, offset);
+    register_new_node(max_idx_expr, ctrl);
+    if (TraceLoopPredicate)
+      if (offset->is_Con()) tty->print("+ %d ", offset->get_int());
+      else tty->print("+ offset ");
+  }
+
+  CmpUNode* cmp = new (C, 3) CmpUNode(max_idx_expr, range);
+  register_new_node(cmp, ctrl);
+  BoolNode* bol = new (C, 2) BoolNode(cmp, BoolTest::lt);
+  register_new_node(bol, ctrl);
+
+  if (TraceLoopPredicate) tty->print_cr("<u range");
+  return bol;
+}
+
+//------------------------------ loop_predication_impl--------------------------
+// Insert loop predicates for null checks and range checks
+bool PhaseIdealLoop::loop_predication_impl(IdealLoopTree *loop) {
+  if (!UseLoopPredicate) return false;
+
+  if (!loop->_head->is_Loop()) {
+    // Could be a simple region when irreducible loops are present.
+    return false;
+  }
+
+  if (loop->_head->unique_ctrl_out()->Opcode() == Op_NeverBranch) {
+    // do nothing for infinite loops
+    return false;
+  }
+
+  CountedLoopNode *cl = NULL;
+  if (loop->_head->is_CountedLoop()) {
+    cl = loop->_head->as_CountedLoop();
+    // do nothing for iteration-splitted loops
+    if (!cl->is_normal_loop()) return false;
+  }
+
+  LoopNode *lpn  = loop->_head->as_Loop();
+  Node* entry = lpn->in(LoopNode::EntryControl);
+
+  ProjNode *predicate_proj = find_predicate_insertion_point(entry, Deoptimization::Reason_predicate);
+  if (!predicate_proj) {
+#ifndef PRODUCT
+    if (TraceLoopPredicate) {
+      tty->print("missing predicate:");
+      loop->dump_head();
+      lpn->dump(1);
+    }
+#endif
+    return false;
+  }
+  ConNode* zero = _igvn.intcon(0);
+  set_ctrl(zero, C->root());
+
+  ResourceArea *area = Thread::current()->resource_area();
+  Invariance invar(area, loop);
+
+  // Create list of if-projs such that a newer proj dominates all older
+  // projs in the list, and they all dominate loop->tail()
+  Node_List if_proj_list(area);
+  LoopNode *head  = loop->_head->as_Loop();
+  Node *current_proj = loop->tail(); //start from tail
+  while (current_proj != head) {
+    if (loop == get_loop(current_proj) && // still in the loop ?
+        current_proj->is_Proj()        && // is a projection  ?
+        current_proj->in(0)->Opcode() == Op_If) { // is a if projection ?
+      if_proj_list.push(current_proj);
+    }
+    current_proj = idom(current_proj);
+  }
+
+  bool hoisted = false; // true if at least one proj is promoted
+  while (if_proj_list.size() > 0) {
+    // Following are changed to nonnull when a predicate can be hoisted
+    ProjNode* new_predicate_proj = NULL;
+
+    ProjNode* proj = if_proj_list.pop()->as_Proj();
+    IfNode*   iff  = proj->in(0)->as_If();
+
+    if (!is_uncommon_trap_if_pattern(proj, Deoptimization::Reason_none)) {
+      if (loop->is_loop_exit(iff)) {
+        // stop processing the remaining projs in the list because the execution of them
+        // depends on the condition of "iff" (iff->in(1)).
+        break;
+      } else {
+        // Both arms are inside the loop. There are two cases:
+        // (1) there is one backward branch. In this case, any remaining proj
+        //     in the if_proj list post-dominates "iff". So, the condition of "iff"
+        //     does not determine the execution the remining projs directly, and we
+        //     can safely continue.
+        // (2) both arms are forwarded, i.e. a diamond shape. In this case, "proj"
+        //     does not dominate loop->tail(), so it can not be in the if_proj list.
+        continue;
+      }
+    }
+
+    Node*     test = iff->in(1);
+    if (!test->is_Bool()){ //Conv2B, ...
+      continue;
+    }
+    BoolNode* bol = test->as_Bool();
+    if (invar.is_invariant(bol)) {
+      // Invariant test
+      new_predicate_proj = create_new_if_for_predicate(predicate_proj, NULL,
+                                                       Deoptimization::Reason_predicate);
+      Node* ctrl = new_predicate_proj->in(0)->as_If()->in(0);
+      BoolNode* new_predicate_bol = invar.clone(bol, ctrl)->as_Bool();
+
+      // Negate test if necessary
+      bool negated = false;
+      if (proj->_con != predicate_proj->_con) {
+        new_predicate_bol = new (C, 2) BoolNode(new_predicate_bol->in(1), new_predicate_bol->_test.negate());
+        register_new_node(new_predicate_bol, ctrl);
+        negated = true;
+      }
+      IfNode* new_predicate_iff = new_predicate_proj->in(0)->as_If();
+      _igvn.hash_delete(new_predicate_iff);
+      new_predicate_iff->set_req(1, new_predicate_bol);
+#ifndef PRODUCT
+      if (TraceLoopPredicate) {
+        tty->print("Predicate invariant if%s: %d ", negated ? " negated" : "", new_predicate_iff->_idx);
+        loop->dump_head();
+      } else if (TraceLoopOpts) {
+        tty->print("Predicate IC ");
+        loop->dump_head();
+      }
+#endif
+    } else if (cl != NULL && loop->is_range_check_if(iff, this, invar)) {
+      assert(proj->_con == predicate_proj->_con, "must match");
+
+      // Range check for counted loops
+      const Node*    cmp    = bol->in(1)->as_Cmp();
+      Node*          idx    = cmp->in(1);
+      assert(!invar.is_invariant(idx), "index is variant");
+      assert(cmp->in(2)->Opcode() == Op_LoadRange || OptimizeFill, "must be");
+      Node* rng = cmp->in(2);
+      assert(invar.is_invariant(rng), "range must be invariant");
+      int scale    = 1;
+      Node* offset = zero;
+      bool ok = is_scaled_iv_plus_offset(idx, cl->phi(), &scale, &offset);
+      assert(ok, "must be index expression");
+
+      Node* init    = cl->init_trip();
+      Node* limit   = cl->limit();
+      Node* stride  = cl->stride();
+
+      // Build if's for the upper and lower bound tests.  The
+      // lower_bound test will dominate the upper bound test and all
+      // cloned or created nodes will use the lower bound test as
+      // their declared control.
+      ProjNode* lower_bound_proj = create_new_if_for_predicate(predicate_proj, NULL, Deoptimization::Reason_predicate);
+      ProjNode* upper_bound_proj = create_new_if_for_predicate(predicate_proj, NULL, Deoptimization::Reason_predicate);
+      assert(upper_bound_proj->in(0)->as_If()->in(0) == lower_bound_proj, "should dominate");
+      Node *ctrl = lower_bound_proj->in(0)->as_If()->in(0);
+
+      // Perform cloning to keep Invariance state correct since the
+      // late schedule will place invariant things in the loop.
+      rng = invar.clone(rng, ctrl);
+      if (offset && offset != zero) {
+        assert(invar.is_invariant(offset), "offset must be loop invariant");
+        offset = invar.clone(offset, ctrl);
+      }
+
+      // Test the lower bound
+      Node*  lower_bound_bol = rc_predicate(ctrl, scale, offset, init, limit, stride, rng, false);
+      IfNode* lower_bound_iff = lower_bound_proj->in(0)->as_If();
+      _igvn.hash_delete(lower_bound_iff);
+      lower_bound_iff->set_req(1, lower_bound_bol);
+      if (TraceLoopPredicate) tty->print_cr("lower bound check if: %d", lower_bound_iff->_idx);
+
+      // Test the upper bound
+      Node* upper_bound_bol = rc_predicate(ctrl, scale, offset, init, limit, stride, rng, true);
+      IfNode* upper_bound_iff = upper_bound_proj->in(0)->as_If();
+      _igvn.hash_delete(upper_bound_iff);
+      upper_bound_iff->set_req(1, upper_bound_bol);
+      if (TraceLoopPredicate) tty->print_cr("upper bound check if: %d", lower_bound_iff->_idx);
+
+      // Fall through into rest of the clean up code which will move
+      // any dependent nodes onto the upper bound test.
+      new_predicate_proj = upper_bound_proj;
+
+#ifndef PRODUCT
+      if (TraceLoopOpts && !TraceLoopPredicate) {
+        tty->print("Predicate RC ");
+        loop->dump_head();
+      }
+#endif
+    } else {
+      // Loop variant check (for example, range check in non-counted loop)
+      // with uncommon trap.
+      continue;
+    }
+    assert(new_predicate_proj != NULL, "sanity");
+    // Success - attach condition (new_predicate_bol) to predicate if
+    invar.map_ctrl(proj, new_predicate_proj); // so that invariance test can be appropriate
+
+    // Eliminate the old If in the loop body
+    dominated_by( new_predicate_proj, iff, proj->_con != new_predicate_proj->_con );
+
+    hoisted = true;
+    C->set_major_progress();
+  } // end while
+
+#ifndef PRODUCT
+  // report that the loop predication has been actually performed
+  // for this loop
+  if (TraceLoopPredicate && hoisted) {
+    tty->print("Loop Predication Performed:");
+    loop->dump_head();
+  }
+#endif
+
+  return hoisted;
+}
+
+//------------------------------loop_predication--------------------------------
+// driver routine for loop predication optimization
+bool IdealLoopTree::loop_predication( PhaseIdealLoop *phase) {
+  bool hoisted = false;
+  // Recursively promote predicates
+  if (_child) {
+    hoisted = _child->loop_predication( phase);
+  }
+
+  // self
+  if (!_irreducible && !tail()->is_top()) {
+    hoisted |= phase->loop_predication_impl(this);
+  }
+
+  if (_next) { //sibling
+    hoisted |= _next->loop_predication( phase);
+  }
+
+  return hoisted;
+}
+
--- a/src/share/vm/opto/loopTransform.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/opto/loopTransform.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -63,6 +63,46 @@
   }
 }
 
+//------------------------------compute_exact_trip_count-----------------------
+// Compute loop exact trip count if possible. Do not recalculate trip count for
+// split loops (pre-main-post) which have their limits and inits behind Opaque node.
+void IdealLoopTree::compute_exact_trip_count( PhaseIdealLoop *phase ) {
+  if (!_head->as_Loop()->is_valid_counted_loop()) {
+    return;
+  }
+  CountedLoopNode* cl = _head->as_CountedLoop();
+  // Trip count may become nonexact for iteration split loops since
+  // RCE modifies limits. Note, _trip_count value is not reset since
+  // it is used to limit unrolling of main loop.
+  cl->set_nonexact_trip_count();
+
+  // Loop's test should be part of loop.
+  if (!phase->is_member(this, phase->get_ctrl(cl->loopexit()->in(CountedLoopEndNode::TestValue))))
+    return; // Infinite loop
+
+#ifdef ASSERT
+  BoolTest::mask bt = cl->loopexit()->test_trip();
+  assert(bt == BoolTest::lt || bt == BoolTest::gt ||
+         bt == BoolTest::ne, "canonical test is expected");
+#endif
+
+  Node* init_n = cl->init_trip();
+  Node* limit_n = cl->limit();
+  if (init_n  != NULL &&  init_n->is_Con() &&
+      limit_n != NULL && limit_n->is_Con()) {
+    // Use longs to avoid integer overflow.
+    int stride_con  = cl->stride_con();
+    long init_con   = cl->init_trip()->get_int();
+    long limit_con  = cl->limit()->get_int();
+    int stride_m    = stride_con - (stride_con > 0 ? 1 : -1);
+    long trip_count = (limit_con - init_con + stride_m)/stride_con;
+    if (trip_count > 0 && (julong)trip_count < (julong)max_juint) {
+      // Set exact trip count.
+      cl->set_exact_trip_count((uint)trip_count);
+    }
+  }
+}
+
 //------------------------------compute_profile_trip_cnt----------------------------
 // Compute loop trip count from profile data as
 //    (backedge_count + loop_exit_count) / loop_exit_count
@@ -301,6 +341,132 @@
 //         peeled-loop backedge has 2 users.
 // Step 3: Cut the backedge on the clone (so its not a loop) and remove the
 //         extra backedge user.
+//
+//                   orig
+//
+//                  stmt1
+//                    |
+//                    v
+//              loop predicate
+//                    |
+//                    v
+//                   loop<----+
+//                     |      |
+//                   stmt2    |
+//                     |      |
+//                     v      |
+//                    if      ^
+//                   / \      |
+//                  /   \     |
+//                 v     v    |
+//               false true   |
+//               /       \    |
+//              /         ----+
+//             |
+//             v
+//           exit
+//
+//
+//            after clone loop
+//
+//                   stmt1
+//                     |
+//                     v
+//               loop predicate
+//                 /       \
+//        clone   /         \   orig
+//               /           \
+//              /             \
+//             v               v
+//   +---->loop clone          loop<----+
+//   |      |                    |      |
+//   |    stmt2 clone          stmt2    |
+//   |      |                    |      |
+//   |      v                    v      |
+//   ^      if clone            If      ^
+//   |      / \                / \      |
+//   |     /   \              /   \     |
+//   |    v     v            v     v    |
+//   |    true  false      false true   |
+//   |    /         \      /       \    |
+//   +----           \    /         ----+
+//                    \  /
+//                    1v v2
+//                  region
+//                     |
+//                     v
+//                   exit
+//
+//
+//         after peel and predicate move
+//
+//                   stmt1
+//                    /
+//                   /
+//        clone     /            orig
+//                 /
+//                /              +----------+
+//               /               |          |
+//              /          loop predicate   |
+//             /                 |          |
+//            v                  v          |
+//   TOP-->loop clone          loop<----+   |
+//          |                    |      |   |
+//        stmt2 clone          stmt2    |   |
+//          |                    |      |   ^
+//          v                    v      |   |
+//          if clone            If      ^   |
+//          / \                / \      |   |
+//         /   \              /   \     |   |
+//        v     v            v     v    |   |
+//      true   false      false  true   |   |
+//        |         \      /       \    |   |
+//        |          \    /         ----+   ^
+//        |           \  /                  |
+//        |           1v v2                 |
+//        v         region                  |
+//        |            |                    |
+//        |            v                    |
+//        |          exit                   |
+//        |                                 |
+//        +--------------->-----------------+
+//
+//
+//              final graph
+//
+//                  stmt1
+//                    |
+//                    v
+//                  stmt2 clone
+//                    |
+//                    v
+//                   if clone
+//                  / |
+//                 /  |
+//                v   v
+//            false  true
+//             |      |
+//             |      v
+//             | loop predicate
+//             |      |
+//             |      v
+//             |     loop<----+
+//             |      |       |
+//             |    stmt2     |
+//             |      |       |
+//             |      v       |
+//             v      if      ^
+//             |     /  \     |
+//             |    /    \    |
+//             |   v     v    |
+//             | false  true  |
+//             |  |        \  |
+//             v  v         --+
+//            region
+//              |
+//              v
+//             exit
+//
 void PhaseIdealLoop::do_peeling( IdealLoopTree *loop, Node_List &old_new ) {
 
   C->set_major_progress();
@@ -315,9 +481,10 @@
     loop->dump_head();
   }
 #endif
-  Node *h = loop->_head;
-  if (h->is_CountedLoop()) {
-    CountedLoopNode *cl = h->as_CountedLoop();
+  Node* head = loop->_head;
+  bool counted_loop = head->is_CountedLoop();
+  if (counted_loop) {
+    CountedLoopNode *cl = head->as_CountedLoop();
     assert(cl->trip_count() > 0, "peeling a fully unrolled loop");
     cl->set_trip_count(cl->trip_count() - 1);
     if (cl->is_main_loop()) {
@@ -330,11 +497,11 @@
 #endif
     }
   }
+  Node* entry = head->in(LoopNode::EntryControl);
 
   // Step 1: Clone the loop body.  The clone becomes the peeled iteration.
   //         The pre-loop illegally has 2 control users (old & new loops).
-  clone_loop( loop, old_new, dom_depth(loop->_head) );
-
+  clone_loop( loop, old_new, dom_depth(head) );
 
   // Step 2: Make the old-loop fall-in edges point to the peeled iteration.
   //         Do this by making the old-loop fall-in edges act as if they came
@@ -342,12 +509,15 @@
   //         backedges) and then map to the new peeled iteration.  This leaves
   //         the pre-loop with only 1 user (the new peeled iteration), but the
   //         peeled-loop backedge has 2 users.
-  for (DUIterator_Fast jmax, j = loop->_head->fast_outs(jmax); j < jmax; j++) {
-    Node* old = loop->_head->fast_out(j);
-    if( old->in(0) == loop->_head && old->req() == 3 &&
-        (old->is_Loop() || old->is_Phi()) ) {
-      Node *new_exit_value = old_new[old->in(LoopNode::LoopBackControl)->_idx];
-      if( !new_exit_value )     // Backedge value is ALSO loop invariant?
+  Node* new_exit_value = old_new[head->in(LoopNode::LoopBackControl)->_idx];
+  new_exit_value = move_loop_predicates(entry, new_exit_value);
+  _igvn.hash_delete(head);
+  head->set_req(LoopNode::EntryControl, new_exit_value);
+  for (DUIterator_Fast jmax, j = head->fast_outs(jmax); j < jmax; j++) {
+    Node* old = head->fast_out(j);
+    if (old->in(0) == loop->_head && old->req() == 3 && old->is_Phi()) {
+      new_exit_value = old_new[old->in(LoopNode::LoopBackControl)->_idx];
+      if (!new_exit_value )     // Backedge value is ALSO loop invariant?
         // Then loop body backedge value remains the same.
         new_exit_value = old->in(LoopNode::LoopBackControl);
       _igvn.hash_delete(old);
@@ -358,12 +528,12 @@
 
   // Step 3: Cut the backedge on the clone (so its not a loop) and remove the
   //         extra backedge user.
-  Node *nnn = old_new[loop->_head->_idx];
-  _igvn.hash_delete(nnn);
-  nnn->set_req(LoopNode::LoopBackControl, C->top());
-  for (DUIterator_Fast j2max, j2 = nnn->fast_outs(j2max); j2 < j2max; j2++) {
-    Node* use = nnn->fast_out(j2);
-    if( use->in(0) == nnn && use->req() == 3 && use->is_Phi() ) {
+  Node* new_head = old_new[head->_idx];
+  _igvn.hash_delete(new_head);
+  new_head->set_req(LoopNode::LoopBackControl, C->top());
+  for (DUIterator_Fast j2max, j2 = new_head->fast_outs(j2max); j2 < j2max; j2++) {
+    Node* use = new_head->fast_out(j2);
+    if (use->in(0) == new_head && use->req() == 3 && use->is_Phi()) {
       _igvn.hash_delete(use);
       use->set_req(LoopNode::LoopBackControl, C->top());
     }
@@ -371,15 +541,15 @@
 
 
   // Step 4: Correct dom-depth info.  Set to loop-head depth.
-  int dd = dom_depth(loop->_head);
-  set_idom(loop->_head, loop->_head->in(1), dd);
+  int dd = dom_depth(head);
+  set_idom(head, head->in(1), dd);
   for (uint j3 = 0; j3 < loop->_body.size(); j3++) {
     Node *old = loop->_body.at(j3);
     Node *nnn = old_new[old->_idx];
     if (!has_ctrl(nnn))
       set_idom(nnn, idom(nnn), dd-1);
     // While we're at it, remove any SafePoints from the peeled code
-    if( old->Opcode() == Op_SafePoint ) {
+    if (old->Opcode() == Op_SafePoint) {
       Node *nnn = old_new[old->_idx];
       lazy_replace(nnn,nnn->in(TypeFunc::Control));
     }
@@ -392,34 +562,26 @@
   loop->record_for_igvn();
 }
 
+#define EMPTY_LOOP_SIZE 7 // number of nodes in an empty loop
+
 //------------------------------policy_maximally_unroll------------------------
-// Return exact loop trip count, or 0 if not maximally unrolling
+// Calculate exact loop trip count and return true if loop can be maximally
+// unrolled.
 bool IdealLoopTree::policy_maximally_unroll( PhaseIdealLoop *phase ) const {
   CountedLoopNode *cl = _head->as_CountedLoop();
   assert(cl->is_normal_loop(), "");
-
-  Node *init_n = cl->init_trip();
-  Node *limit_n = cl->limit();
+  if (!cl->is_valid_counted_loop())
+    return false; // Malformed counted loop
 
-  // Non-constant bounds
-  if (init_n   == NULL || !init_n->is_Con()  ||
-      limit_n  == NULL || !limit_n->is_Con() ||
-      // protect against stride not being a constant
-      !cl->stride_is_con()) {
+  if (!cl->has_exact_trip_count()) {
+    // Trip count is not exact.
     return false;
   }
-  int init   = init_n->get_int();
-  int limit  = limit_n->get_int();
-  int span   = limit - init;
-  int stride = cl->stride_con();
 
-  if (init >= limit || stride > span) {
-    // return a false (no maximally unroll) and the regular unroll/peel
-    // route will make a small mess which CCP will fold away.
-    return false;
-  }
-  uint trip_count = span/stride;   // trip_count can be greater than 2 Gig.
-  assert( (int)trip_count*stride == span, "must divide evenly" );
+  uint trip_count = cl->trip_count();
+  // Note, max_juint is used to indicate unknown trip count.
+  assert(trip_count > 1, "one iteration loop should be optimized out already");
+  assert(trip_count < max_juint, "exact trip_count should be less than max_uint.");
 
   // Real policy: if we maximally unroll, does it get too big?
   // Allow the unrolled mess to get larger than standard loop
@@ -427,15 +589,29 @@
   uint body_size    = _body.size();
   uint unroll_limit = (uint)LoopUnrollLimit * 4;
   assert( (intx)unroll_limit == LoopUnrollLimit * 4, "LoopUnrollLimit must fit in 32bits");
-  cl->set_trip_count(trip_count);
   if (trip_count > unroll_limit || body_size > unroll_limit) {
     return false;
   }
 
+  // Take into account that after unroll conjoined heads and tails will fold,
+  // otherwise policy_unroll() may allow more unrolling than max unrolling.
+  uint new_body_size = EMPTY_LOOP_SIZE + (body_size - EMPTY_LOOP_SIZE) * trip_count;
+  uint tst_body_size = (new_body_size - EMPTY_LOOP_SIZE) / trip_count + EMPTY_LOOP_SIZE;
+  if (body_size != tst_body_size) // Check for int overflow
+    return false;
+  if (new_body_size > unroll_limit ||
+      // Unrolling can result in a large amount of node construction
+      new_body_size >= MaxNodeLimit - phase->C->unique()) {
+    return false;
+  }
+
   // Currently we don't have policy to optimize one iteration loops.
   // Maximally unrolling transformation is used for that:
   // it is peeled and the original loop become non reachable (dead).
-  if (trip_count == 1)
+  // Also fully unroll a loop with few iterations regardless next
+  // conditions since following loop optimizations will split
+  // such loop anyway (pre-main-post).
+  if (trip_count <= 3)
     return true;
 
   // Do not unroll a loop with String intrinsics code.
@@ -452,17 +628,7 @@
     } // switch
   }
 
-  if (body_size <= unroll_limit) {
-    uint new_body_size = body_size * trip_count;
-    if (new_body_size <= unroll_limit &&
-        body_size == new_body_size / trip_count &&
-        // Unrolling can result in a large amount of node construction
-        new_body_size < MaxNodeLimit - phase->C->unique()) {
-      return true;    // maximally unroll
-    }
-  }
-
-  return false;               // Do not maximally unroll
+  return true; // Do maximally unroll
 }
 
 
@@ -474,12 +640,15 @@
   CountedLoopNode *cl = _head->as_CountedLoop();
   assert(cl->is_normal_loop() || cl->is_main_loop(), "");
 
-  // protect against stride not being a constant
-  if (!cl->stride_is_con()) return false;
+  if (!cl->is_valid_counted_loop())
+    return false; // Malformed counted loop
 
   // protect against over-unrolling
   if (cl->trip_count() <= 1) return false;
 
+  // Check for stride being a small enough constant
+  if (abs(cl->stride_con()) > (1<<3)) return false;
+
   int future_unroll_ct = cl->unrolled_count() * 2;
 
   // Don't unroll if the next round of unrolling would push us
@@ -560,9 +729,6 @@
     return false;
   }
 
-  // Check for stride being a small enough constant
-  if (abs(cl->stride_con()) > (1<<3)) return false;
-
   // Unroll once!  (Each trip will soon do double iterations)
   return true;
 }
@@ -956,7 +1122,11 @@
     tty->print("Unrolling ");
     loop->dump_head();
   } else if (TraceLoopOpts) {
-    tty->print("Unroll     %d ", loop_head->unrolled_count()*2);
+    if (loop_head->trip_count() < (uint)LoopUnrollLimit) {
+      tty->print("Unroll  %d(%2d) ", loop_head->unrolled_count()*2, loop_head->trip_count());
+    } else {
+      tty->print("Unroll  %d     ", loop_head->unrolled_count()*2);
+    }
     loop->dump_head();
   }
 #endif
@@ -1631,7 +1801,7 @@
 // have on the last iteration.  This will break the loop.
 bool IdealLoopTree::policy_do_remove_empty_loop( PhaseIdealLoop *phase ) {
   // Minimum size must be empty loop
-  if (_body.size() > 7/*number of nodes in an empty loop*/)
+  if (_body.size() > EMPTY_LOOP_SIZE)
     return false;
 
   if (!_head->is_CountedLoop())
@@ -1658,8 +1828,19 @@
   // main and post loops have explicitly created zero trip guard
   bool needs_guard = !cl->is_main_loop() && !cl->is_post_loop();
   if (needs_guard) {
+    // Skip guard if values not overlap.
+    const TypeInt* init_t = phase->_igvn.type(cl->init_trip())->is_int();
+    const TypeInt* limit_t = phase->_igvn.type(cl->limit())->is_int();
+    int  stride_con = cl->stride_con();
+    if (stride_con > 0) {
+      needs_guard = (init_t->_hi >= limit_t->_lo);
+    } else {
+      needs_guard = (init_t->_lo <= limit_t->_hi);
+    }
+  }
+  if (needs_guard) {
     // Check for an obvious zero trip guard.
-    Node* inctrl = cl->in(LoopNode::EntryControl);
+    Node* inctrl = PhaseIdealLoop::skip_loop_predicates(cl->in(LoopNode::EntryControl));
     if (inctrl->Opcode() == Op_IfTrue) {
       // The test should look like just the backedge of a CountedLoop
       Node* iff = inctrl->in(0);
@@ -1702,12 +1883,49 @@
   return true;
 }
 
+//------------------------------policy_do_one_iteration_loop-------------------
+// Convert one iteration loop into normal code.
+bool IdealLoopTree::policy_do_one_iteration_loop( PhaseIdealLoop *phase ) {
+  if (!_head->as_Loop()->is_valid_counted_loop())
+    return false; // Only for counted loop
+
+  CountedLoopNode *cl = _head->as_CountedLoop();
+  if (!cl->has_exact_trip_count() || cl->trip_count() != 1) {
+    return false;
+  }
+
+#ifndef PRODUCT
+  if(TraceLoopOpts) {
+    tty->print("OneIteration ");
+    this->dump_head();
+  }
+#endif
+
+  Node *init_n = cl->init_trip();
+#ifdef ASSERT
+  // Loop boundaries should be constant since trip count is exact.
+  assert(init_n->get_int() + cl->stride_con() >= cl->limit()->get_int(), "should be one iteration");
+#endif
+  // Replace the phi at loop head with the value of the init_trip.
+  // Then the CountedLoopEnd will collapse (backedge will not be taken)
+  // and all loop-invariant uses of the exit values will be correct.
+  phase->_igvn.replace_node(cl->phi(), cl->init_trip());
+  phase->C->set_major_progress();
+  return true;
+}
 
 //=============================================================================
 //------------------------------iteration_split_impl---------------------------
 bool IdealLoopTree::iteration_split_impl( PhaseIdealLoop *phase, Node_List &old_new ) {
+  // Compute exact loop trip count if possible.
+  compute_exact_trip_count(phase);
+
+  // Convert one iteration loop into normal code.
+  if (policy_do_one_iteration_loop(phase))
+    return true;
+
   // Check and remove empty loops (spam micro-benchmarks)
-  if( policy_do_remove_empty_loop(phase) )
+  if (policy_do_remove_empty_loop(phase))
     return true;  // Here we removed an empty loop
 
   bool should_peel = policy_peeling(phase); // Should we peel?
@@ -1716,40 +1934,40 @@
 
   // Non-counted loops may be peeled; exactly 1 iteration is peeled.
   // This removes loop-invariant tests (usually null checks).
-  if( !_head->is_CountedLoop() ) { // Non-counted loop
+  if (!_head->is_CountedLoop()) { // Non-counted loop
     if (PartialPeelLoop && phase->partial_peel(this, old_new)) {
       // Partial peel succeeded so terminate this round of loop opts
       return false;
     }
-    if( should_peel ) {            // Should we peel?
+    if (should_peel) {            // Should we peel?
 #ifndef PRODUCT
       if (PrintOpto) tty->print_cr("should_peel");
 #endif
       phase->do_peeling(this,old_new);
-    } else if( should_unswitch ) {
+    } else if (should_unswitch) {
       phase->do_unswitching(this, old_new);
     }
     return true;
   }
   CountedLoopNode *cl = _head->as_CountedLoop();
 
-  if( !cl->loopexit() ) return true; // Ignore various kinds of broken loops
+  if (!cl->loopexit()) return true; // Ignore various kinds of broken loops
 
   // Do nothing special to pre- and post- loops
-  if( cl->is_pre_loop() || cl->is_post_loop() ) return true;
+  if (cl->is_pre_loop() || cl->is_post_loop()) return true;
 
   // Compute loop trip count from profile data
   compute_profile_trip_cnt(phase);
 
   // Before attempting fancy unrolling, RCE or alignment, see if we want
   // to completely unroll this loop or do loop unswitching.
-  if( cl->is_normal_loop() ) {
+  if (cl->is_normal_loop()) {
     if (should_unswitch) {
       phase->do_unswitching(this, old_new);
       return true;
     }
     bool should_maximally_unroll =  policy_maximally_unroll(phase);
-    if( should_maximally_unroll ) {
+    if (should_maximally_unroll) {
       // Here we did some unrolling and peeling.  Eventually we will
       // completely unroll this loop and it will no longer be a loop.
       phase->do_maximally_unroll(this,old_new);
@@ -1757,6 +1975,12 @@
     }
   }
 
+  // Skip next optimizations if running low on nodes. Note that
+  // policy_unswitching and policy_maximally_unroll have this check.
+  uint nodes_left = MaxNodeLimit - phase->C->unique();
+  if ((2 * _body.size()) > nodes_left) {
+    return true;
+  }
 
   // Counted loops may be peeled, may need some iterations run up
   // front for RCE, and may want to align loop refs to a cache
@@ -1787,14 +2011,14 @@
   // If we have any of these conditions (RCE, alignment, unrolling) met, then
   // we switch to the pre-/main-/post-loop model.  This model also covers
   // peeling.
-  if( should_rce || should_align || should_unroll ) {
-    if( cl->is_normal_loop() )  // Convert to 'pre/main/post' loops
+  if (should_rce || should_align || should_unroll) {
+    if (cl->is_normal_loop())  // Convert to 'pre/main/post' loops
       phase->insert_pre_post_loops(this,old_new, !may_rce_align);
 
     // Adjust the pre- and main-loop limits to let the pre and post loops run
     // with full checks, but the main-loop with no checks.  Remove said
     // checks from the main body.
-    if( should_rce )
+    if (should_rce)
       phase->do_range_check(this,old_new);
 
     // Double loop body for unrolling.  Adjust the minimum-trip test (will do
@@ -1802,16 +2026,16 @@
     // an even number of trips).  If we are peeling, we might enable some RCE
     // and we'd rather unroll the post-RCE'd loop SO... do not unroll if
     // peeling.
-      if( should_unroll && !should_peel )
-        phase->do_unroll(this,old_new, true);
+    if (should_unroll && !should_peel)
+      phase->do_unroll(this,old_new, true);
 
     // Adjust the pre-loop limits to align the main body
     // iterations.
-    if( should_align )
+    if (should_align)
       Unimplemented();
 
   } else {                      // Else we have an unchanged counted loop
-    if( should_peel )           // Might want to peel but do nothing else
+    if (should_peel)           // Might want to peel but do nothing else
       phase->do_peeling(this,old_new);
   }
   return true;
@@ -1861,651 +2085,8 @@
   return true;
 }
 
-//-------------------------------is_uncommon_trap_proj----------------------------
-// Return true if proj is the form of "proj->[region->..]call_uct"
-bool PhaseIdealLoop::is_uncommon_trap_proj(ProjNode* proj, Deoptimization::DeoptReason reason) {
-  int path_limit = 10;
-  assert(proj, "invalid argument");
-  Node* out = proj;
-  for (int ct = 0; ct < path_limit; ct++) {
-    out = out->unique_ctrl_out();
-    if (out == NULL || out->is_Root() || out->is_Start())
-      return false;
-    if (out->is_CallStaticJava()) {
-      int req = out->as_CallStaticJava()->uncommon_trap_request();
-      if (req != 0) {
-        Deoptimization::DeoptReason trap_reason = Deoptimization::trap_request_reason(req);
-        if (trap_reason == reason || reason == Deoptimization::Reason_none) {
-           return true;
-        }
-      }
-      return false; // don't do further after call
-    }
-  }
-  return false;
-}
 
-//-------------------------------is_uncommon_trap_if_pattern-------------------------
-// Return true  for "if(test)-> proj -> ...
-//                          |
-//                          V
-//                      other_proj->[region->..]call_uct"
-//
-// "must_reason_predicate" means the uct reason must be Reason_predicate
-bool PhaseIdealLoop::is_uncommon_trap_if_pattern(ProjNode *proj, Deoptimization::DeoptReason reason) {
-  Node *in0 = proj->in(0);
-  if (!in0->is_If()) return false;
-  // Variation of a dead If node.
-  if (in0->outcnt() < 2)  return false;
-  IfNode* iff = in0->as_If();
-
-  // we need "If(Conv2B(Opaque1(...)))" pattern for reason_predicate
-  if (reason != Deoptimization::Reason_none) {
-    if (iff->in(1)->Opcode() != Op_Conv2B ||
-       iff->in(1)->in(1)->Opcode() != Op_Opaque1) {
-      return false;
-    }
-  }
-
-  ProjNode* other_proj = iff->proj_out(1-proj->_con)->as_Proj();
-  return is_uncommon_trap_proj(other_proj, reason);
-}
-
-//-------------------------------register_control-------------------------
-void PhaseIdealLoop::register_control(Node* n, IdealLoopTree *loop, Node* pred) {
-  assert(n->is_CFG(), "must be control node");
-  _igvn.register_new_node_with_optimizer(n);
-  loop->_body.push(n);
-  set_loop(n, loop);
-  // When called from beautify_loops() idom is not constructed yet.
-  if (_idom != NULL) {
-    set_idom(n, pred, dom_depth(pred));
-  }
-}
-
-//------------------------------create_new_if_for_predicate------------------------
-// create a new if above the uct_if_pattern for the predicate to be promoted.
-//
-//          before                                after
-//        ----------                           ----------
-//           ctrl                                 ctrl
-//            |                                     |
-//            |                                     |
-//            v                                     v
-//           iff                                 new_iff
-//          /    \                                /      \
-//         /      \                              /        \
-//        v        v                            v          v
-//  uncommon_proj cont_proj                   if_uct     if_cont
-// \      |        |                           |          |
-//  \     |        |                           |          |
-//   v    v        v                           |          v
-//     rgn       loop                          |         iff
-//      |                                      |        /     \
-//      |                                      |       /       \
-//      v                                      |      v         v
-// uncommon_trap                               | uncommon_proj cont_proj
-//                                           \  \    |           |
-//                                            \  \   |           |
-//                                             v  v  v           v
-//                                               rgn           loop
-//                                                |
-//                                                |
-//                                                v
-//                                           uncommon_trap
-//
-//
-// We will create a region to guard the uct call if there is no one there.
-// The true projecttion (if_cont) of the new_iff is returned.
-// This code is also used to clone predicates to clonned loops.
-ProjNode* PhaseIdealLoop::create_new_if_for_predicate(ProjNode* cont_proj, Node* new_entry,
-                                                      Deoptimization::DeoptReason reason) {
-  assert(is_uncommon_trap_if_pattern(cont_proj, reason), "must be a uct if pattern!");
-  IfNode* iff = cont_proj->in(0)->as_If();
-
-  ProjNode *uncommon_proj = iff->proj_out(1 - cont_proj->_con);
-  Node     *rgn   = uncommon_proj->unique_ctrl_out();
-  assert(rgn->is_Region() || rgn->is_Call(), "must be a region or call uct");
-
-  if (!rgn->is_Region()) { // create a region to guard the call
-    assert(rgn->is_Call(), "must be call uct");
-    CallNode* call = rgn->as_Call();
-    IdealLoopTree* loop = get_loop(call);
-    rgn = new (C, 1) RegionNode(1);
-    rgn->add_req(uncommon_proj);
-    register_control(rgn, loop, uncommon_proj);
-    _igvn.hash_delete(call);
-    call->set_req(0, rgn);
-    // When called from beautify_loops() idom is not constructed yet.
-    if (_idom != NULL) {
-      set_idom(call, rgn, dom_depth(rgn));
-    }
-  }
-
-  Node* entry = iff->in(0);
-  if (new_entry != NULL) {
-    // Clonning the predicate to new location.
-    entry = new_entry;
-  }
-  // Create new_iff
-  IdealLoopTree* lp = get_loop(entry);
-  IfNode *new_iff = new (C, 2) IfNode(entry, NULL, iff->_prob, iff->_fcnt);
-  register_control(new_iff, lp, entry);
-  Node *if_cont = new (C, 1) IfTrueNode(new_iff);
-  Node *if_uct  = new (C, 1) IfFalseNode(new_iff);
-  if (cont_proj->is_IfFalse()) {
-    // Swap
-    Node* tmp = if_uct; if_uct = if_cont; if_cont = tmp;
-  }
-  register_control(if_cont, lp, new_iff);
-  register_control(if_uct, get_loop(rgn), new_iff);
-
-  // if_uct to rgn
-  _igvn.hash_delete(rgn);
-  rgn->add_req(if_uct);
-  // When called from beautify_loops() idom is not constructed yet.
-  if (_idom != NULL) {
-    Node* ridom = idom(rgn);
-    Node* nrdom = dom_lca(ridom, new_iff);
-    set_idom(rgn, nrdom, dom_depth(rgn));
-  }
-  // rgn must have no phis
-  assert(!rgn->as_Region()->has_phi(), "region must have no phis");
-
-  if (new_entry == NULL) {
-    // Attach if_cont to iff
-    _igvn.hash_delete(iff);
-    iff->set_req(0, if_cont);
-    if (_idom != NULL) {
-      set_idom(iff, if_cont, dom_depth(iff));
-    }
-  }
-  return if_cont->as_Proj();
-}
-
-//--------------------------find_predicate_insertion_point-------------------
-// Find a good location to insert a predicate
-ProjNode* PhaseIdealLoop::find_predicate_insertion_point(Node* start_c, Deoptimization::DeoptReason reason) {
-  if (start_c == NULL || !start_c->is_Proj())
-    return NULL;
-  if (is_uncommon_trap_if_pattern(start_c->as_Proj(), reason)) {
-    return start_c->as_Proj();
-  }
-  return NULL;
-}
-
-//--------------------------find_predicate------------------------------------
-// Find a predicate
-Node* PhaseIdealLoop::find_predicate(Node* entry) {
-  Node* predicate = NULL;
-  if (UseLoopPredicate) {
-    predicate = find_predicate_insertion_point(entry, Deoptimization::Reason_predicate);
-    if (predicate != NULL) { // right pattern that can be used by loop predication
-      assert(entry->in(0)->in(1)->in(1)->Opcode()==Op_Opaque1, "must be");
-      return entry;
-    }
-  }
-  return NULL;
-}
-
-//------------------------------Invariance-----------------------------------
-// Helper class for loop_predication_impl to compute invariance on the fly and
-// clone invariants.
-class Invariance : public StackObj {
-  VectorSet _visited, _invariant;
-  Node_Stack _stack;
-  VectorSet _clone_visited;
-  Node_List _old_new; // map of old to new (clone)
-  IdealLoopTree* _lpt;
-  PhaseIdealLoop* _phase;
-
-  // Helper function to set up the invariance for invariance computation
-  // If n is a known invariant, set up directly. Otherwise, look up the
-  // the possibility to push n onto the stack for further processing.
-  void visit(Node* use, Node* n) {
-    if (_lpt->is_invariant(n)) { // known invariant
-      _invariant.set(n->_idx);
-    } else if (!n->is_CFG()) {
-      Node *n_ctrl = _phase->ctrl_or_self(n);
-      Node *u_ctrl = _phase->ctrl_or_self(use); // self if use is a CFG
-      if (_phase->is_dominator(n_ctrl, u_ctrl)) {
-        _stack.push(n, n->in(0) == NULL ? 1 : 0);
-      }
-    }
-  }
-
-  // Compute invariance for "the_node" and (possibly) all its inputs recursively
-  // on the fly
-  void compute_invariance(Node* n) {
-    assert(_visited.test(n->_idx), "must be");
-    visit(n, n);
-    while (_stack.is_nonempty()) {
-      Node*  n = _stack.node();
-      uint idx = _stack.index();
-      if (idx == n->req()) { // all inputs are processed
-        _stack.pop();
-        // n is invariant if it's inputs are all invariant
-        bool all_inputs_invariant = true;
-        for (uint i = 0; i < n->req(); i++) {
-          Node* in = n->in(i);
-          if (in == NULL) continue;
-          assert(_visited.test(in->_idx), "must have visited input");
-          if (!_invariant.test(in->_idx)) { // bad guy
-            all_inputs_invariant = false;
-            break;
-          }
-        }
-        if (all_inputs_invariant) {
-          _invariant.set(n->_idx); // I am a invariant too
-        }
-      } else { // process next input
-        _stack.set_index(idx + 1);
-        Node* m = n->in(idx);
-        if (m != NULL && !_visited.test_set(m->_idx)) {
-          visit(n, m);
-        }
-      }
-    }
-  }
-
-  // Helper function to set up _old_new map for clone_nodes.
-  // If n is a known invariant, set up directly ("clone" of n == n).
-  // Otherwise, push n onto the stack for real cloning.
-  void clone_visit(Node* n) {
-    assert(_invariant.test(n->_idx), "must be invariant");
-    if (_lpt->is_invariant(n)) { // known invariant
-      _old_new.map(n->_idx, n);
-    } else{ // to be cloned
-      assert (!n->is_CFG(), "should not see CFG here");
-      _stack.push(n, n->in(0) == NULL ? 1 : 0);
-    }
-  }
-
-  // Clone "n" and (possibly) all its inputs recursively
-  void clone_nodes(Node* n, Node* ctrl) {
-    clone_visit(n);
-    while (_stack.is_nonempty()) {
-      Node*  n = _stack.node();
-      uint idx = _stack.index();
-      if (idx == n->req()) { // all inputs processed, clone n!
-        _stack.pop();
-        // clone invariant node
-        Node* n_cl = n->clone();
-        _old_new.map(n->_idx, n_cl);
-        _phase->register_new_node(n_cl, ctrl);
-        for (uint i = 0; i < n->req(); i++) {
-          Node* in = n_cl->in(i);
-          if (in == NULL) continue;
-          n_cl->set_req(i, _old_new[in->_idx]);
-        }
-      } else { // process next input
-        _stack.set_index(idx + 1);
-        Node* m = n->in(idx);
-        if (m != NULL && !_clone_visited.test_set(m->_idx)) {
-          clone_visit(m); // visit the input
-        }
-      }
-    }
-  }
-
- public:
-  Invariance(Arena* area, IdealLoopTree* lpt) :
-    _lpt(lpt), _phase(lpt->_phase),
-    _visited(area), _invariant(area), _stack(area, 10 /* guess */),
-    _clone_visited(area), _old_new(area)
-  {}
-
-  // Map old to n for invariance computation and clone
-  void map_ctrl(Node* old, Node* n) {
-    assert(old->is_CFG() && n->is_CFG(), "must be");
-    _old_new.map(old->_idx, n); // "clone" of old is n
-    _invariant.set(old->_idx);  // old is invariant
-    _clone_visited.set(old->_idx);
-  }
-
-  // Driver function to compute invariance
-  bool is_invariant(Node* n) {
-    if (!_visited.test_set(n->_idx))
-      compute_invariance(n);
-    return (_invariant.test(n->_idx) != 0);
-  }
-
-  // Driver function to clone invariant
-  Node* clone(Node* n, Node* ctrl) {
-    assert(ctrl->is_CFG(), "must be");
-    assert(_invariant.test(n->_idx), "must be an invariant");
-    if (!_clone_visited.test(n->_idx))
-      clone_nodes(n, ctrl);
-    return _old_new[n->_idx];
-  }
-};
-
-//------------------------------is_range_check_if -----------------------------------
-// Returns true if the predicate of iff is in "scale*iv + offset u< load_range(ptr)" format
-// Note: this function is particularly designed for loop predication. We require load_range
-//       and offset to be loop invariant computed on the fly by "invar"
-bool IdealLoopTree::is_range_check_if(IfNode *iff, PhaseIdealLoop *phase, Invariance& invar) const {
-  if (!is_loop_exit(iff)) {
-    return false;
-  }
-  if (!iff->in(1)->is_Bool()) {
-    return false;
-  }
-  const BoolNode *bol = iff->in(1)->as_Bool();
-  if (bol->_test._test != BoolTest::lt) {
-    return false;
-  }
-  if (!bol->in(1)->is_Cmp()) {
-    return false;
-  }
-  const CmpNode *cmp = bol->in(1)->as_Cmp();
-  if (cmp->Opcode() != Op_CmpU ) {
-    return false;
-  }
-  Node* range = cmp->in(2);
-  if (range->Opcode() != Op_LoadRange) {
-    const TypeInt* tint = phase->_igvn.type(range)->isa_int();
-    if (!OptimizeFill || tint == NULL || tint->empty() || tint->_lo < 0) {
-      // Allow predication on positive values that aren't LoadRanges.
-      // This allows optimization of loops where the length of the
-      // array is a known value and doesn't need to be loaded back
-      // from the array.
-      return false;
-    }
-  }
-  if (!invar.is_invariant(range)) {
-    return false;
-  }
-  Node *iv     = _head->as_CountedLoop()->phi();
-  int   scale  = 0;
-  Node *offset = NULL;
-  if (!phase->is_scaled_iv_plus_offset(cmp->in(1), iv, &scale, &offset)) {
-    return false;
-  }
-  if(offset && !invar.is_invariant(offset)) { // offset must be invariant
-    return false;
-  }
-  return true;
-}
-
-//------------------------------rc_predicate-----------------------------------
-// Create a range check predicate
-//
-// for (i = init; i < limit; i += stride) {
-//    a[scale*i+offset]
-// }
-//
-// Compute max(scale*i + offset) for init <= i < limit and build the predicate
-// as "max(scale*i + offset) u< a.length".
-//
-// There are two cases for max(scale*i + offset):
-// (1) stride*scale > 0
-//   max(scale*i + offset) = scale*(limit-stride) + offset
-// (2) stride*scale < 0
-//   max(scale*i + offset) = scale*init + offset
-BoolNode* PhaseIdealLoop::rc_predicate(Node* ctrl,
-                                       int scale, Node* offset,
-                                       Node* init, Node* limit, Node* stride,
-                                       Node* range, bool upper) {
-  DEBUG_ONLY(ttyLocker ttyl);
-  if (TraceLoopPredicate) tty->print("rc_predicate ");
-
-  Node* max_idx_expr  = init;
-  int stride_con = stride->get_int();
-  if ((stride_con > 0) == (scale > 0) == upper) {
-    max_idx_expr = new (C, 3) SubINode(limit, stride);
-    register_new_node(max_idx_expr, ctrl);
-    if (TraceLoopPredicate) tty->print("(limit - stride) ");
-  } else {
-    if (TraceLoopPredicate) tty->print("init ");
-  }
-
-  if (scale != 1) {
-    ConNode* con_scale = _igvn.intcon(scale);
-    max_idx_expr = new (C, 3) MulINode(max_idx_expr, con_scale);
-    register_new_node(max_idx_expr, ctrl);
-    if (TraceLoopPredicate) tty->print("* %d ", scale);
-  }
-
-  if (offset && (!offset->is_Con() || offset->get_int() != 0)){
-    max_idx_expr = new (C, 3) AddINode(max_idx_expr, offset);
-    register_new_node(max_idx_expr, ctrl);
-    if (TraceLoopPredicate)
-      if (offset->is_Con()) tty->print("+ %d ", offset->get_int());
-      else tty->print("+ offset ");
-  }
-
-  CmpUNode* cmp = new (C, 3) CmpUNode(max_idx_expr, range);
-  register_new_node(cmp, ctrl);
-  BoolNode* bol = new (C, 2) BoolNode(cmp, BoolTest::lt);
-  register_new_node(bol, ctrl);
-
-  if (TraceLoopPredicate) tty->print_cr("<u range");
-  return bol;
-}
-
-//------------------------------ loop_predication_impl--------------------------
-// Insert loop predicates for null checks and range checks
-bool PhaseIdealLoop::loop_predication_impl(IdealLoopTree *loop) {
-  if (!UseLoopPredicate) return false;
-
-  if (!loop->_head->is_Loop()) {
-    // Could be a simple region when irreducible loops are present.
-    return false;
-  }
-
-  if (loop->_head->unique_ctrl_out()->Opcode() == Op_NeverBranch) {
-    // do nothing for infinite loops
-    return false;
-  }
-
-  CountedLoopNode *cl = NULL;
-  if (loop->_head->is_CountedLoop()) {
-    cl = loop->_head->as_CountedLoop();
-    // do nothing for iteration-splitted loops
-    if (!cl->is_normal_loop()) return false;
-  }
-
-  LoopNode *lpn  = loop->_head->as_Loop();
-  Node* entry = lpn->in(LoopNode::EntryControl);
-
-  ProjNode *predicate_proj = find_predicate_insertion_point(entry, Deoptimization::Reason_predicate);
-  if (!predicate_proj) {
-#ifndef PRODUCT
-    if (TraceLoopPredicate) {
-      tty->print("missing predicate:");
-      loop->dump_head();
-      lpn->dump(1);
-    }
-#endif
-    return false;
-  }
-  ConNode* zero = _igvn.intcon(0);
-  set_ctrl(zero, C->root());
-
-  ResourceArea *area = Thread::current()->resource_area();
-  Invariance invar(area, loop);
-
-  // Create list of if-projs such that a newer proj dominates all older
-  // projs in the list, and they all dominate loop->tail()
-  Node_List if_proj_list(area);
-  LoopNode *head  = loop->_head->as_Loop();
-  Node *current_proj = loop->tail(); //start from tail
-  while ( current_proj != head ) {
-    if (loop == get_loop(current_proj) && // still in the loop ?
-        current_proj->is_Proj()        && // is a projection  ?
-        current_proj->in(0)->Opcode() == Op_If) { // is a if projection ?
-      if_proj_list.push(current_proj);
-    }
-    current_proj = idom(current_proj);
-  }
-
-  bool hoisted = false; // true if at least one proj is promoted
-  while (if_proj_list.size() > 0) {
-    // Following are changed to nonnull when a predicate can be hoisted
-    ProjNode* new_predicate_proj = NULL;
-
-    ProjNode* proj = if_proj_list.pop()->as_Proj();
-    IfNode*   iff  = proj->in(0)->as_If();
-
-    if (!is_uncommon_trap_if_pattern(proj, Deoptimization::Reason_none)) {
-      if (loop->is_loop_exit(iff)) {
-        // stop processing the remaining projs in the list because the execution of them
-        // depends on the condition of "iff" (iff->in(1)).
-        break;
-      } else {
-        // Both arms are inside the loop. There are two cases:
-        // (1) there is one backward branch. In this case, any remaining proj
-        //     in the if_proj list post-dominates "iff". So, the condition of "iff"
-        //     does not determine the execution the remining projs directly, and we
-        //     can safely continue.
-        // (2) both arms are forwarded, i.e. a diamond shape. In this case, "proj"
-        //     does not dominate loop->tail(), so it can not be in the if_proj list.
-        continue;
-      }
-    }
-
-    Node*     test = iff->in(1);
-    if (!test->is_Bool()){ //Conv2B, ...
-      continue;
-    }
-    BoolNode* bol = test->as_Bool();
-    if (invar.is_invariant(bol)) {
-      // Invariant test
-      new_predicate_proj = create_new_if_for_predicate(predicate_proj, NULL,
-                                                       Deoptimization::Reason_predicate);
-      Node* ctrl = new_predicate_proj->in(0)->as_If()->in(0);
-      BoolNode* new_predicate_bol = invar.clone(bol, ctrl)->as_Bool();
-
-      // Negate test if necessary
-      bool negated = false;
-      if (proj->_con != predicate_proj->_con) {
-        new_predicate_bol = new (C, 2) BoolNode(new_predicate_bol->in(1), new_predicate_bol->_test.negate());
-        register_new_node(new_predicate_bol, ctrl);
-        negated = true;
-      }
-      IfNode* new_predicate_iff = new_predicate_proj->in(0)->as_If();
-      _igvn.hash_delete(new_predicate_iff);
-      new_predicate_iff->set_req(1, new_predicate_bol);
-#ifndef PRODUCT
-      if (TraceLoopPredicate) {
-        tty->print("Predicate invariant if%s: %d ", negated ? " negated" : "", new_predicate_iff->_idx);
-        loop->dump_head();
-      } else if (TraceLoopOpts) {
-        tty->print("Predicate IC ");
-        loop->dump_head();
-      }
-#endif
-    } else if (cl != NULL && loop->is_range_check_if(iff, this, invar)) {
-      assert(proj->_con == predicate_proj->_con, "must match");
-
-      // Range check for counted loops
-      const Node*    cmp    = bol->in(1)->as_Cmp();
-      Node*          idx    = cmp->in(1);
-      assert(!invar.is_invariant(idx), "index is variant");
-      assert(cmp->in(2)->Opcode() == Op_LoadRange || OptimizeFill, "must be");
-      Node* rng = cmp->in(2);
-      assert(invar.is_invariant(rng), "range must be invariant");
-      int scale    = 1;
-      Node* offset = zero;
-      bool ok = is_scaled_iv_plus_offset(idx, cl->phi(), &scale, &offset);
-      assert(ok, "must be index expression");
-
-      Node* init    = cl->init_trip();
-      Node* limit   = cl->limit();
-      Node* stride  = cl->stride();
-
-      // Build if's for the upper and lower bound tests.  The
-      // lower_bound test will dominate the upper bound test and all
-      // cloned or created nodes will use the lower bound test as
-      // their declared control.
-      ProjNode* lower_bound_proj = create_new_if_for_predicate(predicate_proj, NULL, Deoptimization::Reason_predicate);
-      ProjNode* upper_bound_proj = create_new_if_for_predicate(predicate_proj, NULL, Deoptimization::Reason_predicate);
-      assert(upper_bound_proj->in(0)->as_If()->in(0) == lower_bound_proj, "should dominate");
-      Node *ctrl = lower_bound_proj->in(0)->as_If()->in(0);
-
-      // Perform cloning to keep Invariance state correct since the
-      // late schedule will place invariant things in the loop.
-      rng = invar.clone(rng, ctrl);
-      if (offset && offset != zero) {
-        assert(invar.is_invariant(offset), "offset must be loop invariant");
-        offset = invar.clone(offset, ctrl);
-      }
-
-      // Test the lower bound
-      Node*  lower_bound_bol = rc_predicate(ctrl, scale, offset, init, limit, stride, rng, false);
-      IfNode* lower_bound_iff = lower_bound_proj->in(0)->as_If();
-      _igvn.hash_delete(lower_bound_iff);
-      lower_bound_iff->set_req(1, lower_bound_bol);
-      if (TraceLoopPredicate) tty->print_cr("lower bound check if: %d", lower_bound_iff->_idx);
-
-      // Test the upper bound
-      Node* upper_bound_bol = rc_predicate(ctrl, scale, offset, init, limit, stride, rng, true);
-      IfNode* upper_bound_iff = upper_bound_proj->in(0)->as_If();
-      _igvn.hash_delete(upper_bound_iff);
-      upper_bound_iff->set_req(1, upper_bound_bol);
-      if (TraceLoopPredicate) tty->print_cr("upper bound check if: %d", lower_bound_iff->_idx);
-
-      // Fall through into rest of the clean up code which will move
-      // any dependent nodes onto the upper bound test.
-      new_predicate_proj = upper_bound_proj;
-
-#ifndef PRODUCT
-      if (TraceLoopOpts && !TraceLoopPredicate) {
-        tty->print("Predicate RC ");
-        loop->dump_head();
-      }
-#endif
-    } else {
-      // Loop variant check (for example, range check in non-counted loop)
-      // with uncommon trap.
-      continue;
-    }
-    assert(new_predicate_proj != NULL, "sanity");
-    // Success - attach condition (new_predicate_bol) to predicate if
-    invar.map_ctrl(proj, new_predicate_proj); // so that invariance test can be appropriate
-
-    // Eliminate the old If in the loop body
-    dominated_by( new_predicate_proj, iff, proj->_con != new_predicate_proj->_con );
-
-    hoisted = true;
-    C->set_major_progress();
-  } // end while
-
-#ifndef PRODUCT
-  // report that the loop predication has been actually performed
-  // for this loop
-  if (TraceLoopPredicate && hoisted) {
-    tty->print("Loop Predication Performed:");
-    loop->dump_head();
-  }
-#endif
-
-  return hoisted;
-}
-
-//------------------------------loop_predication--------------------------------
-// driver routine for loop predication optimization
-bool IdealLoopTree::loop_predication( PhaseIdealLoop *phase) {
-  bool hoisted = false;
-  // Recursively promote predicates
-  if ( _child ) {
-    hoisted = _child->loop_predication( phase);
-  }
-
-  // self
-  if (!_irreducible && !tail()->is_top()) {
-    hoisted |= phase->loop_predication_impl(this);
-  }
-
-  if ( _next ) { //sibling
-    hoisted |= _next->loop_predication( phase);
-  }
-
-  return hoisted;
-}
-
-
+//=============================================================================
 // Process all the loops in the loop tree and replace any fill
 // patterns with an intrisc version.
 bool PhaseIdealLoop::do_intrinsify_fill() {
@@ -2625,9 +2206,12 @@
       if (value != head->phi()) {
         msg = "unhandled shift in address";
       } else {
-        found_index = true;
-        shift = n;
-        assert(type2aelembytes(store->as_Mem()->memory_type(), true) == 1 << shift->in(2)->get_int(), "scale should match");
+        if (type2aelembytes(store->as_Mem()->memory_type(), true) != (1 << n->in(2)->get_int())) {
+          msg = "scale doesn't match";
+        } else {
+          found_index = true;
+          shift = n;
+        }
       }
     } else if (n->Opcode() == Op_ConvI2L && conv == NULL) {
       if (n->in(1) == head->phi()) {
@@ -2762,6 +2346,13 @@
     return false;
   }
 
+#ifndef PRODUCT
+  if (TraceLoopOpts) {
+    tty->print("ArrayFill    ");
+    lpt->dump_head();
+  }
+#endif
+
   // Now replace the whole loop body by a call to a fill routine that
   // covers the same region as the loop.
   Node* base = store->in(MemNode::Address)->as_AddP()->in(AddPNode::Base);
--- a/src/share/vm/opto/loopUnswitch.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/opto/loopUnswitch.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -32,15 +32,17 @@
 //
 // orig:                       transformed:
 //                               if (invariant-test) then
+//  predicate                      predicate
 //  loop                           loop
 //    stmt1                          stmt1
 //    if (invariant-test) then       stmt2
 //      stmt2                        stmt4
 //    else                         endloop
 //      stmt3                    else
-//    endif                        loop [clone]
-//    stmt4                          stmt1 [clone]
-//  endloop                          stmt3
+//    endif                        predicate [clone]
+//    stmt4                        loop [clone]
+//  endloop                          stmt1 [clone]
+//                                   stmt3
 //                                   stmt4 [clone]
 //                                 endloop
 //                               endif
@@ -124,8 +126,15 @@
 
   ProjNode* proj_true = create_slow_version_of_loop(loop, old_new);
 
-  assert(proj_true->is_IfTrue() && proj_true->unique_ctrl_out() == head, "by construction");
-
+#ifdef ASSERT
+  Node* uniqc = proj_true->unique_ctrl_out();
+  Node* entry = head->in(LoopNode::EntryControl);
+  Node* predicate = find_predicate(entry);
+  if (predicate != NULL) predicate = predicate->in(0);
+  assert(proj_true->is_IfTrue() &&
+         (predicate == NULL && uniqc == head ||
+          predicate != NULL && uniqc == predicate), "by construction");
+#endif
   // Increment unswitch count
   LoopNode* head_clone = old_new[head->_idx]->as_Loop();
   int nct = head->unswitch_count() + 1;
@@ -227,21 +236,24 @@
   register_node(ifslow, outer_loop, iff, dom_depth(iff));
 
   // Clone the loop body.  The clone becomes the fast loop.  The
-  // original pre-header will (illegally) have 2 control users (old & new loops).
+  // original pre-header will (illegally) have 3 control users
+  // (old & new loops & new if).
   clone_loop(loop, old_new, dom_depth(head), iff);
   assert(old_new[head->_idx]->is_Loop(), "" );
 
   // Fast (true) control
+  Node* iffast_pred = clone_loop_predicates(entry, iffast);
   _igvn.hash_delete(head);
-  head->set_req(LoopNode::EntryControl, iffast);
-  set_idom(head, iffast, dom_depth(head));
+  head->set_req(LoopNode::EntryControl, iffast_pred);
+  set_idom(head, iffast_pred, dom_depth(head));
   _igvn._worklist.push(head);
 
   // Slow (false) control
+  Node* ifslow_pred = move_loop_predicates(entry, ifslow);
   LoopNode* slow_head = old_new[head->_idx]->as_Loop();
   _igvn.hash_delete(slow_head);
-  slow_head->set_req(LoopNode::EntryControl, ifslow);
-  set_idom(slow_head, ifslow, dom_depth(slow_head));
+  slow_head->set_req(LoopNode::EntryControl, ifslow_pred);
+  set_idom(slow_head, ifslow_pred, dom_depth(slow_head));
   _igvn._worklist.push(slow_head);
 
   recompute_dom_depth();
--- a/src/share/vm/opto/loopnode.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/opto/loopnode.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -341,7 +341,12 @@
   //
   assert(x->Opcode() == Op_Loop, "regular loops only");
   C->print_method("Before CountedLoop", 3);
-
+#ifndef PRODUCT
+  if (TraceLoopOpts) {
+    tty->print("Counted      ");
+    loop->dump_head();
+  }
+#endif
   // If compare points to incr, we are ok.  Otherwise the compare
   // can directly point to the phi; in this case adjust the compare so that
   // it points to the incr by adjusting the limit.
@@ -864,8 +869,10 @@
   Node *outer = new (phase->C, 3) LoopNode( ctl, _head->in(outer_idx) );
   outer = igvn.register_new_node_with_optimizer(outer, _head);
   phase->set_created_loop_node();
+
+  Node* pred = phase->clone_loop_predicates(ctl, outer);
   // Outermost loop falls into '_head' loop
-  _head->set_req(LoopNode::EntryControl, outer);
+  _head->set_req(LoopNode::EntryControl, pred);
   _head->del_req(outer_idx);
   // Split all the Phis up between '_head' loop and 'outer' loop.
   for (DUIterator_Fast jmax, j = _head->fast_outs(jmax); j < jmax; j++) {
@@ -1103,12 +1110,13 @@
   // backedges into a private merge point and use the merge point as
   // the one true backedge.
   if( _head->req() > 3 ) {
-    // Merge the many backedges into a single backedge.
+    // Merge the many backedges into a single backedge but leave
+    // the hottest backedge as separate edge for the following peel.
     merge_many_backedges( phase );
     result = true;
   }
 
-  // If I am a shared header (multiple backedges), peel off myself loop.
+  // If I have one hot backedge, peel off myself loop.
   // I better be the outermost loop.
   if( _head->req() > 3 ) {
     split_outer_loop( phase );
@@ -1433,15 +1441,30 @@
   tty->print("Loop: N%d/N%d ",_head->_idx,_tail->_idx);
   if (_irreducible) tty->print(" IRREDUCIBLE");
   if (UseLoopPredicate) {
-    Node* entry = _head->in(LoopNode::EntryControl);
-    if (entry != NULL && entry->is_Proj() &&
-        PhaseIdealLoop::is_uncommon_trap_if_pattern(entry->as_Proj(), Deoptimization::Reason_predicate)) {
+    Node* entry = PhaseIdealLoop::find_predicate_insertion_point(_head->in(LoopNode::EntryControl),
+                                                                 Deoptimization::Reason_predicate);
+    if (entry != NULL) {
       tty->print(" predicated");
     }
   }
   if (_head->is_CountedLoop()) {
     CountedLoopNode *cl = _head->as_CountedLoop();
     tty->print(" counted");
+
+    Node* init_n = cl->init_trip();
+    if (init_n  != NULL &&  init_n->is_Con())
+      tty->print(" [%d,", cl->init_trip()->get_int());
+    else
+      tty->print(" [int,");
+    Node* limit_n = cl->limit();
+    if (limit_n  != NULL &&  limit_n->is_Con())
+      tty->print("%d),", cl->limit()->get_int());
+    else
+      tty->print("int),");
+    int stride_con  = cl->stride_con();
+    if (stride_con > 0) tty->print("+");
+    tty->print("%d", stride_con);
+
     if (cl->is_pre_loop ()) tty->print(" pre" );
     if (cl->is_main_loop()) tty->print(" main");
     if (cl->is_post_loop()) tty->print(" post");
@@ -1541,7 +1564,7 @@
 //----------------------------build_and_optimize-------------------------------
 // Create a PhaseLoop.  Build the ideal Loop tree.  Map each Ideal Node to
 // its corresponding LoopNode.  If 'optimize' is true, do some loop cleanups.
-void PhaseIdealLoop::build_and_optimize(bool do_split_ifs, bool do_loop_pred) {
+void PhaseIdealLoop::build_and_optimize(bool do_split_ifs) {
   ResourceMark rm;
 
   int old_progress = C->major_progress();
@@ -1573,6 +1596,13 @@
   // Do not need a safepoint at the top level
   _ltree_root->_has_sfpt = 1;
 
+  // Initialize Dominators.
+  // Checked in clone_loop_predicate() during beautify_loops().
+  _idom_size = 0;
+  _idom      = NULL;
+  _dom_depth = NULL;
+  _dom_stk   = NULL;
+
   // Empty pre-order array
   allocate_preorders();
 
@@ -1698,8 +1728,9 @@
     return;
   }
 
-  // some parser-inserted loop predicates could never be used by loop
-  // predication. Eliminate them before loop optimization
+  // Some parser-inserted loop predicates could never be used by loop
+  // predication or they were moved away from loop during some optimizations.
+  // For example, peeling. Eliminate them before next loop optimizations.
   if (UseLoopPredicate) {
     eliminate_useless_predicates();
   }
@@ -1750,7 +1781,7 @@
   }
 
   // Perform loop predication before iteration splitting
-  if (do_loop_pred && C->has_loops() && !C->major_progress()) {
+  if (C->has_loops() && !C->major_progress() && (C->predicate_count() > 0)) {
     _ltree_root->_child->loop_predication(this);
   }
 
@@ -1793,8 +1824,20 @@
     C->set_major_progress();
   }
 
-  // Convert scalar to superword operations
+  // Keep loop predicates and perform optimizations with them
+  // until no more loop optimizations could be done.
+  // After that switch predicates off and do more loop optimizations.
+  if (!C->major_progress() && (C->predicate_count() > 0)) {
+     C->cleanup_loop_predicates(_igvn);
+#ifndef PRODUCT
+     if (TraceLoopOpts) {
+       tty->print_cr("PredicatesOff");
+     }
+#endif
+     C->set_major_progress();
+  }
 
+  // Convert scalar to superword operations at the end of all loop opts.
   if (UseSuperWord && C->has_loops() && !C->major_progress()) {
     // SuperWord transform
     SuperWord sw(this);
--- a/src/share/vm/opto/loopnode.hpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/opto/loopnode.hpp	Thu Apr 21 08:12:46 2011 -0700
@@ -57,7 +57,12 @@
 protected:
   short _loop_flags;
   // Names for flag bitfields
-  enum { pre_post_main=0, inner_loop=8, partial_peel_loop=16, partial_peel_failed=32  };
+  enum { Normal=0, Pre=1, Main=2, Post=3, PreMainPostFlagsMask=3,
+         MainHasNoPreLoop=4,
+         HasExactTripCount=8,
+         InnerLoop=16,
+         PartialPeelLoop=32,
+         PartialPeelFailed=64 };
   char _unswitch_count;
   enum { _unswitch_max=3 };
 
@@ -65,13 +70,13 @@
   // Names for edge indices
   enum { Self=0, EntryControl, LoopBackControl };
 
-  int is_inner_loop() const { return _loop_flags & inner_loop; }
-  void set_inner_loop() { _loop_flags |= inner_loop; }
+  int is_inner_loop() const { return _loop_flags & InnerLoop; }
+  void set_inner_loop() { _loop_flags |= InnerLoop; }
 
-  int is_partial_peel_loop() const { return _loop_flags & partial_peel_loop; }
-  void set_partial_peel_loop() { _loop_flags |= partial_peel_loop; }
-  int partial_peel_has_failed() const { return _loop_flags & partial_peel_failed; }
-  void mark_partial_peel_failed() { _loop_flags |= partial_peel_failed; }
+  int is_partial_peel_loop() const { return _loop_flags & PartialPeelLoop; }
+  void set_partial_peel_loop() { _loop_flags |= PartialPeelLoop; }
+  int partial_peel_has_failed() const { return _loop_flags & PartialPeelFailed; }
+  void mark_partial_peel_failed() { _loop_flags |= PartialPeelFailed; }
 
   int unswitch_max() { return _unswitch_max; }
   int unswitch_count() { return _unswitch_count; }
@@ -137,8 +142,8 @@
   // the Main CountedLoop.  Used to assert that we understand the graph shape.
   node_idx_t _main_idx;
 
-  // Known trip count calculated by policy_maximally_unroll
-  int   _trip_count;
+  // Known trip count calculated by compute_exact_trip_count()
+  uint  _trip_count;
 
   // Expected trip count from profile data
   float _profile_trip_cnt;
@@ -152,7 +157,7 @@
 
 public:
   CountedLoopNode( Node *entry, Node *backedge )
-    : LoopNode(entry, backedge), _trip_count(max_jint),
+    : LoopNode(entry, backedge), _main_idx(0), _trip_count(max_juint),
       _profile_trip_cnt(COUNT_UNKNOWN), _unrolled_count_log2(0),
       _node_count_before_unroll(0) {
     init_class_id(Class_CountedLoop);
@@ -194,13 +199,12 @@
 
   // A 'main' loop that is ONLY unrolled or peeled, never RCE'd or
   // Aligned, may be missing it's pre-loop.
-  enum { Normal=0, Pre=1, Main=2, Post=3, PrePostFlagsMask=3, Main_Has_No_Pre_Loop=4 };
-  int is_normal_loop() const { return (_loop_flags&PrePostFlagsMask) == Normal; }
-  int is_pre_loop   () const { return (_loop_flags&PrePostFlagsMask) == Pre;    }
-  int is_main_loop  () const { return (_loop_flags&PrePostFlagsMask) == Main;   }
-  int is_post_loop  () const { return (_loop_flags&PrePostFlagsMask) == Post;   }
-  int is_main_no_pre_loop() const { return _loop_flags & Main_Has_No_Pre_Loop; }
-  void set_main_no_pre_loop() { _loop_flags |= Main_Has_No_Pre_Loop; }
+  int is_normal_loop() const { return (_loop_flags&PreMainPostFlagsMask) == Normal; }
+  int is_pre_loop   () const { return (_loop_flags&PreMainPostFlagsMask) == Pre;    }
+  int is_main_loop  () const { return (_loop_flags&PreMainPostFlagsMask) == Main;   }
+  int is_post_loop  () const { return (_loop_flags&PreMainPostFlagsMask) == Post;   }
+  int is_main_no_pre_loop() const { return _loop_flags & MainHasNoPreLoop; }
+  void set_main_no_pre_loop() { _loop_flags |= MainHasNoPreLoop; }
 
   int main_idx() const { return _main_idx; }
 
@@ -208,10 +212,19 @@
   void set_pre_loop  (CountedLoopNode *main) { assert(is_normal_loop(),""); _loop_flags |= Pre ; _main_idx = main->_idx; }
   void set_main_loop (                     ) { assert(is_normal_loop(),""); _loop_flags |= Main;                         }
   void set_post_loop (CountedLoopNode *main) { assert(is_normal_loop(),""); _loop_flags |= Post; _main_idx = main->_idx; }
-  void set_normal_loop(                    ) { _loop_flags &= ~PrePostFlagsMask; }
+  void set_normal_loop(                    ) { _loop_flags &= ~PreMainPostFlagsMask; }
+
+  void set_trip_count(uint tc) { _trip_count = tc; }
+  uint trip_count()            { return _trip_count; }
 
-  void set_trip_count(int tc) { _trip_count = tc; }
-  int trip_count()            { return _trip_count; }
+  bool has_exact_trip_count() const { return (_loop_flags & HasExactTripCount) != 0; }
+  void set_exact_trip_count(uint tc) {
+    _trip_count = tc;
+    _loop_flags |= HasExactTripCount;
+  }
+  void set_nonexact_trip_count() {
+    _loop_flags &= ~HasExactTripCount;
+  }
 
   void set_profile_trip_cnt(float ptc) { _profile_trip_cnt = ptc; }
   float profile_trip_cnt()             { return _profile_trip_cnt; }
@@ -384,6 +397,9 @@
   // Micro-benchmark spamming.  Remove empty loops.
   bool policy_do_remove_empty_loop( PhaseIdealLoop *phase );
 
+  // Convert one iteration loop into normal code.
+  bool policy_do_one_iteration_loop( PhaseIdealLoop *phase );
+
   // Return TRUE or FALSE if the loop should be peeled or not.  Peel if we can
   // make some loop-invariant test (usually a null-check) happen before the
   // loop.
@@ -412,6 +428,9 @@
   // Return TRUE if "iff" is a range check.
   bool is_range_check_if(IfNode *iff, PhaseIdealLoop *phase, Invariance& invar) const;
 
+  // Compute loop exact trip count if possible
+  void compute_exact_trip_count( PhaseIdealLoop *phase );
+
   // Compute loop trip count from profile data
   void compute_profile_trip_cnt( PhaseIdealLoop *phase );
 
@@ -706,11 +725,11 @@
     _dom_lca_tags(arena()), // Thread::resource_area
     _verify_me(NULL),
     _verify_only(true) {
-    build_and_optimize(false, false);
+    build_and_optimize(false);
   }
 
   // build the loop tree and perform any requested optimizations
-  void build_and_optimize(bool do_split_if, bool do_loop_pred);
+  void build_and_optimize(bool do_split_if);
 
 public:
   // Dominators for the sea of nodes
@@ -721,13 +740,13 @@
   Node *dom_lca_internal( Node *n1, Node *n2 ) const;
 
   // Compute the Ideal Node to Loop mapping
-  PhaseIdealLoop( PhaseIterGVN &igvn, bool do_split_ifs, bool do_loop_pred) :
+  PhaseIdealLoop( PhaseIterGVN &igvn, bool do_split_ifs) :
     PhaseTransform(Ideal_Loop),
     _igvn(igvn),
     _dom_lca_tags(arena()), // Thread::resource_area
     _verify_me(NULL),
     _verify_only(false) {
-    build_and_optimize(do_split_ifs, do_loop_pred);
+    build_and_optimize(do_split_ifs);
   }
 
   // Verify that verify_me made the same decisions as a fresh run.
@@ -737,7 +756,7 @@
     _dom_lca_tags(arena()), // Thread::resource_area
     _verify_me(verify_me),
     _verify_only(false) {
-    build_and_optimize(false, false);
+    build_and_optimize(false);
   }
 
   // Build and verify the loop tree without modifying the graph.  This
@@ -830,7 +849,26 @@
                                         Deoptimization::DeoptReason reason);
   void register_control(Node* n, IdealLoopTree *loop, Node* pred);
 
-   // Find a good location to insert a predicate
+  // Clone loop predicates to cloned loops (peeled, unswitched)
+  static ProjNode* clone_predicate(ProjNode* predicate_proj, Node* new_entry,
+                                   Deoptimization::DeoptReason reason,
+                                   PhaseIdealLoop* loop_phase,
+                                   PhaseIterGVN* igvn);
+  static ProjNode*  move_predicate(ProjNode* predicate_proj, Node* new_entry,
+                                   Deoptimization::DeoptReason reason,
+                                   PhaseIdealLoop* loop_phase,
+                                   PhaseIterGVN* igvn);
+  static Node* clone_loop_predicates(Node* old_entry, Node* new_entry,
+                                         bool move_predicates,
+                                         PhaseIdealLoop* loop_phase,
+                                         PhaseIterGVN* igvn);
+  Node* clone_loop_predicates(Node* old_entry, Node* new_entry);
+  Node*  move_loop_predicates(Node* old_entry, Node* new_entry);
+
+  void eliminate_loop_predicates(Node* entry);
+  static Node* skip_loop_predicates(Node* entry);
+
+  // Find a good location to insert a predicate
   static ProjNode* find_predicate_insertion_point(Node* start_c, Deoptimization::DeoptReason reason);
   // Find a predicate
   static Node* find_predicate(Node* entry);
--- a/src/share/vm/opto/loopopts.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/opto/loopopts.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -2139,9 +2139,12 @@
 //
 //                   orig
 //
-//                  stmt1
-//                    |
-//                    v
+//                   stmt1
+//                     |
+//                     v
+//               loop predicate
+//                     |
+//                     v
 //                   loop<----+
 //                     |      |
 //                   stmt2    |
@@ -2172,6 +2175,9 @@
 //            after clone loop
 //
 //                   stmt1
+//                     |
+//                     v
+//               loop predicate
 //                 /       \
 //        clone   /         \   orig
 //               /           \
@@ -2210,12 +2216,15 @@
 //           after partial peel
 //
 //                  stmt1
+//                     |
+//                     v
+//               loop predicate
 //                 /
 //        clone   /             orig
 //               /          TOP
 //              /             \
 //             v               v
-//    TOP->region             region----+
+//    TOP->loop                loop----+
 //          |                    |      |
 //        stmt2                stmt2    |
 //          |                    |      |
@@ -2253,13 +2262,17 @@
 //                  stmt1
 //                    |
 //                    v
+//                  stmt2 clone
+//                    |
+//                    v
 //         ........> ifA clone
 //         :        / |
 //        dom      /  |
 //         :      v   v
 //         :  false   true
 //         :  |       |
-//         :  |     stmt2 clone
+//         :  |       v
+//         :  | loop predicate
 //         :  |       |
 //         :  |       v
 //         :  |    newloop<-----+
@@ -2289,6 +2302,7 @@
 //
 bool PhaseIdealLoop::partial_peel( IdealLoopTree *loop, Node_List &old_new ) {
 
+  assert(!loop->_head->is_CountedLoop(), "Non-counted loop only");
   if (!loop->_head->is_Loop()) {
     return false;  }
 
@@ -2316,6 +2330,7 @@
     }
   }
 
+  Node* entry = head->in(LoopNode::EntryControl);
   int dd = dom_depth(head);
 
   // Step 1: find cut point
@@ -2612,6 +2627,8 @@
 
   // Backedge of the surviving new_head (the clone) is original last_peel
   _igvn.hash_delete(new_head_clone);
+  Node* new_entry = move_loop_predicates(entry, new_head_clone->in(LoopNode::EntryControl));
+  new_head_clone->set_req(LoopNode::EntryControl, new_entry);
   new_head_clone->set_req(LoopNode::LoopBackControl, last_peel);
   _igvn._worklist.push(new_head_clone);
 
--- a/src/share/vm/opto/parse2.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/opto/parse2.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -795,8 +795,9 @@
   taken = method()->scale_count(taken);
   not_taken = method()->scale_count(not_taken);
 
-  // Give up if too few counts to be meaningful
-  if (taken + not_taken < 40) {
+  // Give up if too few (or too many, in which case the sum will overflow) counts to be meaningful.
+  // We also check that individual counters are positive first, overwise the sum can become positive.
+  if (taken < 0 || not_taken < 0 || taken + not_taken < 40) {
     if (C->log() != NULL) {
       C->log()->elem("branch target_bci='%d' taken='%d' not_taken='%d'", iter().get_dest(), taken, not_taken);
     }
@@ -804,13 +805,13 @@
   }
 
   // Compute frequency that we arrive here
-  int sum = taken + not_taken;
+  float sum = taken + not_taken;
   // Adjust, if this block is a cloned private block but the
   // Jump counts are shared.  Taken the private counts for
   // just this path instead of the shared counts.
   if( block()->count() > 0 )
     sum = block()->count();
-  cnt = (float)sum / (float)FreqCountInvocations;
+  cnt = sum / FreqCountInvocations;
 
   // Pin probability to sane limits
   float prob;
--- a/src/share/vm/opto/phaseX.hpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/opto/phaseX.hpp	Thu Apr 21 08:12:46 2011 -0700
@@ -471,6 +471,13 @@
     _delay_transform = delay;
   }
 
+  // Clone loop predicates. Defined in loopTransform.cpp.
+  Node* clone_loop_predicates(Node* old_entry, Node* new_entry);
+  Node*  move_loop_predicates(Node* old_entry, Node* new_entry);
+  // Create a new if below new_entry for the predicate to be cloned
+  ProjNode* create_new_if_for_predicate(ProjNode* cont_proj, Node* new_entry,
+                                        Deoptimization::DeoptReason reason);
+
 #ifndef PRODUCT
 protected:
   // Sub-quadratic implementation of VerifyIterativeGVN.
--- a/src/share/vm/opto/split_if.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/opto/split_if.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -399,6 +399,9 @@
 #ifndef PRODUCT
   if( PrintOpto && VerifyLoopOptimizations )
     tty->print_cr("Split-if");
+  if (TraceLoopOpts) {
+    tty->print_cr("SplitIf");
+  }
 #endif
   C->set_major_progress();
   Node *region = iff->in(0);
--- a/src/share/vm/opto/superword.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/opto/superword.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -1132,6 +1132,13 @@
 void SuperWord::output() {
   if (_packset.length() == 0) return;
 
+#ifndef PRODUCT
+  if (TraceLoopOpts) {
+    tty->print("SuperWord    ");
+    lpt()->dump_head();
+  }
+#endif
+
   // MUST ENSURE main loop's initial value is properly aligned:
   //  (iv_initial_value + min_iv_offset) % vector_width_in_bytes() == 0
 
--- a/src/share/vm/opto/vectornode.hpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/opto/vectornode.hpp	Thu Apr 21 08:12:46 2011 -0700
@@ -32,6 +32,7 @@
 //------------------------------VectorNode--------------------------------------
 // Vector Operation
 class VectorNode : public Node {
+  virtual uint size_of() const { return sizeof(*this); }
  protected:
   uint _length; // vector length
   virtual BasicType elt_basic_type() const = 0; // Vector element basic type
--- a/src/share/vm/prims/jvm.h	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/prims/jvm.h	Thu Apr 21 08:12:46 2011 -0700
@@ -1062,7 +1062,7 @@
     JVM_CONSTANT_NameAndType,
     JVM_CONSTANT_MethodHandle           = 15,  // JSR 292
     JVM_CONSTANT_MethodType             = 16,  // JSR 292
-    JVM_CONSTANT_InvokeDynamicTrans     = 17,  // JSR 292, only occurs in old class files
+    //JVM_CONSTANT_(unused)             = 17,  // JSR 292 early drafts only
     JVM_CONSTANT_InvokeDynamic          = 18,  // JSR 292
     JVM_CONSTANT_ExternalMax            = 18   // Last tag found in classfiles
 };
--- a/src/share/vm/prims/jvmtiManageCapabilities.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/prims/jvmtiManageCapabilities.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -319,8 +319,11 @@
   bool enter_all_methods =
     interp_events ||
     avail.can_generate_breakpoint_events;
-  UseFastEmptyMethods = !enter_all_methods;
-  UseFastAccessorMethods = !enter_all_methods;
+  if (enter_all_methods) {
+    // Disable these when tracking the bytecodes
+    UseFastEmptyMethods = false;
+    UseFastAccessorMethods = false;
+  }
 
   if (avail.can_generate_breakpoint_events) {
     RewriteFrequentPairs = false;
--- a/src/share/vm/prims/methodHandleWalk.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/prims/methodHandleWalk.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -959,12 +959,6 @@
   if (m == NULL) {
     // Get the intrinsic methodOop.
     m = vmIntrinsics::method_for(iid);
-    if (m == NULL && iid == vmIntrinsics::_checkSpreadArgument && AllowTransitionalJSR292) {
-      m = vmIntrinsics::method_for(vmIntrinsics::_checkSpreadArgument_TRANS);
-      if (m == NULL)
-        // sun.dyn.MethodHandleImpl not found, look for java.dyn.MethodHandleNatives:
-        m = vmIntrinsics::method_for(vmIntrinsics::_checkSpreadArgument_TRANS2);
-    }
     if (m == NULL) {
       ArgToken zero;
       lose(vmIntrinsics::name_at(iid), CHECK_(zero));
--- a/src/share/vm/prims/methodHandleWalk.hpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/prims/methodHandleWalk.hpp	Thu Apr 21 08:12:46 2011 -0700
@@ -343,6 +343,7 @@
   int cpool_symbol_put(int tag, Symbol* con) {
     if (con == NULL)  return 0;
     ConstantValue* cv = new ConstantValue(tag, con);
+    con->increment_refcount();
     return _constants.append(cv);
   }
 
--- a/src/share/vm/prims/methodHandles.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/prims/methodHandles.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -928,6 +928,7 @@
 };
 
 static bool is_always_null_type(klassOop klass) {
+  if (klass == NULL)  return false;  // safety
   if (!Klass::cast(klass)->oop_is_instance())  return false;
   instanceKlass* ik = instanceKlass::cast(klass);
   // Must be on the boot class path:
@@ -944,6 +945,8 @@
 }
 
 bool MethodHandles::class_cast_needed(klassOop src, klassOop dst) {
+  if (dst == NULL)  return true;
+  if (src == NULL)  return (dst != SystemDictionary::Object_klass());
   if (src == dst || dst == SystemDictionary::Object_klass())
     return false;                               // quickest checks
   Klass* srck = Klass::cast(src);
@@ -1026,10 +1029,15 @@
                                             int first_ptype_pos,
                                             KlassHandle insert_ptype,
                                             TRAPS) {
+  Handle mhi_type;
+  if (m->is_method_handle_invoke()) {
+    // use this more exact typing instead of the symbolic signature:
+    mhi_type = Handle(THREAD, m->method_handle_type());
+  }
   objArrayHandle ptypes(THREAD, java_lang_invoke_MethodType::ptypes(mtype()));
   int pnum = first_ptype_pos;
   int pmax = ptypes->length();
-  int mnum = 0;                 // method argument
+  int anum = 0;                 // method argument
   const char* err = NULL;
   ResourceMark rm(THREAD);
   for (SignatureStream ss(m->signature()); !ss.is_done(); ss.next()) {
@@ -1048,47 +1056,70 @@
       else
         ptype_oop = insert_ptype->java_mirror();
       pnum += 1;
-      mnum += 1;
+      anum += 1;
     }
-    klassOop  pklass = NULL;
-    BasicType ptype  = T_OBJECT;
-    if (ptype_oop != NULL)
-      ptype = java_lang_Class::as_BasicType(ptype_oop, &pklass);
-    else
-      // null does not match any non-reference; use Object to report the error
-      pklass = SystemDictionary::Object_klass();
-    klassOop  mklass = NULL;
-    BasicType mtype  = ss.type();
-    if (mtype == T_ARRAY)  mtype = T_OBJECT; // fold all refs to T_OBJECT
-    if (mtype == T_OBJECT) {
-      if (ptype_oop == NULL) {
+    KlassHandle pklass;
+    BasicType   ptype = T_OBJECT;
+    bool   have_ptype = false;
+    // missing ptype_oop does not match any non-reference; use Object to report the error
+    pklass = SystemDictionaryHandles::Object_klass();
+    if (ptype_oop != NULL) {
+      have_ptype = true;
+      klassOop pklass_oop = NULL;
+      ptype = java_lang_Class::as_BasicType(ptype_oop, &pklass_oop);
+      pklass = KlassHandle(THREAD, pklass_oop);
+    }
+    ptype_oop = NULL; //done with this
+    KlassHandle aklass;
+    BasicType   atype = ss.type();
+    if (atype == T_ARRAY)  atype = T_OBJECT; // fold all refs to T_OBJECT
+    if (atype == T_OBJECT) {
+      if (!have_ptype) {
         // null matches any reference
         continue;
       }
-      KlassHandle pklass_handle(THREAD, pklass); pklass = NULL;
-      // If we fail to resolve types at this point, we will throw an error.
-      Symbol* name = ss.as_symbol(CHECK);
-      instanceKlass* mk = instanceKlass::cast(m->method_holder());
-      Handle loader(THREAD, mk->class_loader());
-      Handle domain(THREAD, mk->protection_domain());
-      mklass = SystemDictionary::resolve_or_null(name, loader, domain, CHECK);
-      pklass = pklass_handle();
-      if (mklass == NULL && pklass != NULL &&
-          Klass::cast(pklass)->name() == name &&
-          m->is_method_handle_invoke()) {
-        // Assume a match.  We can't really decode the signature of MH.invoke*.
-        continue;
+      if (mhi_type.is_null()) {
+        // If we fail to resolve types at this point, we will usually throw an error.
+        TempNewSymbol name = ss.as_symbol_or_null();
+        if (name != NULL) {
+          instanceKlass* mk = instanceKlass::cast(m->method_holder());
+          Handle loader(THREAD, mk->class_loader());
+          Handle domain(THREAD, mk->protection_domain());
+          klassOop aklass_oop = SystemDictionary::resolve_or_null(name, loader, domain, CHECK);
+          if (aklass_oop != NULL)
+            aklass = KlassHandle(THREAD, aklass_oop);
+        }
+      } else {
+        // for method handle invokers we don't look at the name in the signature
+        oop atype_oop;
+        if (ss.at_return_type())
+          atype_oop = java_lang_invoke_MethodType::rtype(mhi_type());
+        else
+          atype_oop = java_lang_invoke_MethodType::ptype(mhi_type(), anum-1);
+        klassOop aklass_oop = NULL;
+        atype = java_lang_Class::as_BasicType(atype_oop, &aklass_oop);
+        aklass = KlassHandle(THREAD, aklass_oop);
       }
     }
     if (!ss.at_return_type()) {
-      err = check_argument_type_change(ptype, pklass, mtype, mklass, mnum);
+      err = check_argument_type_change(ptype, pklass(), atype, aklass(), anum);
     } else {
-      err = check_return_type_change(mtype, mklass, ptype, pklass); // note reversal!
+      err = check_return_type_change(atype, aklass(), ptype, pklass()); // note reversal!
     }
     if (err != NULL)  break;
   }
 
   if (err != NULL) {
+#ifndef PRODUCT
+    if (PrintMiscellaneous && (Verbose || WizardMode)) {
+      tty->print("*** verify_method_signature failed: ");
+      java_lang_invoke_MethodType::print_signature(mtype(), tty);
+      tty->cr();
+      tty->print_cr("    first_ptype_pos = %d, insert_ptype = "UINTX_FORMAT, first_ptype_pos, insert_ptype());
+      tty->print("    Failing method: ");
+      m->print();
+    }
+#endif //PRODUCT
     THROW_MSG(vmSymbols::java_lang_InternalError(), err);
   }
 }
@@ -1288,10 +1319,12 @@
   // format, format, format
   const char* src_name = type2name(src_type);
   const char* dst_name = type2name(dst_type);
-  if (src_type == T_OBJECT)  src_name = Klass::cast(src_klass)->external_name();
-  if (dst_type == T_OBJECT)  dst_name = Klass::cast(dst_klass)->external_name();
   if (src_name == NULL)  src_name = "unknown type";
   if (dst_name == NULL)  dst_name = "unknown type";
+  if (src_type == T_OBJECT)
+    src_name = (src_klass != NULL) ? Klass::cast(src_klass)->external_name() : "an unresolved class";
+  if (dst_type == T_OBJECT)
+    dst_name = (dst_klass != NULL) ? Klass::cast(dst_klass)->external_name() : "an unresolved class";
 
   size_t msglen = strlen(err) + strlen(src_name) + strlen(dst_name) + (argnum < 10 ? 1 : 11);
   char* msg = NEW_RESOURCE_ARRAY(char, msglen + 1);
@@ -2488,74 +2521,21 @@
 }
 JVM_END
 
-JVM_ENTRY(void, MHN_registerBootstrap(JNIEnv *env, jobject igcls, jclass caller_jh, jobject bsm_jh)) {
-  instanceKlassHandle ik = MethodHandles::resolve_instance_klass(caller_jh, THREAD);
-  if (!AllowTransitionalJSR292) {
-    THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
-              "registerBootstrapMethod is only supported in JSR 292 EDR");
-  }
-  ik->link_class(CHECK);
-  if (!java_lang_invoke_MethodHandle::is_instance(JNIHandles::resolve(bsm_jh))) {
-    THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "method handle");
-  }
-  const char* err = NULL;
-  if (ik->is_initialized() || ik->is_in_error_state()) {
-    err = "too late: class is already initialized";
-  } else {
-    ObjectLocker ol(ik, THREAD);  // note:  this should be a recursive lock
-    if (ik->is_not_initialized() ||
-        (ik->is_being_initialized() && ik->is_reentrant_initialization(THREAD))) {
-      if (ik->bootstrap_method() != NULL) {
-        err = "class is already equipped with a bootstrap method";
-      } else {
-        ik->set_bootstrap_method(JNIHandles::resolve_non_null(bsm_jh));
-        err = NULL;
-      }
-    } else {
-      err = "class is already initialized";
-      if (ik->is_being_initialized())
-        err = "class is already being initialized in a different thread";
-    }
-  }
-  if (err != NULL) {
-    THROW_MSG(vmSymbols::java_lang_IllegalStateException(), err);
-  }
-}
-JVM_END
-
-JVM_ENTRY(jobject, MHN_getBootstrap(JNIEnv *env, jobject igcls, jclass caller_jh)) {
-  if (!AllowTransitionalJSR292)
-    THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), "getBootstrap: transitional only");
-  instanceKlassHandle ik = MethodHandles::resolve_instance_klass(caller_jh, THREAD);
-  return JNIHandles::make_local(THREAD, ik->bootstrap_method());
-}
-JVM_END
-
-JVM_ENTRY(void, MHN_setCallSiteTarget(JNIEnv *env, jobject igcls, jobject site_jh, jobject target_jh)) {
-  if (!AllowTransitionalJSR292)
-    THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "setCallSite: transitional only");
-}
-JVM_END
-
 
 /// JVM_RegisterMethodHandleMethods
 
 #define LANG "Ljava/lang/"
-#define JLINV "Ljava/lang/invoke/" /* standard package */
-#define JDYN "Ljava/dyn/" /* alternative package to JLINV if AllowTransitionalJSR292 */
-#define IDYN "Lsun/dyn/"  /* alternative package to JDYN if AllowTransitionalJSR292 */
-// FIXME: After AllowTransitionalJSR292 is removed, replace JDYN and IDYN by JLINV.
+#define JLINV "Ljava/lang/invoke/"
 
 #define OBJ   LANG"Object;"
 #define CLS   LANG"Class;"
 #define STRG  LANG"String;"
-#define CST   JDYN"CallSite;"
-#define MT    JDYN"MethodType;"
-#define MH    JDYN"MethodHandle;"
-#define MEM   IDYN"MemberName;"
-#define AMH   IDYN"AdapterMethodHandle;"
-#define BMH   IDYN"BoundMethodHandle;"
-#define DMH   IDYN"DirectMethodHandle;"
+#define MT    JLINV"MethodType;"
+#define MH    JLINV"MethodHandle;"
+#define MEM   JLINV"MemberName;"
+#define AMH   JLINV"AdapterMethodHandle;"
+#define BMH   JLINV"BoundMethodHandle;"
+#define DMH   JLINV"DirectMethodHandle;"
 
 #define CC (char*)  /*cast a literal from (const char*)*/
 #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)
@@ -2579,39 +2559,6 @@
   {CC"getMembers",              CC"("CLS""STRG""STRG"I"CLS"I["MEM")I",  FN_PTR(MHN_getMembers)}
 };
 
-// FIXME: Remove methods2 after AllowTransitionalJSR292 is removed.
-static JNINativeMethod methods2[] = {
-  {CC"registerBootstrap",       CC"("CLS MH")V",                FN_PTR(MHN_registerBootstrap)},
-  {CC"getBootstrap",            CC"("CLS")"MH,                  FN_PTR(MHN_getBootstrap)},
-  {CC"setCallSiteTarget",       CC"("CST MH")V",                FN_PTR(MHN_setCallSiteTarget)}
-};
-
-static void hack_signatures(JNINativeMethod* methods, jint num_methods, const char* from_sig, const char* to_sig) {
-  for (int i = 0; i < num_methods; i++) {
-    const char* sig = methods[i].signature;
-    if (!strstr(sig, from_sig))  continue;
-    size_t buflen = strlen(sig) + 100;
-    char* buf = NEW_C_HEAP_ARRAY(char, buflen);
-    char* bufp = buf;
-    const char* sigp = sig;
-    size_t from_len = strlen(from_sig), to_len = strlen(to_sig);
-    while (*sigp != '\0') {
-      assert(bufp < buf + buflen - to_len - 1, "oob");
-      if (strncmp(sigp, from_sig, from_len) != 0) {
-        *bufp++ = *sigp++;
-      } else {
-        strcpy(bufp, to_sig);
-        bufp += to_len;
-        sigp += from_len;
-      }
-    }
-    *bufp = '\0';
-    methods[i].signature = buf;  // replace with new signature
-    if (TraceMethodHandles)
-      tty->print_cr("MethodHandleNatives: %s: change signature %s => %s", methods[i].name, sig, buf);
-  }
-}
-
 // This one function is exported, used by NativeLookup.
 
 JVM_ENTRY(void, JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass MHN_class)) {
@@ -2622,92 +2569,41 @@
     return;  // bind nothing
   }
 
-  if (SystemDictionary::MethodHandleNatives_klass() != NULL &&
-      SystemDictionary::MethodHandleNatives_klass() != java_lang_Class::as_klassOop(JNIHandles::resolve(MHN_class))) {
-    warning("multiple versions of MethodHandleNatives in boot classpath; consider using -XX:+PreferTransitionalJSR292");
-    THROW_MSG(vmSymbols::java_lang_InternalError(), "multiple versions of MethodHandleNatives in boot classpath; consider using -XX:+PreferTransitionalJSR292");
-  }
-
   bool enable_MH = true;
 
-  // Loop control.  FIXME: Replace by dead reckoning after AllowTransitionalJSR292 is removed.
-  bool registered_natives = false;
-  bool try_plain = true, try_JDYN = true, try_IDYN = true;
-  for (;;) {
+  {
     ThreadToNativeFromVM ttnfv(thread);
 
-    if      (try_plain) { try_plain = false; }
-    else if (try_JDYN)  { try_JDYN  = false; hack_signatures(methods, sizeof(methods)/sizeof(JNINativeMethod), IDYN, JDYN); }
-    else if (try_IDYN)  { try_IDYN  = false; hack_signatures(methods, sizeof(methods)/sizeof(JNINativeMethod), JDYN, JLINV); }
-    else                { break; }
     int status = env->RegisterNatives(MHN_class, methods, sizeof(methods)/sizeof(JNINativeMethod));
     if (env->ExceptionOccurred()) {
+      MethodHandles::set_enabled(false);
+      warning("JSR 292 method handle code is mismatched to this JVM.  Disabling support.");
+      enable_MH = false;
       env->ExceptionClear();
-      // and try again...
-    } else {
-      registered_natives = true;
-      break;
     }
   }
-  if (!registered_natives) {
-    MethodHandles::set_enabled(false);
-    warning("JSR 292 method handle code is mismatched to this JVM.  Disabling support.");
-    enable_MH = false;
-  }
 
   if (enable_MH) {
-    bool found_raise_exception = false;
     KlassHandle MHN_klass = SystemDictionaryHandles::MethodHandleNatives_klass();
-    KlassHandle MHI_klass = SystemDictionaryHandles::MethodHandleImpl_klass();
-    // Loop control.  FIXME: Replace by dead reckoning after AllowTransitionalJSR292 is removed.
-    bool try_MHN = true, try_MHI = AllowTransitionalJSR292;
-    for (;;) {
-      KlassHandle try_klass;
-      if      (try_MHN) { try_MHN = false; try_klass = MHN_klass; }
-      else if (try_MHI) { try_MHI = false; try_klass = MHI_klass; }
-      else              { break; }
-      if (try_klass.is_null())  continue;
+    if (MHN_klass.not_null()) {
       TempNewSymbol raiseException_name = SymbolTable::new_symbol("raiseException", CHECK);
       TempNewSymbol raiseException_sig = SymbolTable::new_symbol("(ILjava/lang/Object;Ljava/lang/Object;)V", CHECK);
-      methodOop raiseException_method  = instanceKlass::cast(try_klass->as_klassOop())
+      methodOop raiseException_method  = instanceKlass::cast(MHN_klass->as_klassOop())
                     ->find_method(raiseException_name, raiseException_sig);
       if (raiseException_method != NULL && raiseException_method->is_static()) {
         MethodHandles::set_raise_exception_method(raiseException_method);
-        found_raise_exception = true;
-        break;
+      } else {
+        warning("JSR 292 method handle code is mismatched to this JVM.  Disabling support.");
+        enable_MH = false;
       }
-    }
-    if (!found_raise_exception) {
-      warning("JSR 292 method handle code is mismatched to this JVM.  Disabling support.");
+    } else {
       enable_MH = false;
     }
   }
 
   if (enable_MH) {
-    if (AllowTransitionalJSR292) {
-      // We need to link the MethodHandleImpl klass before we generate
-      // the method handle adapters as the _raise_exception adapter uses
-      // one of its methods (and its c2i-adapter).
-      klassOop k = SystemDictionary::MethodHandleImpl_klass();
-      if (k != NULL) {
-        instanceKlass* ik = instanceKlass::cast(k);
-        ik->link_class(CHECK);
-      }
-    }
-
     MethodHandles::generate_adapters();
     MethodHandles::set_enabled(true);
   }
-
-  if (AllowTransitionalJSR292) {
-    ThreadToNativeFromVM ttnfv(thread);
-
-    int status = env->RegisterNatives(MHN_class, methods2, sizeof(methods2)/sizeof(JNINativeMethod));
-    if (env->ExceptionOccurred()) {
-      // Don't do this, since it's too late:
-      //   MethodHandles::set_enabled(false)
-      env->ExceptionClear();
-    }
-  }
 }
 JVM_END
--- a/src/share/vm/prims/nativeLookup.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/prims/nativeLookup.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -117,8 +117,6 @@
 
   { CC"Java_sun_misc_Unsafe_registerNatives",                      NULL, FN_PTR(JVM_RegisterUnsafeMethods)       },
   { CC"Java_java_lang_invoke_MethodHandleNatives_registerNatives", NULL, FN_PTR(JVM_RegisterMethodHandleMethods) },
-  { CC"Java_sun_dyn_MethodHandleNatives_registerNatives",          NULL, FN_PTR(JVM_RegisterMethodHandleMethods) },  // AllowTransitionalJSR292
-  { CC"Java_java_dyn_MethodHandleNatives_registerNatives",         NULL, FN_PTR(JVM_RegisterMethodHandleMethods) },  // AllowTransitionalJSR292
   { CC"Java_sun_misc_Perf_registerNatives",                        NULL, FN_PTR(JVM_RegisterPerfMethods)         }
 };
 
--- a/src/share/vm/runtime/arguments.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/runtime/arguments.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -59,7 +59,8 @@
 #include "gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp"
 #endif
 
-#define DEFAULT_VENDOR_URL_BUG "http://java.sun.com/webapps/bugreport/crash.jsp"
+// Note: This is a special bug reporting site for the JVM
+#define DEFAULT_VENDOR_URL_BUG "http://bugreport.sun.com/bugreport/crash.jsp"
 #define DEFAULT_JAVA_LAUNCHER  "generic"
 
 char**  Arguments::_jvm_flags_array             = NULL;
@@ -243,6 +244,7 @@
   { "MaxLiveObjectEvacuationRatio",
                            JDK_Version::jdk_update(6,24), JDK_Version::jdk(8) },
   { "ForceSharedSpaces",   JDK_Version::jdk_update(6,25), JDK_Version::jdk(8) },
+  { "AllowTransitionalJSR292",       JDK_Version::jdk(7), JDK_Version::jdk(8) },
   { NULL, JDK_Version(0), JDK_Version(0) }
 };
 
@@ -962,6 +964,16 @@
   UseCompiler                = true;
   UseLoopCounter             = true;
 
+#ifndef ZERO
+  // Turn these off for mixed and comp.  Leave them on for Zero.
+  if (FLAG_IS_DEFAULT(UseFastAccessorMethods)) {
+    UseFastAccessorMethods = mode == _int;
+  }
+  if (FLAG_IS_DEFAULT(UseFastEmptyMethods)) {
+    UseFastEmptyMethods = mode == _int;
+  }
+#endif
+
   // Default values may be platform/compiler dependent -
   // use the saved values
   ClipInlining               = Arguments::_ClipInlining;
--- a/src/share/vm/runtime/globals.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/runtime/globals.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -63,6 +63,12 @@
 
 bool Flag::is_unlocked() const {
   if (strcmp(kind, "{diagnostic}") == 0) {
+    if (strcmp(name, "EnableInvokeDynamic") == 0 && UnlockExperimentalVMOptions && !UnlockDiagnosticVMOptions) {
+      // transitional logic to allow tests to run until they are changed
+      static int warned;
+      if (++warned == 1)  warning("Use -XX:+UnlockDiagnosticVMOptions before EnableInvokeDynamic flag");
+      return true;
+    }
     return UnlockDiagnosticVMOptions;
   } else if (strcmp(kind, "{experimental}") == 0 ||
              strcmp(kind, "{C2 experimental}") == 0) {
--- a/src/share/vm/runtime/globals.hpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/runtime/globals.hpp	Thu Apr 21 08:12:46 2011 -0700
@@ -3718,13 +3718,7 @@
   experimental(bool, TrustFinalNonStaticFields, false,                      \
           "trust final non-static declarations for constant folding")       \
                                                                             \
-  experimental(bool, AllowTransitionalJSR292, true,                         \
-          "recognize pre-PFD formats of invokedynamic")                     \
-                                                                            \
-  experimental(bool, PreferTransitionalJSR292, false,                       \
-          "prefer pre-PFD APIs on boot class path, if they exist")          \
-                                                                            \
-  experimental(bool, AllowInvokeForInvokeGeneric, false,                    \
+  experimental(bool, AllowInvokeGeneric, true,                              \
           "accept MethodHandle.invoke and MethodHandle.invokeGeneric "      \
           "as equivalent methods")                                          \
                                                                             \
--- a/src/share/vm/runtime/os.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/runtime/os.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -1291,3 +1291,41 @@
   }
   return result;
 }
+
+// Read file line by line, if line is longer than bsize,
+// skip rest of line.
+int os::get_line_chars(int fd, char* buf, const size_t bsize){
+  size_t sz, i = 0;
+
+  // read until EOF, EOL or buf is full
+  while ((sz = (int) read(fd, &buf[i], 1)) == 1 && i < (bsize-1) && buf[i] != '\n') {
+     ++i;
+  }
+
+  if (buf[i] == '\n') {
+    // EOL reached so ignore EOL character and return
+
+    buf[i] = 0;
+    return (int) i;
+  }
+
+  buf[i+1] = 0;
+
+  if (sz != 1) {
+    // EOF reached. if we read chars before EOF return them and
+    // return EOF on next call otherwise return EOF
+
+    return (i == 0) ? -1 : (int) i;
+  }
+
+  // line is longer than size of buf, skip to EOL
+  int ch;
+  while (read(fd, &ch, 1) == 1 && ch != '\n') {
+    // Do nothing
+  }
+
+  // return initial part of line that fits in buf.
+  // If we reached EOF, it will be returned on next call.
+
+  return (int) i;
+}
--- a/src/share/vm/runtime/os.hpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/runtime/os.hpp	Thu Apr 21 08:12:46 2011 -0700
@@ -658,6 +658,10 @@
   // Hook for os specific jvm options that we don't want to abort on seeing
   static bool obsolete_option(const JavaVMOption *option);
 
+  // Read file line by line. If line is longer than bsize,
+  // rest of line is skipped. Returns number of bytes read or -1 on EOF
+  static int get_line_chars(int fd, char *buf, const size_t bsize);
+
   // Platform dependent stuff
 #ifdef TARGET_OS_FAMILY_linux
 # include "os_linux.hpp"
--- a/src/share/vm/runtime/sharedRuntime.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/runtime/sharedRuntime.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -1700,9 +1700,11 @@
     message = generate_class_cast_message(objName, targetKlass->external_name());
   } else {
     // %%% need to get the MethodType string, without messing around too much
+    const char* desc = NULL;
     // Get a signature from the invoke instruction
     const char* mhName = "method handle";
     const char* targetType = "the required signature";
+    int targetArity = -1, mhArity = -1;
     vframeStream vfst(thread, true);
     if (!vfst.at_end()) {
       Bytecode_invoke call(vfst.method(), vfst.bci());
@@ -1716,20 +1718,35 @@
           && target->is_method_handle_invoke()
           && required == target->method_handle_type()) {
         targetType = target->signature()->as_C_string();
+        targetArity = ArgumentCount(target->signature()).size();
       }
     }
-    klassOop kignore; int fignore;
-    methodOop actual_method = MethodHandles::decode_method(actual,
-                                                          kignore, fignore);
+    klassOop kignore; int dmf_flags = 0;
+    methodOop actual_method = MethodHandles::decode_method(actual, kignore, dmf_flags);
+    if ((dmf_flags & ~(MethodHandles::_dmf_has_receiver |
+                       MethodHandles::_dmf_does_dispatch |
+                       MethodHandles::_dmf_from_interface)) != 0)
+      actual_method = NULL;  // MH does extra binds, drops, etc.
+    bool has_receiver = ((dmf_flags & MethodHandles::_dmf_has_receiver) != 0);
     if (actual_method != NULL) {
-      if (methodOopDesc::is_method_handle_invoke_name(actual_method->name()))
-        mhName = "$";
+      mhName = actual_method->signature()->as_C_string();
+      mhArity = ArgumentCount(actual_method->signature()).size();
+      if (!actual_method->is_static())  mhArity += 1;
+    } else if (java_lang_invoke_MethodHandle::is_instance(actual)) {
+      oopDesc* mhType = java_lang_invoke_MethodHandle::type(actual);
+      mhArity = java_lang_invoke_MethodType::ptype_count(mhType);
+      stringStream st;
+      java_lang_invoke_MethodType::print_signature(mhType, &st);
+      mhName = st.as_string();
+    }
+    if (targetArity != -1 && targetArity != mhArity) {
+      if (has_receiver && targetArity == mhArity-1)
+        desc = " cannot be called without a receiver argument as ";
       else
-        mhName = actual_method->signature()->as_C_string();
-      if (mhName[0] == '$')
-        mhName = actual_method->signature()->as_C_string();
+        desc = " cannot be called with a different arity as ";
     }
     message = generate_class_cast_message(mhName, targetType,
+                                          desc != NULL ? desc :
                                           " cannot be called as ");
   }
   if (TraceMethodHandles) {
--- a/src/share/vm/runtime/stubRoutines.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/runtime/stubRoutines.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -433,3 +433,77 @@
 
 #undef RETURN_STUB
 }
+
+// constants for computing the copy function
+enum {
+  COPYFUNC_UNALIGNED = 0,
+  COPYFUNC_ALIGNED = 1,                 // src, dest aligned to HeapWordSize
+  COPYFUNC_CONJOINT = 0,
+  COPYFUNC_DISJOINT = 2                 // src != dest, or transfer can descend
+};
+
+// Note:  The condition "disjoint" applies also for overlapping copies
+// where an descending copy is permitted (i.e., dest_offset <= src_offset).
+address
+StubRoutines::select_arraycopy_function(BasicType t, bool aligned, bool disjoint, const char* &name, bool dest_uninitialized) {
+  int selector =
+    (aligned  ? COPYFUNC_ALIGNED  : COPYFUNC_UNALIGNED) +
+    (disjoint ? COPYFUNC_DISJOINT : COPYFUNC_CONJOINT);
+
+#define RETURN_STUB(xxx_arraycopy) { \
+  name = #xxx_arraycopy; \
+  return StubRoutines::xxx_arraycopy(); }
+
+#define RETURN_STUB_PARM(xxx_arraycopy, parm) {           \
+  name = #xxx_arraycopy; \
+  return StubRoutines::xxx_arraycopy(parm); }
+
+  switch (t) {
+  case T_BYTE:
+  case T_BOOLEAN:
+    switch (selector) {
+    case COPYFUNC_CONJOINT | COPYFUNC_UNALIGNED:  RETURN_STUB(jbyte_arraycopy);
+    case COPYFUNC_CONJOINT | COPYFUNC_ALIGNED:    RETURN_STUB(arrayof_jbyte_arraycopy);
+    case COPYFUNC_DISJOINT | COPYFUNC_UNALIGNED:  RETURN_STUB(jbyte_disjoint_arraycopy);
+    case COPYFUNC_DISJOINT | COPYFUNC_ALIGNED:    RETURN_STUB(arrayof_jbyte_disjoint_arraycopy);
+    }
+  case T_CHAR:
+  case T_SHORT:
+    switch (selector) {
+    case COPYFUNC_CONJOINT | COPYFUNC_UNALIGNED:  RETURN_STUB(jshort_arraycopy);
+    case COPYFUNC_CONJOINT | COPYFUNC_ALIGNED:    RETURN_STUB(arrayof_jshort_arraycopy);
+    case COPYFUNC_DISJOINT | COPYFUNC_UNALIGNED:  RETURN_STUB(jshort_disjoint_arraycopy);
+    case COPYFUNC_DISJOINT | COPYFUNC_ALIGNED:    RETURN_STUB(arrayof_jshort_disjoint_arraycopy);
+    }
+  case T_INT:
+  case T_FLOAT:
+    switch (selector) {
+    case COPYFUNC_CONJOINT | COPYFUNC_UNALIGNED:  RETURN_STUB(jint_arraycopy);
+    case COPYFUNC_CONJOINT | COPYFUNC_ALIGNED:    RETURN_STUB(arrayof_jint_arraycopy);
+    case COPYFUNC_DISJOINT | COPYFUNC_UNALIGNED:  RETURN_STUB(jint_disjoint_arraycopy);
+    case COPYFUNC_DISJOINT | COPYFUNC_ALIGNED:    RETURN_STUB(arrayof_jint_disjoint_arraycopy);
+    }
+  case T_DOUBLE:
+  case T_LONG:
+    switch (selector) {
+    case COPYFUNC_CONJOINT | COPYFUNC_UNALIGNED:  RETURN_STUB(jlong_arraycopy);
+    case COPYFUNC_CONJOINT | COPYFUNC_ALIGNED:    RETURN_STUB(arrayof_jlong_arraycopy);
+    case COPYFUNC_DISJOINT | COPYFUNC_UNALIGNED:  RETURN_STUB(jlong_disjoint_arraycopy);
+    case COPYFUNC_DISJOINT | COPYFUNC_ALIGNED:    RETURN_STUB(arrayof_jlong_disjoint_arraycopy);
+    }
+  case T_ARRAY:
+  case T_OBJECT:
+    switch (selector) {
+    case COPYFUNC_CONJOINT | COPYFUNC_UNALIGNED:  RETURN_STUB_PARM(oop_arraycopy, dest_uninitialized);
+    case COPYFUNC_CONJOINT | COPYFUNC_ALIGNED:    RETURN_STUB_PARM(arrayof_oop_arraycopy, dest_uninitialized);
+    case COPYFUNC_DISJOINT | COPYFUNC_UNALIGNED:  RETURN_STUB_PARM(oop_disjoint_arraycopy, dest_uninitialized);
+    case COPYFUNC_DISJOINT | COPYFUNC_ALIGNED:    RETURN_STUB_PARM(arrayof_oop_disjoint_arraycopy, dest_uninitialized);
+    }
+  default:
+    ShouldNotReachHere();
+    return NULL;
+  }
+
+#undef RETURN_STUB
+#undef RETURN_STUB_PARM
+}
--- a/src/share/vm/runtime/stubRoutines.hpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/runtime/stubRoutines.hpp	Thu Apr 21 08:12:46 2011 -0700
@@ -282,6 +282,8 @@
   static address addr_fpu_subnormal_bias2()                { return (address)&_fpu_subnormal_bias2; }
 
 
+  static address select_arraycopy_function(BasicType t, bool aligned, bool disjoint, const char* &name, bool dest_uninitialized);
+
   static address jbyte_arraycopy()  { return _jbyte_arraycopy; }
   static address jshort_arraycopy() { return _jshort_arraycopy; }
   static address jint_arraycopy()   { return _jint_arraycopy; }
--- a/src/share/vm/runtime/sweeper.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/runtime/sweeper.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -418,6 +418,11 @@
 // state of the code cache if it's requested.
 void NMethodSweeper::log_sweep(const char* msg, const char* format, ...) {
   if (PrintMethodFlushing) {
+    stringStream s;
+    // Dump code cache state into a buffer before locking the tty,
+    // because log_state() will use locks causing lock conflicts.
+    CodeCache::log_state(&s);
+
     ttyLocker ttyl;
     tty->print("### sweeper: %s ", msg);
     if (format != NULL) {
@@ -426,10 +431,15 @@
       tty->vprint(format, ap);
       va_end(ap);
     }
-    CodeCache::log_state(tty); tty->cr();
+    tty->print_cr(s.as_string());
   }
 
   if (LogCompilation && (xtty != NULL)) {
+    stringStream s;
+    // Dump code cache state into a buffer before locking the tty,
+    // because log_state() will use locks causing lock conflicts.
+    CodeCache::log_state(&s);
+
     ttyLocker ttyl;
     xtty->begin_elem("sweeper state='%s' traversals='" INTX_FORMAT "' ", msg, (intx)traversal_count());
     if (format != NULL) {
@@ -438,7 +448,7 @@
       xtty->vprint(format, ap);
       va_end(ap);
     }
-    CodeCache::log_state(xtty);
+    xtty->print(s.as_string());
     xtty->stamp();
     xtty->end_elem();
   }
--- a/src/share/vm/shark/llvmHeaders.hpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/shark/llvmHeaders.hpp	Thu Apr 21 08:12:46 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2008, 2009, 2010 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -46,7 +46,11 @@
 #include <llvm/ModuleProvider.h>
 #endif
 #include <llvm/Support/IRBuilder.h>
+#if SHARK_LLVM_VERSION >= 29
+#include <llvm/Support/Threading.h>
+#else
 #include <llvm/System/Threading.h>
+#endif
 #include <llvm/Target/TargetSelect.h>
 #include <llvm/Type.h>
 #include <llvm/ExecutionEngine/JITMemoryManager.h>
@@ -55,8 +59,12 @@
 #include <llvm/ExecutionEngine/JIT.h>
 #include <llvm/ADT/StringMap.h>
 #include <llvm/Support/Debug.h>
+#if SHARK_LLVM_VERSION >= 29
+#include <llvm/Support/Host.h>
+#else
 #include <llvm/System/Host.h>
 #endif
+#endif
 
 #include <map>
 
--- a/src/share/vm/shark/sharkCompiler.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/shark/sharkCompiler.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2008, 2009, 2010 Red Hat, Inc.
+ * Copyright 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
@@ -218,6 +218,7 @@
 
 nmethod* SharkCompiler::generate_native_wrapper(MacroAssembler* masm,
                                                 methodHandle    target,
+                                                int             compile_id,
                                                 BasicType*      arg_types,
                                                 BasicType       return_type) {
   assert(is_initialized(), "should be");
@@ -241,6 +242,7 @@
 
   // Return the nmethod for installation in the VM
   return nmethod::new_native_nmethod(target,
+                                     compile_id,
                                      masm->code(),
                                      0,
                                      0,
--- a/src/share/vm/shark/sharkCompiler.hpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/shark/sharkCompiler.hpp	Thu Apr 21 08:12:46 2011 -0700
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2008, 2009 Red Hat, Inc.
+ * Copyright 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
@@ -60,6 +60,7 @@
   // Generate a wrapper for a native (JNI) method
   nmethod* generate_native_wrapper(MacroAssembler* masm,
                                    methodHandle    target,
+                                   int             compile_id,
                                    BasicType*      arg_types,
                                    BasicType       return_type);
 
@@ -113,7 +114,8 @@
   // Global access
  public:
   static SharkCompiler* compiler() {
-    AbstractCompiler *compiler = CompileBroker::compiler(CompLevel_simple);
+    AbstractCompiler *compiler =
+      CompileBroker::compiler(CompLevel_full_optimization);
     assert(compiler->is_shark() && compiler->is_initialized(), "should be");
     return (SharkCompiler *) compiler;
   }
--- a/src/share/vm/utilities/constantTag.cpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/utilities/constantTag.cpp	Thu Apr 21 08:12:46 2011 -0700
@@ -93,8 +93,6 @@
       return "MethodType";
     case JVM_CONSTANT_InvokeDynamic :
       return "InvokeDynamic";
-    case JVM_CONSTANT_InvokeDynamicTrans :
-      return "InvokeDynamic/transitional";
     case JVM_CONSTANT_Object :
       return "Object";
     case JVM_CONSTANT_Utf8 :
--- a/src/share/vm/utilities/constantTag.hpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/utilities/constantTag.hpp	Thu Apr 21 08:12:46 2011 -0700
@@ -86,8 +86,7 @@
 
   bool is_method_type() const              { return _tag == JVM_CONSTANT_MethodType; }
   bool is_method_handle() const            { return _tag == JVM_CONSTANT_MethodHandle; }
-  bool is_invoke_dynamic() const           { return (_tag == JVM_CONSTANT_InvokeDynamic ||
-                                                     _tag == JVM_CONSTANT_InvokeDynamicTrans); }
+  bool is_invoke_dynamic() const           { return _tag == JVM_CONSTANT_InvokeDynamic; }
 
   bool is_loadable_constant() const {
     return ((_tag >= JVM_CONSTANT_Integer && _tag <= JVM_CONSTANT_String) ||
--- a/src/share/vm/utilities/globalDefinitions.hpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/utilities/globalDefinitions.hpp	Thu Apr 21 08:12:46 2011 -0700
@@ -746,9 +746,9 @@
   CompLevel_simple            = 1,         // C1
   CompLevel_limited_profile   = 2,         // C1, invocation & backedge counters
   CompLevel_full_profile      = 3,         // C1, invocation & backedge counters + mdo
-  CompLevel_full_optimization = 4,         // C2
+  CompLevel_full_optimization = 4,         // C2 or Shark
 
-#if defined(COMPILER2)
+#if defined(COMPILER2) || defined(SHARK)
   CompLevel_highest_tier      = CompLevel_full_optimization,  // pure C2 and tiered
 #elif defined(COMPILER1)
   CompLevel_highest_tier      = CompLevel_simple,             // pure C1
@@ -760,7 +760,7 @@
   CompLevel_initial_compile   = CompLevel_full_profile        // tiered
 #elif defined(COMPILER1)
   CompLevel_initial_compile   = CompLevel_simple              // pure C1
-#elif defined(COMPILER2)
+#elif defined(COMPILER2) || defined(SHARK)
   CompLevel_initial_compile   = CompLevel_full_optimization   // pure C2
 #else
   CompLevel_initial_compile   = CompLevel_none
--- a/src/share/vm/utilities/globalDefinitions_gcc.hpp	Wed Apr 20 07:43:25 2011 -0700
+++ b/src/share/vm/utilities/globalDefinitions_gcc.hpp	Thu Apr 21 08:12:46 2011 -0700
@@ -77,7 +77,9 @@
 # endif
 
 #ifdef LINUX
+#ifndef __STDC_LIMIT_MACROS
 #define __STDC_LIMIT_MACROS
+#endif // __STDC_LIMIT_MACROS
 #include <inttypes.h>
 #include <signal.h>
 #include <ucontext.h>
--- a/test/compiler/6795161/Test.java	Wed Apr 20 07:43:25 2011 -0700
+++ b/test/compiler/6795161/Test.java	Thu Apr 21 08:12:46 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,7 @@
  * @test
  * @bug 6795161
  * @summary Escape analysis leads to data corruption
- * @run main/othervm -server -Xcomp -XX:CompileOnly=Test -XX:+DoEscapeAnalysis Test
+ * @run main/othervm -server  -XX:+IgnoreUnrecognizedVMOptions -Xcomp -XX:CompileOnly=Test -XX:+DoEscapeAnalysis Test
  */
 
 class Test_Class_1 {