changeset 2844:d968f546734e

Merge
author iveresov
date Wed, 07 Sep 2011 11:52:00 -0700
parents 4668545121b8 (current diff) c2d3caa64b3e (diff)
children 5596e125fe4f
files agent/src/share/classes/sun/jvm/hotspot/runtime/amd64/AMD64Frame.java agent/src/share/classes/sun/jvm/hotspot/runtime/amd64/AMD64RegisterMap.java make/solaris/makefiles/mapfile-vers-nonproduct src/cpu/sparc/vm/assembler_sparc.cpp src/cpu/sparc/vm/assembler_sparc.hpp src/cpu/sparc/vm/c1_Runtime1_sparc.cpp src/share/vm/gc_interface/collectedHeap.cpp src/share/vm/runtime/globals.hpp src/share/vm/runtime/reflectionCompat.hpp
diffstat 130 files changed, 2147 insertions(+), 2372 deletions(-) [+]
line wrap: on
line diff
--- a/agent/src/share/classes/sun/jvm/hotspot/HSDB.java	Fri Sep 02 21:33:57 2011 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/HSDB.java	Wed Sep 07 11:52:00 2011 -0700
@@ -1740,7 +1740,7 @@
       else if (f.isCompiledFrame())    { tty.print("compiled"); }
       else if (f.isEntryFrame())       { tty.print("entry"); }
       else if (f.isNativeFrame())      { tty.print("native"); }
-      else if (f.isGlueFrame())        { tty.print("glue"); }
+      else if (f.isRuntimeFrame())     { tty.print("runtime"); }
       else { tty.print("external"); }
       tty.print(" frame with PC = " + f.getPC() + ", SP = " + f.getSP() + ", FP = " + f.getFP());
       if (f.isSignalHandlerFrameDbg()) {
--- a/agent/src/share/classes/sun/jvm/hotspot/code/CodeBlob.java	Fri Sep 02 21:33:57 2011 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/code/CodeBlob.java	Wed Sep 07 11:52:00 2011 -0700
@@ -102,6 +102,11 @@
   /** On-Stack Replacement method */
   public boolean isOSRMethod()          { return false; }
 
+  public NMethod asNMethodOrNull() {
+    if (isNMethod()) return (NMethod)this;
+    return null;
+  }
+
   // Boundaries
   public Address headerBegin() {
     return addr;
@@ -195,7 +200,7 @@
   }
 
   // Returns true, if the next frame is responsible for GC'ing oops passed as arguments
-  public boolean callerMustGCArguments(JavaThread thread) { return false; }
+  public boolean callerMustGCArguments() { return false; }
 
   public String getName() {
     return CStringUtilities.getString(nameField.getValue(addr));
--- a/agent/src/share/classes/sun/jvm/hotspot/code/CodeCache.java	Fri Sep 02 21:33:57 2011 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/code/CodeCache.java	Wed Sep 07 11:52:00 2011 -0700
@@ -59,6 +59,7 @@
     virtualConstructor.addMapping("RuntimeStub", RuntimeStub.class);
     virtualConstructor.addMapping("RicochetBlob", RicochetBlob.class);
     virtualConstructor.addMapping("AdapterBlob", AdapterBlob.class);
+    virtualConstructor.addMapping("MethodHandlesAdapterBlob", MethodHandlesAdapterBlob.class);
     virtualConstructor.addMapping("SafepointBlob", SafepointBlob.class);
     virtualConstructor.addMapping("DeoptimizationBlob", DeoptimizationBlob.class);
     if (VM.getVM().isServerCompiler()) {
@@ -126,6 +127,10 @@
       Assert.that(result.blobContains(start) || result.blobContains(start.addOffsetTo(8)),
                                                                     "found wrong CodeBlob");
     }
+    if (result.isRicochetBlob()) {
+      // This should probably be done for other SingletonBlobs
+      return VM.getVM().ricochetBlob();
+    }
     return result;
   }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/agent/src/share/classes/sun/jvm/hotspot/code/MethodHandlesAdapterBlob.java	Wed Sep 07 11:52:00 2011 -0700
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package sun.jvm.hotspot.code;
+
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.types.*;
+
+public class MethodHandlesAdapterBlob extends AdapterBlob {
+  static {
+    VM.registerVMInitializedObserver(new Observer() {
+        public void update(Observable o, Object data) {
+          initialize(VM.getVM().getTypeDataBase());
+        }
+      });
+  }
+
+  private static void initialize(TypeDataBase db) {
+    Type type = db.lookupType("MethodHandlesAdapterBlob");
+
+    // FIXME: add any needed fields
+  }
+
+  public MethodHandlesAdapterBlob(Address addr) {
+    super(addr);
+  }
+
+  public boolean isMethodHandlesAdapterBlob() {
+    return true;
+  }
+
+  public String getName() {
+    return "MethodHandlesAdapterBlob: " + super.getName();
+  }
+}
--- a/agent/src/share/classes/sun/jvm/hotspot/code/NMethod.java	Fri Sep 02 21:33:57 2011 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/code/NMethod.java	Wed Sep 07 11:52:00 2011 -0700
@@ -46,6 +46,7 @@
   /** Offsets for different nmethod parts */
   private static CIntegerField exceptionOffsetField;
   private static CIntegerField deoptOffsetField;
+  private static CIntegerField deoptMhOffsetField;
   private static CIntegerField origPCOffsetField;
   private static CIntegerField stubOffsetField;
   private static CIntegerField oopsOffsetField;
@@ -95,6 +96,7 @@
 
     exceptionOffsetField        = type.getCIntegerField("_exception_offset");
     deoptOffsetField            = type.getCIntegerField("_deoptimize_offset");
+    deoptMhOffsetField          = type.getCIntegerField("_deoptimize_mh_offset");
     origPCOffsetField           = type.getCIntegerField("_orig_pc_offset");
     stubOffsetField             = type.getCIntegerField("_stub_offset");
     oopsOffsetField             = type.getCIntegerField("_oops_offset");
@@ -136,10 +138,11 @@
   /** Boundaries for different parts */
   public Address constantsBegin()       { return contentBegin();                                     }
   public Address constantsEnd()         { return getEntryPoint();                                    }
-  public Address instsBegin()           { return codeBegin();                                       }
+  public Address instsBegin()           { return codeBegin();                                        }
   public Address instsEnd()             { return headerBegin().addOffsetTo(getStubOffset());         }
   public Address exceptionBegin()       { return headerBegin().addOffsetTo(getExceptionOffset());    }
-  public Address deoptBegin()           { return headerBegin().addOffsetTo(getDeoptOffset());        }
+  public Address deoptHandlerBegin()    { return headerBegin().addOffsetTo(getDeoptOffset());        }
+  public Address deoptMhHandlerBegin()  { return headerBegin().addOffsetTo(getDeoptMhOffset());      }
   public Address stubBegin()            { return headerBegin().addOffsetTo(getStubOffset());         }
   public Address stubEnd()              { return headerBegin().addOffsetTo(getOopsOffset());         }
   public Address oopsBegin()            { return headerBegin().addOffsetTo(getOopsOffset());         }
@@ -250,6 +253,22 @@
     return (int) scavengeRootStateField.getValue(addr);
   }
 
+  // MethodHandle
+  public boolean isMethodHandleReturn(Address returnPc) {
+    // Hard to read a bit fields from Java and it's only there for performance
+    // so just go directly to the PCDesc
+    // if (!hasMethodHandleInvokes())  return false;
+    PCDesc pd = getPCDescAt(returnPc);
+    if (pd == null)
+      return false;
+    return pd.isMethodHandleInvoke();
+  }
+
+  // Deopt
+  // Return true is the PC is one would expect if the frame is being deopted.
+  public boolean isDeoptPc      (Address pc) { return isDeoptEntry(pc) || isDeoptMhEntry(pc); }
+  public boolean isDeoptEntry   (Address pc) { return pc == deoptHandlerBegin(); }
+  public boolean isDeoptMhEntry (Address pc) { return pc == deoptMhHandlerBegin(); }
 
   /** Tells whether frames described by this nmethod can be
       deoptimized. Note: native wrappers cannot be deoptimized. */
@@ -388,6 +407,7 @@
   private int getEntryBCI()           { return (int) entryBCIField          .getValue(addr); }
   private int getExceptionOffset()    { return (int) exceptionOffsetField   .getValue(addr); }
   private int getDeoptOffset()        { return (int) deoptOffsetField       .getValue(addr); }
+  private int getDeoptMhOffset()      { return (int) deoptMhOffsetField     .getValue(addr); }
   private int getStubOffset()         { return (int) stubOffsetField        .getValue(addr); }
   private int getOopsOffset()         { return (int) oopsOffsetField        .getValue(addr); }
   private int getScopesDataOffset()   { return (int) scopesDataOffsetField  .getValue(addr); }
--- a/agent/src/share/classes/sun/jvm/hotspot/code/PCDesc.java	Fri Sep 02 21:33:57 2011 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/code/PCDesc.java	Wed Sep 07 11:52:00 2011 -0700
@@ -38,6 +38,9 @@
   private static CIntegerField scopeDecodeOffsetField;
   private static CIntegerField objDecodeOffsetField;
   private static CIntegerField pcFlagsField;
+  private static int reexecuteMask;
+  private static int isMethodHandleInvokeMask;
+  private static int returnOopMask;
 
   static {
     VM.registerVMInitializedObserver(new Observer() {
@@ -54,6 +57,10 @@
     scopeDecodeOffsetField = type.getCIntegerField("_scope_decode_offset");
     objDecodeOffsetField   = type.getCIntegerField("_obj_decode_offset");
     pcFlagsField           = type.getCIntegerField("_flags");
+
+    reexecuteMask            = db.lookupIntConstant("PcDesc::PCDESC_reexecute");
+    isMethodHandleInvokeMask = db.lookupIntConstant("PcDesc::PCDESC_is_method_handle_invoke");
+    returnOopMask            = db.lookupIntConstant("PcDesc::PCDESC_return_oop");
   }
 
   public PCDesc(Address addr) {
@@ -81,7 +88,12 @@
 
   public boolean getReexecute() {
     int flags = (int)pcFlagsField.getValue(addr);
-    return ((flags & 0x1)== 1); //first is the reexecute bit
+    return (flags & reexecuteMask) != 0;
+  }
+
+  public boolean isMethodHandleInvoke() {
+    int flags = (int)pcFlagsField.getValue(addr);
+    return (flags & isMethodHandleInvokeMask) != 0;
   }
 
   public void print(NMethod code) {
--- a/agent/src/share/classes/sun/jvm/hotspot/code/RicochetBlob.java	Fri Sep 02 21:33:57 2011 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/code/RicochetBlob.java	Wed Sep 07 11:52:00 2011 -0700
@@ -41,11 +41,15 @@
   }
 
   private static void initialize(TypeDataBase db) {
-    // Type type = db.lookupType("RicochetBlob");
+    Type type = db.lookupType("RicochetBlob");
 
-    // FIXME: add any needed fields
+    bounceOffsetField                = type.getCIntegerField("_bounce_offset");
+    exceptionOffsetField             = type.getCIntegerField("_exception_offset");
   }
 
+  private static CIntegerField bounceOffsetField;
+  private static CIntegerField exceptionOffsetField;
+
   public RicochetBlob(Address addr) {
     super(addr);
   }
@@ -53,4 +57,14 @@
   public boolean isRicochetBlob() {
     return true;
   }
+
+  public Address bounceAddr() {
+    return codeBegin().addOffsetTo(bounceOffsetField.getValue(addr));
+  }
+
+  public boolean returnsToBounceAddr(Address pc) {
+    Address bouncePc = bounceAddr();
+    return (pc.equals(bouncePc) || pc.addOffsetTo(Frame.pcReturnOffset()).equals(bouncePc));
+  }
+
 }
--- a/agent/src/share/classes/sun/jvm/hotspot/code/RuntimeStub.java	Fri Sep 02 21:33:57 2011 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/code/RuntimeStub.java	Wed Sep 07 11:52:00 2011 -0700
@@ -30,6 +30,8 @@
 import sun.jvm.hotspot.types.*;
 
 public class RuntimeStub extends CodeBlob {
+  private static CIntegerField callerMustGCArgumentsField;
+
   static {
     VM.registerVMInitializedObserver(new Observer() {
         public void update(Observable o, Object data) {
@@ -40,6 +42,7 @@
 
   private static void initialize(TypeDataBase db) {
     Type type = db.lookupType("RuntimeStub");
+    callerMustGCArgumentsField                = type.getCIntegerField("_caller_must_gc_arguments");
 
     // FIXME: add any needed fields
   }
@@ -52,6 +55,11 @@
     return true;
   }
 
+  public boolean callerMustGCArguments() {
+    return callerMustGCArgumentsField.getValue(addr) != 0;
+  }
+
+
   public String getName() {
     return "RuntimeStub: " + super.getName();
   }
--- a/agent/src/share/classes/sun/jvm/hotspot/compiler/OopMapSet.java	Fri Sep 02 21:33:57 2011 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/compiler/OopMapSet.java	Wed Sep 07 11:52:00 2011 -0700
@@ -246,7 +246,7 @@
     }
 
     // Check if caller must update oop argument
-    regMap.setIncludeArgumentOops(cb.callerMustGCArguments(regMap.getThread()));
+    regMap.setIncludeArgumentOops(cb.callerMustGCArguments());
 
     int nofCallee = 0;
     Address[] locs = new Address[2 * REG_COUNT + 1];
--- a/agent/src/share/classes/sun/jvm/hotspot/interpreter/BytecodeLoadConstant.java	Fri Sep 02 21:33:57 2011 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/interpreter/BytecodeLoadConstant.java	Wed Sep 07 11:52:00 2011 -0700
@@ -90,7 +90,7 @@
            jcode == Bytecodes._ldc2_w;
     if (! codeOk) return false;
 
-    ConstantTag ctag = method().getConstants().getTagAt(rawIndex());
+    ConstantTag ctag = method().getConstants().getTagAt(poolIndex());
     if (jcode == Bytecodes._ldc2_w) {
        // has to be double or long
        return (ctag.isDouble() || ctag.isLong()) ? true: false;
--- a/agent/src/share/classes/sun/jvm/hotspot/jdi/ReferenceTypeImpl.java	Fri Sep 02 21:33:57 2011 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/jdi/ReferenceTypeImpl.java	Wed Sep 07 11:52:00 2011 -0700
@@ -28,11 +28,13 @@
 
 import com.sun.jdi.*;
 
+import sun.jvm.hotspot.memory.SystemDictionary;
 import sun.jvm.hotspot.oops.Instance;
 import sun.jvm.hotspot.oops.InstanceKlass;
 import sun.jvm.hotspot.oops.ArrayKlass;
 import sun.jvm.hotspot.oops.JVMDIClassStatus;
 import sun.jvm.hotspot.oops.Klass;
+import sun.jvm.hotspot.oops.ObjArray;
 import sun.jvm.hotspot.oops.Oop;
 import sun.jvm.hotspot.oops.Symbol;
 import sun.jvm.hotspot.oops.DefaultHeapVisitor;
@@ -53,6 +55,7 @@
     private SoftReference methodsCache;
     private SoftReference allMethodsCache;
     private SoftReference nestedTypesCache;
+    private SoftReference methodInvokesCache;
 
     /* to mark when no info available */
     static final SDE NO_SDE_INFO_MARK = new SDE();
@@ -82,6 +85,27 @@
                 return method;
             }
         }
+        if (ref.getMethodHolder().equals(SystemDictionary.getMethodHandleKlass())) {
+          // invoke methods are generated as needed, so make mirrors as needed
+          List mis = null;
+          if (methodInvokesCache == null) {
+            mis = new ArrayList();
+            methodInvokesCache = new SoftReference(mis);
+          } else {
+            mis = (List)methodInvokesCache.get();
+          }
+          it = mis.iterator();
+          while (it.hasNext()) {
+            MethodImpl method = (MethodImpl)it.next();
+            if (ref.equals(method.ref())) {
+              return method;
+            }
+          }
+
+          MethodImpl method = MethodImpl.createMethodImpl(vm, this, ref);
+          mis.add(method);
+          return method;
+        }
         throw new IllegalArgumentException("Invalid method id: " + ref);
     }
 
--- a/agent/src/share/classes/sun/jvm/hotspot/jdi/StackFrameImpl.java	Fri Sep 02 21:33:57 2011 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/jdi/StackFrameImpl.java	Wed Sep 07 11:52:00 2011 -0700
@@ -123,6 +123,9 @@
                 Assert.that(values.size() > 0, "this is missing");
             }
             // 'this' at index 0.
+            if (values.get(0).getType() == BasicType.getTConflict()) {
+              return null;
+            }
             OopHandle handle = values.oopHandleAt(0);
             ObjectHeap heap = vm.saObjectHeap();
             thisObject = vm.objectMirror(heap.newOop(handle));
@@ -210,6 +213,8 @@
         validateStackFrame();
         StackValueCollection values = saFrame.getLocals();
         MethodImpl mmm = (MethodImpl)location.method();
+        if (mmm.isNative())
+            return null;
         List argSigs = mmm.argumentSignatures();
         int count = argSigs.size();
         List res = new ArrayList(0);
@@ -231,34 +236,67 @@
         ValueImpl valueImpl = null;
         OopHandle handle = null;
         ObjectHeap heap = vm.saObjectHeap();
-        if (variableType == BasicType.T_BOOLEAN) {
+        if (values.get(ss).getType() == BasicType.getTConflict()) {
+          // Dead locals, so just represent them as a zero of the appropriate type
+          if (variableType == BasicType.T_BOOLEAN) {
+            valueImpl = (BooleanValueImpl) vm.mirrorOf(false);
+          } else if (variableType == BasicType.T_CHAR) {
+            valueImpl = (CharValueImpl) vm.mirrorOf((char)0);
+          } else if (variableType == BasicType.T_FLOAT) {
+            valueImpl = (FloatValueImpl) vm.mirrorOf((float)0);
+          } else if (variableType == BasicType.T_DOUBLE) {
+            valueImpl = (DoubleValueImpl) vm.mirrorOf((double)0);
+          } else if (variableType == BasicType.T_BYTE) {
+            valueImpl = (ByteValueImpl) vm.mirrorOf((byte)0);
+          } else if (variableType == BasicType.T_SHORT) {
+            valueImpl = (ShortValueImpl) vm.mirrorOf((short)0);
+          } else if (variableType == BasicType.T_INT) {
+            valueImpl = (IntegerValueImpl) vm.mirrorOf((int)0);
+          } else if (variableType == BasicType.T_LONG) {
+            valueImpl = (LongValueImpl) vm.mirrorOf((long)0);
+          } else if (variableType == BasicType.T_OBJECT) {
+            // we may have an [Ljava/lang/Object; - i.e., Object[] with the
+            // elements themselves may be arrays because every array is an Object.
+            handle = null;
+            valueImpl = (ObjectReferenceImpl) vm.objectMirror(heap.newOop(handle));
+          } else if (variableType == BasicType.T_ARRAY) {
+            handle = null;
+            valueImpl = vm.arrayMirror((Array)heap.newOop(handle));
+          } else if (variableType == BasicType.T_VOID) {
+            valueImpl = new VoidValueImpl(vm);
+          } else {
+            throw new RuntimeException("Should not read here");
+          }
+        } else {
+          if (variableType == BasicType.T_BOOLEAN) {
             valueImpl = (BooleanValueImpl) vm.mirrorOf(values.booleanAt(ss));
-        } else if (variableType == BasicType.T_CHAR) {
+          } else if (variableType == BasicType.T_CHAR) {
             valueImpl = (CharValueImpl) vm.mirrorOf(values.charAt(ss));
-        } else if (variableType == BasicType.T_FLOAT) {
+          } else if (variableType == BasicType.T_FLOAT) {
             valueImpl = (FloatValueImpl) vm.mirrorOf(values.floatAt(ss));
-        } else if (variableType == BasicType.T_DOUBLE) {
+          } else if (variableType == BasicType.T_DOUBLE) {
             valueImpl = (DoubleValueImpl) vm.mirrorOf(values.doubleAt(ss));
-        } else if (variableType == BasicType.T_BYTE) {
+          } else if (variableType == BasicType.T_BYTE) {
             valueImpl = (ByteValueImpl) vm.mirrorOf(values.byteAt(ss));
-        } else if (variableType == BasicType.T_SHORT) {
+          } else if (variableType == BasicType.T_SHORT) {
             valueImpl = (ShortValueImpl) vm.mirrorOf(values.shortAt(ss));
-        } else if (variableType == BasicType.T_INT) {
+          } else if (variableType == BasicType.T_INT) {
             valueImpl = (IntegerValueImpl) vm.mirrorOf(values.intAt(ss));
-        } else if (variableType == BasicType.T_LONG) {
+          } else if (variableType == BasicType.T_LONG) {
             valueImpl = (LongValueImpl) vm.mirrorOf(values.longAt(ss));
-        } else if (variableType == BasicType.T_OBJECT) {
+          } else if (variableType == BasicType.T_OBJECT) {
             // we may have an [Ljava/lang/Object; - i.e., Object[] with the
             // elements themselves may be arrays because every array is an Object.
             handle = values.oopHandleAt(ss);
             valueImpl = (ObjectReferenceImpl) vm.objectMirror(heap.newOop(handle));
-        } else if (variableType == BasicType.T_ARRAY) {
+          } else if (variableType == BasicType.T_ARRAY) {
             handle = values.oopHandleAt(ss);
             valueImpl = vm.arrayMirror((Array)heap.newOop(handle));
-        } else if (variableType == BasicType.T_VOID) {
+          } else if (variableType == BasicType.T_VOID) {
             valueImpl = new VoidValueImpl(vm);
-        } else {
+          } else {
             throw new RuntimeException("Should not read here");
+          }
         }
 
         return valueImpl;
--- a/agent/src/share/classes/sun/jvm/hotspot/memory/SystemDictionary.java	Fri Sep 02 21:33:57 2011 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/memory/SystemDictionary.java	Wed Sep 07 11:52:00 2011 -0700
@@ -44,6 +44,7 @@
   private static sun.jvm.hotspot.types.OopField systemKlassField;
   private static sun.jvm.hotspot.types.OopField threadKlassField;
   private static sun.jvm.hotspot.types.OopField threadGroupKlassField;
+  private static sun.jvm.hotspot.types.OopField methodHandleKlassField;
 
   static {
     VM.registerVMInitializedObserver(new Observer() {
@@ -69,6 +70,7 @@
     systemKlassField = type.getOopField(WK_KLASS("System_klass"));
     threadKlassField = type.getOopField(WK_KLASS("Thread_klass"));
     threadGroupKlassField = type.getOopField(WK_KLASS("ThreadGroup_klass"));
+    methodHandleKlassField = type.getOopField(WK_KLASS("MethodHandle_klass"));
   }
 
   // This WK functions must follow the definitions in systemDictionary.hpp:
@@ -127,6 +129,10 @@
     return (InstanceKlass) newOop(systemKlassField.getValue());
   }
 
+  public static InstanceKlass getMethodHandleKlass() {
+    return (InstanceKlass) newOop(methodHandleKlassField.getValue());
+  }
+
   public InstanceKlass getAbstractOwnableSynchronizerKlass() {
     return (InstanceKlass) find("java/util/concurrent/locks/AbstractOwnableSynchronizer",
                                 null, null);
--- a/agent/src/share/classes/sun/jvm/hotspot/runtime/CompiledVFrame.java	Fri Sep 02 21:33:57 2011 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/CompiledVFrame.java	Wed Sep 07 11:52:00 2011 -0700
@@ -93,6 +93,8 @@
   }
 
   public StackValueCollection getLocals() {
+    if (getScope() == null)
+      return new StackValueCollection();
     List scvList = getScope().getLocals();
     if (scvList == null)
       return new StackValueCollection();
@@ -108,6 +110,8 @@
   }
 
   public StackValueCollection getExpressions() {
+    if (getScope() == null)
+      return new StackValueCollection();
     List scvList = getScope().getExpressions();
     if (scvList == null)
       return new StackValueCollection();
--- a/agent/src/share/classes/sun/jvm/hotspot/runtime/Frame.java	Fri Sep 02 21:33:57 2011 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/Frame.java	Wed Sep 07 11:52:00 2011 -0700
@@ -33,6 +33,7 @@
 import sun.jvm.hotspot.debugger.*;
 import sun.jvm.hotspot.interpreter.*;
 import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.runtime.sparc.SPARCFrame;
 import sun.jvm.hotspot.types.*;
 import sun.jvm.hotspot.utilities.*;
 
@@ -74,11 +75,19 @@
   /** Size of constMethodOopDesc for computing BCI from BCP (FIXME: hack) */
   private static long    constMethodOopDescSize;
 
+  private static int pcReturnOffset;
+
+  public static int pcReturnOffset() {
+    return pcReturnOffset;
+  }
+
   private static synchronized void initialize(TypeDataBase db) {
     Type constMethodOopType = db.lookupType("constMethodOopDesc");
     // FIXME: not sure whether alignment here is correct or how to
     // force it (round up to address size?)
     constMethodOopDescSize = constMethodOopType.getSize();
+
+    pcReturnOffset = db.lookupIntConstant("frame::pc_return_offset").intValue();
   }
 
   protected int bcpToBci(Address bcp, ConstMethod cm) {
@@ -106,6 +115,10 @@
   public void    setPC(Address newpc) { pc = newpc; }
   public boolean isDeoptimized()      { return deoptimized; }
 
+  public CodeBlob cb() {
+    return VM.getVM().getCodeCache().findBlob(getPC());
+  }
+
   public abstract Address getSP();
   public abstract Address getID();
   public abstract Address getFP();
@@ -134,6 +147,12 @@
     }
   }
 
+  public boolean isRicochetFrame() {
+    CodeBlob cb = VM.getVM().getCodeCache().findBlob(getPC());
+    RicochetBlob rcb = VM.getVM().ricochetBlob();
+    return (cb == rcb && rcb != null && rcb.returnsToBounceAddr(getPC()));
+  }
+
   public boolean isCompiledFrame() {
     if (Assert.ASSERTS_ENABLED) {
       Assert.that(!VM.getVM().isCore(), "noncore builds only");
@@ -142,7 +161,7 @@
     return (cb != null && cb.isJavaMethod());
   }
 
-  public boolean isGlueFrame() {
+  public boolean isRuntimeFrame() {
     if (Assert.ASSERTS_ENABLED) {
       Assert.that(!VM.getVM().isCore(), "noncore builds only");
     }
@@ -197,7 +216,8 @@
   public Frame realSender(RegisterMap map) {
     if (!VM.getVM().isCore()) {
       Frame result = sender(map);
-      while (result.isGlueFrame()) {
+      while (result.isRuntimeFrame() ||
+             result.isRicochetFrame()) {
         result = result.sender(map);
       }
       return result;
@@ -611,6 +631,9 @@
     if (Assert.ASSERTS_ENABLED) {
       Assert.that(cb != null, "sanity check");
     }
+    if (cb == VM.getVM().ricochetBlob()) {
+      oopsRicochetDo(oopVisitor, regMap);
+    }
     if (cb.getOopMaps() != null) {
       OopMapSet.oopsDo(this, cb, regMap, oopVisitor, VM.getVM().isDebugging());
 
@@ -627,6 +650,10 @@
     //    }
   }
 
+  private void oopsRicochetDo      (AddressVisitor oopVisitor, RegisterMap regMap) {
+    // XXX Empty for now
+  }
+
   // FIXME: implement the above routines, plus add
   // oops_interpreted_arguments_do and oops_compiled_arguments_do
 }
--- a/agent/src/share/classes/sun/jvm/hotspot/runtime/JavaVFrame.java	Fri Sep 02 21:33:57 2011 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/JavaVFrame.java	Wed Sep 07 11:52:00 2011 -0700
@@ -128,14 +128,14 @@
       }
 
       // dynamic part - we just compare the frame pointer
-      if (! getFrame().getFP().equals(other.getFrame().getFP())) {
+      if (! getFrame().equals(other.getFrame())) {
           return false;
       }
       return true;
   }
 
   public int hashCode() {
-      return getMethod().hashCode() ^ getBCI() ^ getFrame().getFP().hashCode();
+      return getMethod().hashCode() ^ getBCI() ^ getFrame().hashCode();
   }
 
   /** Structural compare */
--- a/agent/src/share/classes/sun/jvm/hotspot/runtime/StackValue.java	Fri Sep 02 21:33:57 2011 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/StackValue.java	Wed Sep 07 11:52:00 2011 -0700
@@ -100,7 +100,7 @@
 
   public int hashCode() {
     if (type == BasicType.getTObject()) {
-      return handleValue.hashCode();
+      return handleValue != null ? handleValue.hashCode() : 5;
     } else {
       // Returns 0 for conflict type
       return (int) integerValue;
--- a/agent/src/share/classes/sun/jvm/hotspot/runtime/VFrame.java	Fri Sep 02 21:33:57 2011 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/VFrame.java	Wed Sep 07 11:52:00 2011 -0700
@@ -77,7 +77,7 @@
           return new CompiledVFrame(f, regMap, thread, scope, mayBeImprecise);
         }
 
-        if (f.isGlueFrame()) {
+        if (f.isRuntimeFrame()) {
           // This is a conversion frame. Skip this frame and try again.
           RegisterMap tempMap = regMap.copy();
           Frame s = f.sender(tempMap);
--- a/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java	Fri Sep 02 21:33:57 2011 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java	Wed Sep 07 11:52:00 2011 -0700
@@ -30,6 +30,7 @@
 import java.util.regex.*;
 import sun.jvm.hotspot.code.*;
 import sun.jvm.hotspot.c1.*;
+import sun.jvm.hotspot.code.*;
 import sun.jvm.hotspot.debugger.*;
 import sun.jvm.hotspot.interpreter.*;
 import sun.jvm.hotspot.memory.*;
@@ -85,6 +86,9 @@
   private Interpreter  interpreter;
   private StubRoutines stubRoutines;
   private Bytes        bytes;
+
+  private RicochetBlob ricochetBlob;
+
   /** Flags indicating whether we are attached to a core, C1, or C2 build */
   private boolean      usingClientCompiler;
   private boolean      usingServerCompiler;
@@ -618,6 +622,18 @@
     return stubRoutines;
   }
 
+  public RicochetBlob ricochetBlob() {
+    if (ricochetBlob == null) {
+      Type ricochetType  = db.lookupType("SharedRuntime");
+      AddressField ricochetBlobAddress = ricochetType.getAddressField("_ricochet_blob");
+      Address addr = ricochetBlobAddress.getValue();
+      if (addr != null) {
+        ricochetBlob = new RicochetBlob(addr);
+      }
+    }
+    return ricochetBlob;
+  }
+
   public VMRegImpl getVMRegImplInfo() {
     if (vmregImpl == null) {
       vmregImpl = new VMRegImpl();
--- a/agent/src/share/classes/sun/jvm/hotspot/runtime/amd64/AMD64CurrentFrameGuess.java	Fri Sep 02 21:33:57 2011 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/amd64/AMD64CurrentFrameGuess.java	Wed Sep 07 11:52:00 2011 -0700
@@ -29,6 +29,7 @@
 import sun.jvm.hotspot.code.*;
 import sun.jvm.hotspot.interpreter.*;
 import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.runtime.x86.*;
 
 /** <P> Should be able to be used on all amd64 platforms we support
     (Linux/amd64) to implement JavaThread's
@@ -123,7 +124,7 @@
              offset += vm.getAddressSize()) {
           try {
             Address curSP = sp.addOffsetTo(offset);
-            Frame frame = new AMD64Frame(curSP, null, pc);
+            Frame frame = new X86Frame(curSP, null, pc);
             RegisterMap map = thread.newRegisterMap(false);
             while (frame != null) {
               if (frame.isEntryFrame() && frame.entryFrameIsFirst()) {
--- a/agent/src/share/classes/sun/jvm/hotspot/runtime/amd64/AMD64Frame.java	Fri Sep 02 21:33:57 2011 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,528 +0,0 @@
-/*
- * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.runtime.amd64;
-
-import java.util.*;
-import sun.jvm.hotspot.code.*;
-import sun.jvm.hotspot.compiler.*;
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.oops.*;
-import sun.jvm.hotspot.runtime.*;
-import sun.jvm.hotspot.types.*;
-import sun.jvm.hotspot.utilities.*;
-
-/** Specialization of and implementation of abstract methods of the
-    Frame class for the amd64 CPU. */
-
-public class AMD64Frame extends Frame {
-  private static final boolean DEBUG;
-  static {
-    DEBUG = System.getProperty("sun.jvm.hotspot.runtime.amd64.AMD64Frame.DEBUG") != null;
-  }
-
-  // refer to frame_amd64.hpp
-  private static final int PC_RETURN_OFFSET           =  0;
-  // All frames
-  private static final int LINK_OFFSET                =  0;
-  private static final int RETURN_ADDR_OFFSET         =  1;
-  private static final int SENDER_SP_OFFSET           =  2;
-
-  // Interpreter frames
-  private static final int INTERPRETER_FRAME_MIRROR_OFFSET    =  2; // for native calls only
-  private static final int INTERPRETER_FRAME_SENDER_SP_OFFSET = -1;
-  private static final int INTERPRETER_FRAME_LAST_SP_OFFSET   = INTERPRETER_FRAME_SENDER_SP_OFFSET - 1;
-  private static final int INTERPRETER_FRAME_METHOD_OFFSET    = INTERPRETER_FRAME_LAST_SP_OFFSET - 1;
-  private static       int INTERPRETER_FRAME_MDX_OFFSET;         // Non-core builds only
-  private static       int INTERPRETER_FRAME_CACHE_OFFSET;
-  private static       int INTERPRETER_FRAME_LOCALS_OFFSET;
-  private static       int INTERPRETER_FRAME_BCX_OFFSET;
-  private static       int INTERPRETER_FRAME_INITIAL_SP_OFFSET;
-  private static       int INTERPRETER_FRAME_MONITOR_BLOCK_TOP_OFFSET;
-  private static       int INTERPRETER_FRAME_MONITOR_BLOCK_BOTTOM_OFFSET;
-
-  // Entry frames
-  private static final int ENTRY_FRAME_CALL_WRAPPER_OFFSET   =  -6;
-
-  // Native frames
-  private static final int NATIVE_FRAME_INITIAL_PARAM_OFFSET =  2;
-
-  static {
-    VM.registerVMInitializedObserver(new Observer() {
-        public void update(Observable o, Object data) {
-          initialize(VM.getVM().getTypeDataBase());
-        }
-      });
-  }
-
-  private static synchronized void initialize(TypeDataBase db) {
-    if (VM.getVM().isCore()) {
-      INTERPRETER_FRAME_CACHE_OFFSET = INTERPRETER_FRAME_METHOD_OFFSET - 1;
-    } else {
-      INTERPRETER_FRAME_MDX_OFFSET   = INTERPRETER_FRAME_METHOD_OFFSET - 1;
-      INTERPRETER_FRAME_CACHE_OFFSET = INTERPRETER_FRAME_MDX_OFFSET - 1;
-    }
-    INTERPRETER_FRAME_LOCALS_OFFSET               = INTERPRETER_FRAME_CACHE_OFFSET - 1;
-    INTERPRETER_FRAME_BCX_OFFSET                  = INTERPRETER_FRAME_LOCALS_OFFSET - 1;
-    INTERPRETER_FRAME_INITIAL_SP_OFFSET           = INTERPRETER_FRAME_BCX_OFFSET - 1;
-    INTERPRETER_FRAME_MONITOR_BLOCK_TOP_OFFSET    = INTERPRETER_FRAME_INITIAL_SP_OFFSET;
-    INTERPRETER_FRAME_MONITOR_BLOCK_BOTTOM_OFFSET = INTERPRETER_FRAME_INITIAL_SP_OFFSET;
-  }
-
-  // an additional field beyond sp and pc:
-  Address raw_fp; // frame pointer
-  private Address raw_unextendedSP;
-
-  private AMD64Frame() {
-  }
-
-  private void adjustForDeopt() {
-    if ( pc != null) {
-      // Look for a deopt pc and if it is deopted convert to original pc
-      CodeBlob cb = VM.getVM().getCodeCache().findBlob(pc);
-      if (cb != null && cb.isJavaMethod()) {
-        NMethod nm = (NMethod) cb;
-        if (pc.equals(nm.deoptBegin())) {
-          // adjust pc if frame is deoptimized.
-          if (Assert.ASSERTS_ENABLED) {
-            Assert.that(this.getUnextendedSP() != null, "null SP in Java frame");
-          }
-          pc = this.getUnextendedSP().getAddressAt(nm.origPCOffset());
-          deoptimized = true;
-        }
-      }
-    }
-  }
-
-  public AMD64Frame(Address raw_sp, Address raw_fp, Address pc) {
-    this.raw_sp = raw_sp;
-    this.raw_unextendedSP = raw_sp;
-    this.raw_fp = raw_fp;
-    this.pc = pc;
-
-    // Frame must be fully constructed before this call
-    adjustForDeopt();
-
-    if (DEBUG) {
-      System.out.println("AMD64Frame(sp, fp, pc): " + this);
-      dumpStack();
-    }
-  }
-
-  public AMD64Frame(Address raw_sp, Address raw_fp) {
-    this.raw_sp = raw_sp;
-    this.raw_unextendedSP = raw_sp;
-    this.raw_fp = raw_fp;
-    this.pc = raw_sp.getAddressAt(-1 * VM.getVM().getAddressSize());
-
-    // Frame must be fully constructed before this call
-    adjustForDeopt();
-
-    if (DEBUG) {
-      System.out.println("AMD64Frame(sp, fp): " + this);
-      dumpStack();
-    }
-  }
-
-  // This constructor should really take the unextended SP as an arg
-  // but then the constructor is ambiguous with constructor that takes
-  // a PC so take an int and convert it.
-  public AMD64Frame(Address raw_sp, Address raw_fp, long extension) {
-    this.raw_sp = raw_sp;
-    if ( raw_sp == null) {
-      this.raw_unextendedSP = null;
-    } else {
-      this.raw_unextendedSP = raw_sp.addOffsetTo(extension);
-    }
-    this.raw_fp = raw_fp;
-    this.pc = raw_sp.getAddressAt(-1 * VM.getVM().getAddressSize());
-
-    // Frame must be fully constructed before this call
-    adjustForDeopt();
-
-    if (DEBUG) {
-      System.out.println("AMD64Frame(sp, fp, extension): " + this);
-      dumpStack();
-    }
-
-  }
-
-  public Object clone() {
-    AMD64Frame frame = new AMD64Frame();
-    frame.raw_sp = raw_sp;
-    frame.raw_unextendedSP = raw_unextendedSP;
-    frame.raw_fp = raw_fp;
-    frame.pc = pc;
-    frame.deoptimized = deoptimized;
-    return frame;
-  }
-
-  public boolean equals(Object arg) {
-    if (arg == null) {
-      return false;
-    }
-
-    if (!(arg instanceof AMD64Frame)) {
-      return false;
-    }
-
-    AMD64Frame other = (AMD64Frame) arg;
-
-    return (AddressOps.equal(getSP(), other.getSP()) &&
-            AddressOps.equal(getFP(), other.getFP()) &&
-            AddressOps.equal(getUnextendedSP(), other.getUnextendedSP()) &&
-            AddressOps.equal(getPC(), other.getPC()));
-  }
-
-  public int hashCode() {
-    if (raw_sp == null) {
-      return 0;
-    }
-
-    return raw_sp.hashCode();
-  }
-
-  public String toString() {
-    return "sp: " + (getSP() == null? "null" : getSP().toString()) +
-         ", unextendedSP: " + (getUnextendedSP() == null? "null" : getUnextendedSP().toString()) +
-         ", fp: " + (getFP() == null? "null" : getFP().toString()) +
-         ", pc: " + (pc == null? "null" : pc.toString());
-  }
-
-  // accessors for the instance variables
-  public Address getFP() { return raw_fp; }
-  public Address getSP() { return raw_sp; }
-  public Address getID() { return raw_sp; }
-
-  // FIXME: not implemented yet (should be done for Solaris/AMD64)
-  public boolean isSignalHandlerFrameDbg() { return false; }
-  public int     getSignalNumberDbg()      { return 0;     }
-  public String  getSignalNameDbg()        { return null;  }
-
-  public boolean isInterpretedFrameValid() {
-    if (Assert.ASSERTS_ENABLED) {
-      Assert.that(isInterpretedFrame(), "Not an interpreted frame");
-    }
-
-    // These are reasonable sanity checks
-    if (getFP() == null || getFP().andWithMask(0x3) != null) {
-      return false;
-    }
-
-    if (getSP() == null || getSP().andWithMask(0x3) != null) {
-      return false;
-    }
-
-    if (getFP().addOffsetTo(INTERPRETER_FRAME_INITIAL_SP_OFFSET * VM.getVM().getAddressSize()).lessThan(getSP())) {
-      return false;
-    }
-
-    // These are hacks to keep us out of trouble.
-    // The problem with these is that they mask other problems
-    if (getFP().lessThanOrEqual(getSP())) {
-      // this attempts to deal with unsigned comparison above
-      return false;
-    }
-
-    if (getFP().minus(getSP()) > 4096 * VM.getVM().getAddressSize()) {
-      // stack frames shouldn't be large.
-      return false;
-    }
-
-    return true;
-  }
-
-  // FIXME: not applicable in current system
-  //  void    patch_pc(Thread* thread, address pc);
-
-  public Frame sender(RegisterMap regMap, CodeBlob cb) {
-    AMD64RegisterMap map = (AMD64RegisterMap) regMap;
-
-    if (Assert.ASSERTS_ENABLED) {
-      Assert.that(map != null, "map must be set");
-    }
-
-    // Default is we done have to follow them. The sender_for_xxx will
-    // update it accordingly
-    map.setIncludeArgumentOops(false);
-
-    if (isEntryFrame())       return senderForEntryFrame(map);
-    if (isInterpretedFrame()) return senderForInterpreterFrame(map);
-
-
-    if (!VM.getVM().isCore()) {
-      if(cb == null) {
-        cb = VM.getVM().getCodeCache().findBlob(getPC());
-      } else {
-        if (Assert.ASSERTS_ENABLED) {
-          Assert.that(cb.equals(VM.getVM().getCodeCache().findBlob(getPC())), "Must be the same");
-        }
-      }
-
-      if (cb != null) {
-         return senderForCompiledFrame(map, cb);
-      }
-    }
-
-    // Must be native-compiled frame, i.e. the marshaling code for native
-    // methods that exists in the core system.
-    return new AMD64Frame(getSenderSP(), getLink(), getSenderPC());
-  }
-
-  private Frame senderForEntryFrame(AMD64RegisterMap map) {
-    if (Assert.ASSERTS_ENABLED) {
-      Assert.that(map != null, "map must be set");
-    }
-    // Java frame called from C; skip all C frames and return top C
-    // frame of that chunk as the sender
-    AMD64JavaCallWrapper jcw = (AMD64JavaCallWrapper) getEntryFrameCallWrapper();
-    if (Assert.ASSERTS_ENABLED) {
-      Assert.that(!entryFrameIsFirst(), "next Java fp must be non zero");
-      Assert.that(jcw.getLastJavaSP().greaterThan(getSP()), "must be above this frame on stack");
-    }
-    AMD64Frame fr;
-    if (jcw.getLastJavaPC() != null) {
-      fr = new AMD64Frame(jcw.getLastJavaSP(), jcw.getLastJavaFP(), jcw.getLastJavaPC());
-    } else {
-      fr = new AMD64Frame(jcw.getLastJavaSP(), jcw.getLastJavaFP());
-    }
-    map.clear();
-    if (Assert.ASSERTS_ENABLED) {
-      Assert.that(map.getIncludeArgumentOops(), "should be set by clear");
-    }
-    return fr;
-  }
-
-  private Frame senderForInterpreterFrame(AMD64RegisterMap map) {
-    Address unextendedSP = addressOfStackSlot(INTERPRETER_FRAME_SENDER_SP_OFFSET).getAddressAt(0);
-    Address sp = addressOfStackSlot(SENDER_SP_OFFSET);
-    // We do not need to update the callee-save register mapping because above
-    // us is either another interpreter frame or a converter-frame, but never
-    // directly a compiled frame.
-    // 11/24/04 SFG. This is no longer true after adapter were removed. However at the moment
-    // C2 no longer uses callee save register for java calls so there are no callee register
-    // to find.
-    return new AMD64Frame(sp, getLink(), unextendedSP.minus(sp));
-  }
-
-  private Frame senderForCompiledFrame(AMD64RegisterMap map, CodeBlob cb) {
-    //
-    // NOTE: some of this code is (unfortunately) duplicated in AMD64CurrentFrameGuess
-    //
-
-    if (Assert.ASSERTS_ENABLED) {
-      Assert.that(map != null, "map must be set");
-    }
-
-    // frame owned by optimizing compiler
-    Address        sender_sp = null;
-
-
-    if (VM.getVM().isClientCompiler()) {
-      sender_sp        = addressOfStackSlot(SENDER_SP_OFFSET);
-    } else {
-      if (Assert.ASSERTS_ENABLED) {
-        Assert.that(cb.getFrameSize() >= 0, "Compiled by Compiler1: do not use");
-      }
-      sender_sp = getUnextendedSP().addOffsetTo(cb.getFrameSize());
-    }
-
-    // On Intel the return_address is always the word on the stack
-    Address sender_pc = sender_sp.getAddressAt(-1 * VM.getVM().getAddressSize());
-
-    if (map.getUpdateMap() && cb.getOopMaps() != null) {
-      OopMapSet.updateRegisterMap(this, cb, map, true);
-    }
-
-    if (VM.getVM().isClientCompiler()) {
-      // Move this here for C1 and collecting oops in arguments (According to Rene)
-      map.setIncludeArgumentOops(cb.callerMustGCArguments(map.getThread()));
-    }
-
-    Address saved_fp = null;
-    if (VM.getVM().isClientCompiler()) {
-      saved_fp = getFP().getAddressAt(0);
-    } else if (VM.getVM().isServerCompiler() &&
-               (VM.getVM().getInterpreter().contains(sender_pc) ||
-               VM.getVM().getStubRoutines().returnsToCallStub(sender_pc))) {
-      // C2 prologue saves EBP in the usual place.
-      // however only use it if the sender had link infomration in it.
-      saved_fp = sender_sp.getAddressAt(-2 * VM.getVM().getAddressSize());
-    }
-
-    return new AMD64Frame(sender_sp, saved_fp, sender_pc);
-  }
-
-  protected boolean hasSenderPD() {
-    // FIXME
-    // Check for null ebp? Need to do some tests.
-    return true;
-  }
-
-  public long frameSize() {
-    return (getSenderSP().minus(getSP()) / VM.getVM().getAddressSize());
-  }
-
-  public Address getLink() {
-    return addressOfStackSlot(LINK_OFFSET).getAddressAt(0);
-  }
-
-  // FIXME: not implementable yet
-  //inline void      frame::set_link(intptr_t* addr)  { *(intptr_t **)addr_at(link_offset) = addr; }
-
-  public Address getUnextendedSP() { return raw_unextendedSP; }
-
-  // Return address:
-  public Address getSenderPCAddr() { return addressOfStackSlot(RETURN_ADDR_OFFSET); }
-  public Address getSenderPC()     { return getSenderPCAddr().getAddressAt(0);      }
-
-  // return address of param, zero origin index.
-  public Address getNativeParamAddr(int idx) {
-    return addressOfStackSlot(NATIVE_FRAME_INITIAL_PARAM_OFFSET + idx);
-  }
-
-  public Address getSenderSP()     { return addressOfStackSlot(SENDER_SP_OFFSET); }
-
-  public Address compiledArgumentToLocationPD(VMReg reg, RegisterMap regMap, int argSize) {
-    if (VM.getVM().isCore() || VM.getVM().isClientCompiler()) {
-      throw new RuntimeException("Should not reach here");
-    }
-
-    return oopMapRegToLocation(reg, regMap);
-  }
-
-  public Address addressOfInterpreterFrameLocals() {
-    return addressOfStackSlot(INTERPRETER_FRAME_LOCALS_OFFSET);
-  }
-
-  private Address addressOfInterpreterFrameBCX() {
-    return addressOfStackSlot(INTERPRETER_FRAME_BCX_OFFSET);
-  }
-
-  public int getInterpreterFrameBCI() {
-    // FIXME: this is not atomic with respect to GC and is unsuitable
-    // for use in a non-debugging, or reflective, system. Need to
-    // figure out how to express this.
-    Address bcp = addressOfInterpreterFrameBCX().getAddressAt(0);
-    OopHandle methodHandle = addressOfInterpreterFrameMethod().getOopHandleAt(0);
-    Method method = (Method) VM.getVM().getObjectHeap().newOop(methodHandle);
-    return (int) bcpToBci(bcp, method);
-  }
-
-  public Address addressOfInterpreterFrameMDX() {
-    return addressOfStackSlot(INTERPRETER_FRAME_MDX_OFFSET);
-  }
-
-  // FIXME
-  //inline int frame::interpreter_frame_monitor_size() {
-  //  return BasicObjectLock::size();
-  //}
-
-  // expression stack
-  // (the max_stack arguments are used by the GC; see class FrameClosure)
-
-  public Address addressOfInterpreterFrameExpressionStack() {
-    Address monitorEnd = interpreterFrameMonitorEnd().address();
-    return monitorEnd.addOffsetTo(-1 * VM.getVM().getAddressSize());
-  }
-
-  public int getInterpreterFrameExpressionStackDirection() { return -1; }
-
-  // top of expression stack
-  public Address addressOfInterpreterFrameTOS() {
-    return getSP();
-  }
-
-  /** Expression stack from top down */
-  public Address addressOfInterpreterFrameTOSAt(int slot) {
-    return addressOfInterpreterFrameTOS().addOffsetTo(slot * VM.getVM().getAddressSize());
-  }
-
-  public Address getInterpreterFrameSenderSP() {
-    if (Assert.ASSERTS_ENABLED) {
-      Assert.that(isInterpretedFrame(), "interpreted frame expected");
-    }
-    return addressOfStackSlot(INTERPRETER_FRAME_SENDER_SP_OFFSET).getAddressAt(0);
-  }
-
-  // Monitors
-  public BasicObjectLock interpreterFrameMonitorBegin() {
-    return new BasicObjectLock(addressOfStackSlot(INTERPRETER_FRAME_MONITOR_BLOCK_BOTTOM_OFFSET));
-  }
-
-  public BasicObjectLock interpreterFrameMonitorEnd() {
-    Address result = addressOfStackSlot(INTERPRETER_FRAME_MONITOR_BLOCK_TOP_OFFSET).getAddressAt(0);
-    if (Assert.ASSERTS_ENABLED) {
-      // make sure the pointer points inside the frame
-      Assert.that(AddressOps.gt(getFP(), result), "result must <  than frame pointer");
-      Assert.that(AddressOps.lte(getSP(), result), "result must >= than stack pointer");
-    }
-    return new BasicObjectLock(result);
-  }
-
-  public int interpreterFrameMonitorSize() {
-    return BasicObjectLock.size();
-  }
-
-  // Method
-  public Address addressOfInterpreterFrameMethod() {
-    return addressOfStackSlot(INTERPRETER_FRAME_METHOD_OFFSET);
-  }
-
-  // Constant pool cache
-  public Address addressOfInterpreterFrameCPCache() {
-    return addressOfStackSlot(INTERPRETER_FRAME_CACHE_OFFSET);
-  }
-
-  // Entry frames
-  public JavaCallWrapper getEntryFrameCallWrapper() {
-    return new AMD64JavaCallWrapper(addressOfStackSlot(ENTRY_FRAME_CALL_WRAPPER_OFFSET).getAddressAt(0));
-  }
-
-  protected Address addressOfSavedOopResult() {
-    // offset is 2 for compiler2 and 3 for compiler1
-    return getSP().addOffsetTo((VM.getVM().isClientCompiler() ? 2 : 3) *
-                               VM.getVM().getAddressSize());
-  }
-
-  protected Address addressOfSavedReceiver() {
-    return getSP().addOffsetTo(-4 * VM.getVM().getAddressSize());
-  }
-
-  private void dumpStack() {
-    if (getFP() != null) {
-      for (Address addr = getSP().addOffsetTo(-5 * VM.getVM().getAddressSize());
-           AddressOps.lte(addr, getFP().addOffsetTo(5 * VM.getVM().getAddressSize()));
-           addr = addr.addOffsetTo(VM.getVM().getAddressSize())) {
-        System.out.println(addr + ": " + addr.getAddressAt(0));
-      }
-    } else {
-      for (Address addr = getSP().addOffsetTo(-5 * VM.getVM().getAddressSize());
-           AddressOps.lte(addr, getSP().addOffsetTo(20 * VM.getVM().getAddressSize()));
-           addr = addr.addOffsetTo(VM.getVM().getAddressSize())) {
-        System.out.println(addr + ": " + addr.getAddressAt(0));
-      }
-    }
-  }
-}
--- a/agent/src/share/classes/sun/jvm/hotspot/runtime/amd64/AMD64RegisterMap.java	Fri Sep 02 21:33:57 2011 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.runtime.amd64;
-
-import sun.jvm.hotspot.asm.amd64.*;
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.runtime.*;
-
-public class AMD64RegisterMap extends RegisterMap {
-
-  /** This is the only public constructor */
-  public AMD64RegisterMap(JavaThread thread, boolean updateMap) {
-    super(thread, updateMap);
-  }
-
-  protected AMD64RegisterMap(RegisterMap map) {
-    super(map);
-  }
-
-  public Object clone() {
-    AMD64RegisterMap retval = new AMD64RegisterMap(this);
-    return retval;
-  }
-
-  // no PD state to clear or copy:
-  protected void clearPD() {}
-  protected void initializePD() {}
-  protected void initializeFromPD(RegisterMap map) {}
-  protected Address getLocationPD(VMReg reg) { return null; }
-}
--- a/agent/src/share/classes/sun/jvm/hotspot/runtime/linux_amd64/LinuxAMD64JavaThreadPDAccess.java	Fri Sep 02 21:33:57 2011 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/linux_amd64/LinuxAMD64JavaThreadPDAccess.java	Wed Sep 07 11:52:00 2011 -0700
@@ -30,6 +30,7 @@
 import sun.jvm.hotspot.debugger.amd64.*;
 import sun.jvm.hotspot.runtime.*;
 import sun.jvm.hotspot.runtime.amd64.*;
+import sun.jvm.hotspot.runtime.x86.*;
 import sun.jvm.hotspot.types.*;
 import sun.jvm.hotspot.utilities.*;
 
@@ -80,11 +81,11 @@
     if (fp == null) {
       return null; // no information
     }
-    return new AMD64Frame(thread.getLastJavaSP(), fp);
+    return new X86Frame(thread.getLastJavaSP(), fp);
   }
 
   public    RegisterMap newRegisterMap(JavaThread thread, boolean updateMap) {
-    return new AMD64RegisterMap(thread, updateMap);
+    return new X86RegisterMap(thread, updateMap);
   }
 
   public    Frame getCurrentFrameGuess(JavaThread thread, Address addr) {
@@ -95,9 +96,9 @@
       return null;
     }
     if (guesser.getPC() == null) {
-      return new AMD64Frame(guesser.getSP(), guesser.getFP());
+      return new X86Frame(guesser.getSP(), guesser.getFP());
     } else {
-      return new AMD64Frame(guesser.getSP(), guesser.getFP(), guesser.getPC());
+      return new X86Frame(guesser.getSP(), guesser.getFP(), guesser.getPC());
     }
   }
 
--- a/agent/src/share/classes/sun/jvm/hotspot/runtime/solaris_amd64/SolarisAMD64JavaThreadPDAccess.java	Fri Sep 02 21:33:57 2011 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/solaris_amd64/SolarisAMD64JavaThreadPDAccess.java	Wed Sep 07 11:52:00 2011 -0700
@@ -30,6 +30,7 @@
 import sun.jvm.hotspot.debugger.amd64.*;
 import sun.jvm.hotspot.runtime.*;
 import sun.jvm.hotspot.runtime.amd64.*;
+import sun.jvm.hotspot.runtime.x86.*;
 import sun.jvm.hotspot.types.*;
 import sun.jvm.hotspot.utilities.*;
 
@@ -84,14 +85,14 @@
         }
         Address pc =  thread.getLastJavaPC();
         if ( pc != null ) {
-            return new AMD64Frame(thread.getLastJavaSP(), fp, pc);
+            return new X86Frame(thread.getLastJavaSP(), fp, pc);
         } else {
-            return new AMD64Frame(thread.getLastJavaSP(), fp);
+            return new X86Frame(thread.getLastJavaSP(), fp);
         }
     }
 
     public RegisterMap newRegisterMap(JavaThread thread, boolean updateMap) {
-        return new AMD64RegisterMap(thread, updateMap);
+        return new X86RegisterMap(thread, updateMap);
     }
 
     public Frame getCurrentFrameGuess(JavaThread thread, Address addr) {
@@ -102,9 +103,9 @@
             return null;
         }
         if (guesser.getPC() == null) {
-            return new AMD64Frame(guesser.getSP(), guesser.getFP());
+            return new X86Frame(guesser.getSP(), guesser.getFP());
         } else {
-            return new AMD64Frame(guesser.getSP(), guesser.getFP(), guesser.getPC());
+            return new X86Frame(guesser.getSP(), guesser.getFP(), guesser.getPC());
         }
     }
 
--- a/agent/src/share/classes/sun/jvm/hotspot/runtime/sparc/SPARCFrame.java	Fri Sep 02 21:33:57 2011 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/sparc/SPARCFrame.java	Wed Sep 07 11:52:00 2011 -0700
@@ -236,7 +236,7 @@
       CodeBlob cb = VM.getVM().getCodeCache().findBlob(pc);
       if (cb != null && cb.isJavaMethod()) {
         NMethod nm = (NMethod) cb;
-        if (pc.equals(nm.deoptBegin())) {
+        if (pc.equals(nm.deoptHandlerBegin())) {
           // adjust pc if frame is deoptimized.
           pc = this.getUnextendedSP().getAddressAt(nm.origPCOffset());
           deoptimized = true;
@@ -559,49 +559,46 @@
       }
     }
 
-    if (!VM.getVM().isCore()) {
-      // Note:  The version of this operation on any platform with callee-save
-      //        registers must update the register map (if not null).
-      //        In order to do this correctly, the various subtypes of
-      //        of frame (interpreted, compiled, glue, native),
-      //        must be distinguished.  There is no need on SPARC for
-      //        such distinctions, because all callee-save registers are
-      //        preserved for all frames via SPARC-specific mechanisms.
-      //
-      //        *** HOWEVER, *** if and when we make any floating-point
-      //        registers callee-saved, then we will have to copy over
-      //        the RegisterMap update logic from the Intel code.
+    // Note:  The version of this operation on any platform with callee-save
+    //        registers must update the register map (if not null).
+    //        In order to do this correctly, the various subtypes of
+    //        of frame (interpreted, compiled, glue, native),
+    //        must be distinguished.  There is no need on SPARC for
+    //        such distinctions, because all callee-save registers are
+    //        preserved for all frames via SPARC-specific mechanisms.
+    //
+    //        *** HOWEVER, *** if and when we make any floating-point
+    //        registers callee-saved, then we will have to copy over
+    //        the RegisterMap update logic from the Intel code.
 
+    if (isRicochetFrame()) return senderForRicochetFrame(map);
 
-      // The constructor of the sender must know whether this frame is interpreted so it can set the
-      // sender's _interpreter_sp_adjustment field.
-      if (VM.getVM().getInterpreter().contains(pc)) {
-        isInterpreted = true;
-        map.makeIntegerRegsUnsaved();
+    // The constructor of the sender must know whether this frame is interpreted so it can set the
+    // sender's _interpreter_sp_adjustment field.
+    if (VM.getVM().getInterpreter().contains(pc)) {
+      isInterpreted = true;
+      map.makeIntegerRegsUnsaved();
+      map.shiftWindow(sp, youngerSP);
+    } else {
+      // Find a CodeBlob containing this frame's pc or elide the lookup and use the
+      // supplied blob which is already known to be associated with this frame.
+      cb = VM.getVM().getCodeCache().findBlob(pc);
+      if (cb != null) {
+        // Update the location of all implicitly saved registers
+        // as the address of these registers in the register save
+        // area (for %o registers we use the address of the %i
+        // register in the next younger frame)
         map.shiftWindow(sp, youngerSP);
-      } else {
-        // Find a CodeBlob containing this frame's pc or elide the lookup and use the
-        // supplied blob which is already known to be associated with this frame.
-        cb = VM.getVM().getCodeCache().findBlob(pc);
-        if (cb != null) {
-
-          if (cb.callerMustGCArguments(map.getThread())) {
+        if (map.getUpdateMap()) {
+          if (cb.callerMustGCArguments()) {
             map.setIncludeArgumentOops(true);
           }
-
-          // Update the location of all implicitly saved registers
-          // as the address of these registers in the register save
-          // area (for %o registers we use the address of the %i
-          // register in the next younger frame)
-          map.shiftWindow(sp, youngerSP);
-          if (map.getUpdateMap()) {
-            if (cb.getOopMaps() != null) {
-              OopMapSet.updateRegisterMap(this, cb, map, VM.getVM().isDebugging());
-            }
+          if (cb.getOopMaps() != null) {
+            OopMapSet.updateRegisterMap(this, cb, map, VM.getVM().isDebugging());
           }
         }
       }
-    } // #ifndef CORE
+    }
 
     return new SPARCFrame(biasSP(sp), biasSP(youngerSP), isInterpreted);
   }
@@ -948,6 +945,20 @@
   }
 
 
+  private Frame senderForRicochetFrame(SPARCRegisterMap map) {
+    if (DEBUG) {
+      System.out.println("senderForRicochetFrame");
+    }
+    //RicochetFrame* f = RicochetFrame::from_frame(fr);
+    // Cf. is_interpreted_frame path of frame::sender
+    Address youngerSP = getSP();
+    Address sp        = getSenderSP();
+    map.makeIntegerRegsUnsaved();
+    map.shiftWindow(sp, youngerSP);
+    boolean thisFrameAdjustedStack = true;  // I5_savedSP is live in this RF
+    return new SPARCFrame(sp, youngerSP, thisFrameAdjustedStack);
+  }
+
   private Frame senderForEntryFrame(RegisterMap regMap) {
     SPARCRegisterMap map = (SPARCRegisterMap) regMap;
 
@@ -965,10 +976,8 @@
     Address lastJavaPC = jcw.getLastJavaPC();
     map.clear();
 
-    if (!VM.getVM().isCore()) {
-      map.makeIntegerRegsUnsaved();
-      map.shiftWindow(lastJavaSP, null);
-    }
+    map.makeIntegerRegsUnsaved();
+    map.shiftWindow(lastJavaSP, null);
 
     if (Assert.ASSERTS_ENABLED) {
       Assert.that(map.getIncludeArgumentOops(), "should be set by clear");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/sparc/SPARCRicochetFrame.java	Wed Sep 07 11:52:00 2011 -0700
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package sun.jvm.hotspot.runtime.sparc;
+
+import java.util.*;
+import sun.jvm.hotspot.asm.sparc.SPARCRegister;
+import sun.jvm.hotspot.asm.sparc.SPARCRegisters;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.types.*;
+
+public class SPARCRicochetFrame {
+  static {
+    VM.registerVMInitializedObserver(new Observer() {
+        public void update(Observable o, Object data) {
+          initialize(VM.getVM().getTypeDataBase());
+        }
+      });
+  }
+
+  private SPARCFrame frame;
+
+  private static void initialize(TypeDataBase db) {
+    // Type type = db.lookupType("MethodHandles::RicochetFrame");
+
+  }
+
+  static SPARCRicochetFrame fromFrame(SPARCFrame f) {
+    return new SPARCRicochetFrame(f);
+  }
+
+  private SPARCRicochetFrame(SPARCFrame f) {
+    frame = f;
+  }
+
+  private Address registerValue(SPARCRegister reg) {
+    return frame.getSP().addOffsetTo(reg.spOffsetInSavedWindow()).getAddressAt(0);
+  }
+
+  public Address savedArgsBase() {
+    return registerValue(SPARCRegisters.L4);
+  }
+  public Address exactSenderSP() {
+    return registerValue(SPARCRegisters.I5);
+  }
+  public Address senderLink() {
+    return frame.getSenderSP();
+  }
+  public Address senderPC() {
+    return frame.getSenderPC();
+  }
+  public Address extendedSenderSP() {
+    return savedArgsBase();
+  }
+}
--- a/agent/src/share/classes/sun/jvm/hotspot/runtime/win32_amd64/Win32AMD64JavaThreadPDAccess.java	Fri Sep 02 21:33:57 2011 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/win32_amd64/Win32AMD64JavaThreadPDAccess.java	Wed Sep 07 11:52:00 2011 -0700
@@ -31,6 +31,7 @@
 import sun.jvm.hotspot.debugger.amd64.*;
 import sun.jvm.hotspot.runtime.*;
 import sun.jvm.hotspot.runtime.amd64.*;
+import sun.jvm.hotspot.runtime.x86.*;
 import sun.jvm.hotspot.types.*;
 import sun.jvm.hotspot.utilities.*;
 
@@ -86,14 +87,14 @@
     }
     Address pc =  thread.getLastJavaPC();
     if ( pc != null ) {
-      return new AMD64Frame(thread.getLastJavaSP(), fp, pc);
+      return new X86Frame(thread.getLastJavaSP(), fp, pc);
     } else {
-      return new AMD64Frame(thread.getLastJavaSP(), fp);
+      return new X86Frame(thread.getLastJavaSP(), fp);
     }
   }
 
   public RegisterMap newRegisterMap(JavaThread thread, boolean updateMap) {
-    return new AMD64RegisterMap(thread, updateMap);
+    return new X86RegisterMap(thread, updateMap);
   }
 
   public Frame getCurrentFrameGuess(JavaThread thread, Address addr) {
@@ -104,9 +105,9 @@
       return null;
     }
     if (guesser.getPC() == null) {
-      return new AMD64Frame(guesser.getSP(), guesser.getFP());
+      return new X86Frame(guesser.getSP(), guesser.getFP());
     } else {
-      return new AMD64Frame(guesser.getSP(), guesser.getFP(), guesser.getPC());
+      return new X86Frame(guesser.getSP(), guesser.getFP(), guesser.getPC());
     }
   }
 
--- a/agent/src/share/classes/sun/jvm/hotspot/runtime/x86/X86Frame.java	Fri Sep 02 21:33:57 2011 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/x86/X86Frame.java	Wed Sep 07 11:52:00 2011 -0700
@@ -25,7 +25,6 @@
 package sun.jvm.hotspot.runtime.x86;
 
 import java.util.*;
-import sun.jvm.hotspot.asm.x86.*;
 import sun.jvm.hotspot.code.*;
 import sun.jvm.hotspot.compiler.*;
 import sun.jvm.hotspot.debugger.*;
@@ -62,11 +61,13 @@
   private static       int INTERPRETER_FRAME_MONITOR_BLOCK_BOTTOM_OFFSET;
 
   // Entry frames
-  private static final int ENTRY_FRAME_CALL_WRAPPER_OFFSET   =  2;
+  private static       int ENTRY_FRAME_CALL_WRAPPER_OFFSET;
 
   // Native frames
   private static final int NATIVE_FRAME_INITIAL_PARAM_OFFSET =  2;
 
+  private static VMReg rbp;
+
   static {
     VM.registerVMInitializedObserver(new Observer() {
         public void update(Observable o, Object data) {
@@ -76,19 +77,23 @@
   }
 
   private static synchronized void initialize(TypeDataBase db) {
-    if (VM.getVM().isCore()) {
-      INTERPRETER_FRAME_CACHE_OFFSET = INTERPRETER_FRAME_METHOD_OFFSET - 1;
-    } else {
-      INTERPRETER_FRAME_MDX_OFFSET   = INTERPRETER_FRAME_METHOD_OFFSET - 1;
-      INTERPRETER_FRAME_CACHE_OFFSET = INTERPRETER_FRAME_MDX_OFFSET - 1;
-    }
+    INTERPRETER_FRAME_MDX_OFFSET                  = INTERPRETER_FRAME_METHOD_OFFSET - 1;
+    INTERPRETER_FRAME_CACHE_OFFSET                = INTERPRETER_FRAME_MDX_OFFSET - 1;
     INTERPRETER_FRAME_LOCALS_OFFSET               = INTERPRETER_FRAME_CACHE_OFFSET - 1;
     INTERPRETER_FRAME_BCX_OFFSET                  = INTERPRETER_FRAME_LOCALS_OFFSET - 1;
     INTERPRETER_FRAME_INITIAL_SP_OFFSET           = INTERPRETER_FRAME_BCX_OFFSET - 1;
     INTERPRETER_FRAME_MONITOR_BLOCK_TOP_OFFSET    = INTERPRETER_FRAME_INITIAL_SP_OFFSET;
     INTERPRETER_FRAME_MONITOR_BLOCK_BOTTOM_OFFSET = INTERPRETER_FRAME_INITIAL_SP_OFFSET;
+
+    ENTRY_FRAME_CALL_WRAPPER_OFFSET = db.lookupIntConstant("frame::entry_frame_call_wrapper_offset");
+    if (VM.getVM().getAddressSize() == 4) {
+      rbp = new VMReg(5);
+    } else {
+      rbp = new VMReg(5 << 1);
+    }
   }
 
+
   // an additional field beyond sp and pc:
   Address raw_fp; // frame pointer
   private Address raw_unextendedSP;
@@ -102,7 +107,7 @@
       CodeBlob cb = VM.getVM().getCodeCache().findBlob(pc);
       if (cb != null && cb.isJavaMethod()) {
         NMethod nm = (NMethod) cb;
-        if (pc.equals(nm.deoptBegin())) {
+        if (pc.equals(nm.deoptHandlerBegin())) {
           if (Assert.ASSERTS_ENABLED) {
             Assert.that(this.getUnextendedSP() != null, "null SP in Java frame");
           }
@@ -119,6 +124,7 @@
     this.raw_unextendedSP = raw_sp;
     this.raw_fp = raw_fp;
     this.pc = pc;
+    adjustUnextendedSP();
 
     // Frame must be fully constructed before this call
     adjustForDeopt();
@@ -134,6 +140,7 @@
     this.raw_unextendedSP = raw_sp;
     this.raw_fp = raw_fp;
     this.pc = raw_sp.getAddressAt(-1 * VM.getVM().getAddressSize());
+    adjustUnextendedSP();
 
     // Frame must be fully constructed before this call
     adjustForDeopt();
@@ -144,24 +151,18 @@
     }
   }
 
-  // This constructor should really take the unextended SP as an arg
-  // but then the constructor is ambiguous with constructor that takes
-  // a PC so take an int and convert it.
-  public X86Frame(Address raw_sp, Address raw_fp, long extension) {
+  public X86Frame(Address raw_sp, Address raw_unextendedSp, Address raw_fp, Address pc) {
     this.raw_sp = raw_sp;
-    if (raw_sp == null) {
-      this.raw_unextendedSP = null;
-    } else {
-      this.raw_unextendedSP = raw_sp.addOffsetTo(extension);
-    }
+    this.raw_unextendedSP = raw_unextendedSp;
     this.raw_fp = raw_fp;
-    this.pc = raw_sp.getAddressAt(-1 * VM.getVM().getAddressSize());
+    this.pc = pc;
+    adjustUnextendedSP();
 
     // Frame must be fully constructed before this call
     adjustForDeopt();
 
     if (DEBUG) {
-      System.out.println("X86Frame(sp, fp): " + this);
+      System.out.println("X86Frame(sp, unextendedSP, fp, pc): " + this);
       dumpStack();
     }
 
@@ -172,7 +173,6 @@
     frame.raw_sp = raw_sp;
     frame.raw_unextendedSP = raw_unextendedSP;
     frame.raw_fp = raw_fp;
-    frame.raw_fp = raw_fp;
     frame.pc = pc;
     frame.deoptimized = deoptimized;
     return frame;
@@ -269,19 +269,18 @@
 
     if (isEntryFrame())       return senderForEntryFrame(map);
     if (isInterpretedFrame()) return senderForInterpreterFrame(map);
+    if (isRicochetFrame())    return senderForRicochetFrame(map);
 
-    if (!VM.getVM().isCore()) {
-      if(cb == null) {
-        cb = VM.getVM().getCodeCache().findBlob(getPC());
-      } else {
-        if (Assert.ASSERTS_ENABLED) {
-          Assert.that(cb.equals(VM.getVM().getCodeCache().findBlob(getPC())), "Must be the same");
-        }
+    if(cb == null) {
+      cb = VM.getVM().getCodeCache().findBlob(getPC());
+    } else {
+      if (Assert.ASSERTS_ENABLED) {
+        Assert.that(cb.equals(VM.getVM().getCodeCache().findBlob(getPC())), "Must be the same");
       }
+    }
 
-      if (cb != null) {
-         return senderForCompiledFrame(map, cb);
-      }
+    if (cb != null) {
+      return senderForCompiledFrame(map, cb);
     }
 
     // Must be native-compiled frame, i.e. the marshaling code for native
@@ -289,7 +288,20 @@
     return new X86Frame(getSenderSP(), getLink(), getSenderPC());
   }
 
+  private Frame senderForRicochetFrame(X86RegisterMap map) {
+    if (DEBUG) {
+      System.out.println("senderForRicochetFrame");
+    }
+    X86RicochetFrame f = X86RicochetFrame.fromFrame(this);
+    if (map.getUpdateMap())
+      updateMapWithSavedLink(map, f.senderLinkAddress());
+    return new X86Frame(f.extendedSenderSP(), f.exactSenderSP(), f.senderLink(), f.senderPC());
+  }
+
   private Frame senderForEntryFrame(X86RegisterMap map) {
+    if (DEBUG) {
+      System.out.println("senderForEntryFrame");
+    }
     if (Assert.ASSERTS_ENABLED) {
       Assert.that(map != null, "map must be set");
     }
@@ -313,7 +325,37 @@
     return fr;
   }
 
+  //------------------------------------------------------------------------------
+  // frame::adjust_unextended_sp
+  private void adjustUnextendedSP() {
+    // If we are returning to a compiled MethodHandle call site, the
+    // saved_fp will in fact be a saved value of the unextended SP.  The
+    // simplest way to tell whether we are returning to such a call site
+    // is as follows:
+
+    CodeBlob cb = cb();
+    NMethod senderNm = (cb == null) ? null : cb.asNMethodOrNull();
+    if (senderNm != null) {
+      // If the sender PC is a deoptimization point, get the original
+      // PC.  For MethodHandle call site the unextended_sp is stored in
+      // saved_fp.
+      if (senderNm.isDeoptMhEntry(getPC())) {
+        // DEBUG_ONLY(verifyDeoptMhOriginalPc(senderNm, getFP()));
+        raw_unextendedSP = getFP();
+      }
+      else if (senderNm.isDeoptEntry(getPC())) {
+        // DEBUG_ONLY(verifyDeoptOriginalPc(senderNm, raw_unextendedSp));
+      }
+      else if (senderNm.isMethodHandleReturn(getPC())) {
+        raw_unextendedSP = getFP();
+      }
+    }
+  }
+
   private Frame senderForInterpreterFrame(X86RegisterMap map) {
+    if (DEBUG) {
+      System.out.println("senderForInterpreterFrame");
+    }
     Address unextendedSP = addressOfStackSlot(INTERPRETER_FRAME_SENDER_SP_OFFSET).getAddressAt(0);
     Address sp = addressOfStackSlot(SENDER_SP_OFFSET);
     // We do not need to update the callee-save register mapping because above
@@ -323,10 +365,21 @@
     // However c2 no longer uses callee save register for java calls so there
     // are no callee register to find.
 
-    return new X86Frame(sp, getLink(), unextendedSP.minus(sp));
+    if (map.getUpdateMap())
+      updateMapWithSavedLink(map, addressOfStackSlot(LINK_OFFSET));
+
+    return new X86Frame(sp, unextendedSP, getLink(), getSenderPC());
+  }
+
+  private void updateMapWithSavedLink(RegisterMap map, Address savedFPAddr) {
+    map.setLocation(rbp, savedFPAddr);
   }
 
   private Frame senderForCompiledFrame(X86RegisterMap map, CodeBlob cb) {
+    if (DEBUG) {
+      System.out.println("senderForCompiledFrame");
+    }
+
     //
     // NOTE: some of this code is (unfortunately) duplicated in X86CurrentFrameGuess
     //
@@ -336,41 +389,35 @@
     }
 
     // frame owned by optimizing compiler
-    Address        sender_sp = null;
-
-    if (VM.getVM().isClientCompiler()) {
-      sender_sp        = addressOfStackSlot(SENDER_SP_OFFSET);
-    } else {
-      if (Assert.ASSERTS_ENABLED) {
-        Assert.that(cb.getFrameSize() >= 0, "Compiled by Compiler1: do not use");
-      }
-      sender_sp = getUnextendedSP().addOffsetTo(cb.getFrameSize());
+    if (Assert.ASSERTS_ENABLED) {
+        Assert.that(cb.getFrameSize() >= 0, "must have non-zero frame size");
     }
+    Address senderSP = getUnextendedSP().addOffsetTo(cb.getFrameSize());
 
     // On Intel the return_address is always the word on the stack
-    Address sender_pc = sender_sp.getAddressAt(-1 * VM.getVM().getAddressSize());
+    Address senderPC = senderSP.getAddressAt(-1 * VM.getVM().getAddressSize());
+
+    // This is the saved value of EBP which may or may not really be an FP.
+    // It is only an FP if the sender is an interpreter frame (or C1?).
+    Address savedFPAddr = senderSP.addOffsetTo(- SENDER_SP_OFFSET * VM.getVM().getAddressSize());
 
-    if (map.getUpdateMap() && cb.getOopMaps() != null) {
-      OopMapSet.updateRegisterMap(this, cb, map, true);
+    if (map.getUpdateMap()) {
+      // Tell GC to use argument oopmaps for some runtime stubs that need it.
+      // For C1, the runtime stub might not have oop maps, so set this flag
+      // outside of update_register_map.
+      map.setIncludeArgumentOops(cb.callerMustGCArguments());
+
+      if (cb.getOopMaps() != null) {
+        OopMapSet.updateRegisterMap(this, cb, map, true);
+      }
+
+      // Since the prolog does the save and restore of EBP there is no oopmap
+      // for it so we must fill in its location as if there was an oopmap entry
+      // since if our caller was compiled code there could be live jvm state in it.
+      updateMapWithSavedLink(map, savedFPAddr);
     }
 
-    if (VM.getVM().isClientCompiler()) {
-      // Move this here for C1 and collecting oops in arguments (According to Rene)
-      map.setIncludeArgumentOops(cb.callerMustGCArguments(map.getThread()));
-    }
-
-    Address saved_fp = null;
-    if (VM.getVM().isClientCompiler()) {
-      saved_fp = getFP().getAddressAt(0);
-    } else if (VM.getVM().isServerCompiler() &&
-               (VM.getVM().getInterpreter().contains(sender_pc) ||
-               VM.getVM().getStubRoutines().returnsToCallStub(sender_pc))) {
-      // C2 prologue saves EBP in the usual place.
-      // however only use it if the sender had link infomration in it.
-      saved_fp = sender_sp.getAddressAt(-2 * VM.getVM().getAddressSize());
-    }
-
-    return new X86Frame(sender_sp, saved_fp, sender_pc);
+    return new X86Frame(senderSP, savedFPAddr.getAddressAt(0), senderPC);
   }
 
   protected boolean hasSenderPD() {
@@ -403,14 +450,6 @@
 
   public Address getSenderSP()     { return addressOfStackSlot(SENDER_SP_OFFSET); }
 
-  public Address compiledArgumentToLocationPD(VMReg reg, RegisterMap regMap, int argSize) {
-    if (VM.getVM().isCore() || VM.getVM().isClientCompiler()) {
-      throw new RuntimeException("Should not reach here");
-    }
-
-    return oopMapRegToLocation(reg, regMap);
-  }
-
   public Address addressOfInterpreterFrameLocals() {
     return addressOfStackSlot(INTERPRETER_FRAME_LOCALS_OFFSET);
   }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/x86/X86RicochetFrame.java	Wed Sep 07 11:52:00 2011 -0700
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package sun.jvm.hotspot.runtime.x86;
+
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.types.*;
+
+public class X86RicochetFrame extends VMObject {
+  static {
+    VM.registerVMInitializedObserver(new Observer() {
+        public void update(Observable o, Object data) {
+          initialize(VM.getVM().getTypeDataBase());
+        }
+      });
+  }
+
+  private static void initialize(TypeDataBase db) {
+    Type type = db.lookupType("MethodHandles::RicochetFrame");
+
+    senderLinkField    = type.getAddressField("_sender_link");
+    savedArgsBaseField = type.getAddressField("_saved_args_base");
+    exactSenderSPField = type.getAddressField("_exact_sender_sp");
+    senderPCField      = type.getAddressField("_sender_pc");
+  }
+
+  private static AddressField senderLinkField;
+  private static AddressField savedArgsBaseField;
+  private static AddressField exactSenderSPField;
+  private static AddressField senderPCField;
+
+  static X86RicochetFrame fromFrame(X86Frame f) {
+    return new X86RicochetFrame(f.getFP().addOffsetTo(- senderLinkField.getOffset()));
+  }
+
+  private X86RicochetFrame(Address addr) {
+    super(addr);
+  }
+
+  public Address senderLink() {
+    return senderLinkField.getValue(addr);
+  }
+  public Address senderLinkAddress() {
+    return addr.addOffsetTo(senderLinkField.getOffset());
+  }
+  public Address savedArgsBase() {
+    return savedArgsBaseField.getValue(addr);
+  }
+  public Address extendedSenderSP() {
+    return savedArgsBase();
+  }
+  public Address exactSenderSP() {
+    return exactSenderSPField.getValue(addr);
+  }
+  public Address senderPC() {
+    return senderPCField.getValue(addr);
+  }
+}
--- a/make/linux/makefiles/mapfile-vers-debug	Fri Sep 02 21:33:57 2011 -0700
+++ b/make/linux/makefiles/mapfile-vers-debug	Wed Sep 07 11:52:00 2011 -0700
@@ -244,24 +244,6 @@
                 JVM_Yield;
                 JVM_handle_linux_signal;
 
-                # Old reflection routines
-                # These do not need to be present in the product build in JDK 1.4
-                # but their code has not been removed yet because there will not
-                # be a substantial code savings until JVM_InvokeMethod and
-                # JVM_NewInstanceFromConstructor can also be removed; see
-                # reflectionCompat.hpp.
-                JVM_GetClassConstructor;
-                JVM_GetClassConstructors;
-                JVM_GetClassField;
-                JVM_GetClassFields;
-                JVM_GetClassMethod;
-                JVM_GetClassMethods;
-                JVM_GetField;
-                JVM_GetPrimitiveField;
-                JVM_NewInstance;
-                JVM_SetField;
-                JVM_SetPrimitiveField;
-
                 # debug JVM
                 JVM_AccessVMBooleanFlag;
                 JVM_AccessVMIntFlag;
--- a/make/linux/makefiles/mapfile-vers-product	Fri Sep 02 21:33:57 2011 -0700
+++ b/make/linux/makefiles/mapfile-vers-product	Wed Sep 07 11:52:00 2011 -0700
@@ -244,24 +244,6 @@
                 JVM_Yield;
                 JVM_handle_linux_signal;
 
-                # Old reflection routines
-                # These do not need to be present in the product build in JDK 1.4
-                # but their code has not been removed yet because there will not
-                # be a substantial code savings until JVM_InvokeMethod and
-                # JVM_NewInstanceFromConstructor can also be removed; see
-                # reflectionCompat.hpp.
-                JVM_GetClassConstructor;
-                JVM_GetClassConstructors;
-                JVM_GetClassField;
-                JVM_GetClassFields;
-                JVM_GetClassMethod;
-                JVM_GetClassMethods;
-                JVM_GetField;
-                JVM_GetPrimitiveField;
-                JVM_NewInstance;
-                JVM_SetField;
-                JVM_SetPrimitiveField;
-
                 # miscellaneous functions
                 jio_fprintf;
                 jio_printf;
--- a/make/solaris/makefiles/debug.make	Fri Sep 02 21:33:57 2011 -0700
+++ b/make/solaris/makefiles/debug.make	Wed Sep 07 11:52:00 2011 -0700
@@ -41,8 +41,7 @@
 
 # Linker mapfiles
 MAPFILE = $(GAMMADIR)/make/solaris/makefiles/mapfile-vers \
-          $(GAMMADIR)/make/solaris/makefiles/mapfile-vers-debug \
-          $(GAMMADIR)/make/solaris/makefiles/mapfile-vers-nonproduct
+          $(GAMMADIR)/make/solaris/makefiles/mapfile-vers-debug
 
 # This mapfile is only needed when compiling with dtrace support, 
 # and mustn't be otherwise.
--- a/make/solaris/makefiles/fastdebug.make	Fri Sep 02 21:33:57 2011 -0700
+++ b/make/solaris/makefiles/fastdebug.make	Wed Sep 07 11:52:00 2011 -0700
@@ -107,8 +107,7 @@
 
 # Linker mapfiles
 MAPFILE = $(GAMMADIR)/make/solaris/makefiles/mapfile-vers \
-	  $(GAMMADIR)/make/solaris/makefiles/mapfile-vers-debug \
-	  $(GAMMADIR)/make/solaris/makefiles/mapfile-vers-nonproduct
+	  $(GAMMADIR)/make/solaris/makefiles/mapfile-vers-debug
 
 # This mapfile is only needed when compiling with dtrace support, 
 # and mustn't be otherwise.
--- a/make/solaris/makefiles/jvmg.make	Fri Sep 02 21:33:57 2011 -0700
+++ b/make/solaris/makefiles/jvmg.make	Wed Sep 07 11:52:00 2011 -0700
@@ -44,8 +44,7 @@
 
 # Linker mapfiles
 MAPFILE = $(GAMMADIR)/make/solaris/makefiles/mapfile-vers \
-          $(GAMMADIR)/make/solaris/makefiles/mapfile-vers-debug \
-          $(GAMMADIR)/make/solaris/makefiles/mapfile-vers-nonproduct
+          $(GAMMADIR)/make/solaris/makefiles/mapfile-vers-debug
 
 # This mapfile is only needed when compiling with dtrace support,
 # and mustn't be otherwise.
--- a/make/solaris/makefiles/mapfile-vers-nonproduct	Fri Sep 02 21:33:57 2011 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-#
-
-#
-# Copyright (c) 2001, 2008, 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.
-#  
-#
-
-# Define public interface.
-
-SUNWprivate_1.1 {
-        global:
-		# Old reflection routines
-		# These do not need to be present in the product build in JDK 1.4
-		# but their code has not been removed yet because there will not
-		# be a substantial code savings until JVM_InvokeMethod and
-		# JVM_NewInstanceFromConstructor can also be removed; see
-		# reflectionCompat.hpp.
-		JVM_GetClassConstructor;
-		JVM_GetClassConstructors;
-		JVM_GetClassField;
-		JVM_GetClassFields;
-		JVM_GetClassMethod;
-		JVM_GetClassMethods;
-		JVM_GetField;
-		JVM_GetPrimitiveField;
-		JVM_NewInstance;
-		JVM_SetField;
-		JVM_SetPrimitiveField;
-};
--- a/make/solaris/makefiles/optimized.make	Fri Sep 02 21:33:57 2011 -0700
+++ b/make/solaris/makefiles/optimized.make	Wed Sep 07 11:52:00 2011 -0700
@@ -48,9 +48,7 @@
 CFLAGS$(HOTSPARC_GENERIC) += $(OPT_CFLAGS/BYFILE)
 
 # Linker mapfiles
-# NOTE: inclusion of nonproduct mapfile not necessary; read it for details
-MAPFILE = $(GAMMADIR)/make/solaris/makefiles/mapfile-vers \
-          $(GAMMADIR)/make/solaris/makefiles/mapfile-vers-nonproduct
+MAPFILE = $(GAMMADIR)/make/solaris/makefiles/mapfile-vers
 
 # This mapfile is only needed when compiling with dtrace support, 
 # and mustn't be otherwise.
--- a/make/solaris/makefiles/product.make	Fri Sep 02 21:33:57 2011 -0700
+++ b/make/solaris/makefiles/product.make	Wed Sep 07 11:52:00 2011 -0700
@@ -58,13 +58,9 @@
 # to inhibit the effect of the previous line on CFLAGS.
 
 # Linker mapfiles
-# NOTE: inclusion of nonproduct mapfile not necessary; read it for details
-ifdef USE_GCC
 MAPFILE = $(GAMMADIR)/make/solaris/makefiles/mapfile-vers
-else
-MAPFILE = $(GAMMADIR)/make/solaris/makefiles/mapfile-vers \
-          $(GAMMADIR)/make/solaris/makefiles/mapfile-vers-nonproduct
 
+ifndef USE_GCC
 # This mapfile is only needed when compiling with dtrace support, 
 # and mustn't be otherwise.
 MAPFILE_DTRACE = $(GAMMADIR)/make/solaris/makefiles/mapfile-vers-$(TYPE)
--- a/src/cpu/sparc/vm/assembler_sparc.cpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/cpu/sparc/vm/assembler_sparc.cpp	Wed Sep 07 11:52:00 2011 -0700
@@ -1794,7 +1794,8 @@
   mov(reg,O0); // Move arg into O0; arg might be in O7 which is about to be crushed
   stx(O7,SP,frame::register_save_words*wordSize+STACK_BIAS+7*8);
 
-  set((intptr_t)real_msg, O1);
+  // Size of set() should stay the same
+  patchable_set((intptr_t)real_msg, O1);
   // Load address to call to into O7
   load_ptr_contents(a, O7);
   // Register call to verify_oop_subroutine
@@ -1831,7 +1832,8 @@
   ld_ptr(addr.base(), addr.disp() + 8*8, O0); // Load arg into O0; arg might be in O7 which is about to be crushed
   stx(O7,SP,frame::register_save_words*wordSize+STACK_BIAS+7*8);
 
-  set((intptr_t)real_msg, O1);
+  // Size of set() should stay the same
+  patchable_set((intptr_t)real_msg, O1);
   // Load address to call to into O7
   load_ptr_contents(a, O7);
   // Register call to verify_oop_subroutine
@@ -1976,7 +1978,8 @@
     save_frame(::round_to(sizeof(RegistersForDebugging) / BytesPerWord, 2));
 
     // stop_subroutine expects message pointer in I1.
-    set((intptr_t)msg, O1);
+    // Size of set() should stay the same
+    patchable_set((intptr_t)msg, O1);
 
     // factor long stop-sequence into subroutine to save space
     assert(StubRoutines::Sparc::stop_subroutine_entry_address(), "hasn't been generated yet");
@@ -1998,7 +2001,8 @@
   save_frame(::round_to(sizeof(RegistersForDebugging) / BytesPerWord, 2));
   RegistersForDebugging::save_registers(this);
   mov(O0, L0);
-  set((intptr_t)msg, O0);
+  // Size of set() should stay the same
+  patchable_set((intptr_t)msg, O0);
   call( CAST_FROM_FN_PTR(address, warning) );
   delayed()->nop();
 //  ret();
@@ -4901,3 +4905,65 @@
   // Caller should set it:
   // add(G0, 1, result); // equals
 }
+
+// Use BIS for zeroing (count is in bytes).
+void MacroAssembler::bis_zeroing(Register to, Register count, Register temp, Label& Ldone) {
+  assert(UseBlockZeroing && VM_Version::has_block_zeroing(), "only works with BIS zeroing");
+  Register end = count;
+  int cache_line_size = VM_Version::prefetch_data_size();
+  // Minimum count when BIS zeroing can be used since
+  // it needs membar which is expensive.
+  int block_zero_size  = MAX2(cache_line_size*3, (int)BlockZeroingLowLimit);
+
+  Label small_loop;
+  // Check if count is negative (dead code) or zero.
+  // Note, count uses 64bit in 64 bit VM.
+  cmp_and_brx_short(count, 0, Assembler::lessEqual, Assembler::pn, Ldone);
+
+  // Use BIS zeroing only for big arrays since it requires membar.
+  if (Assembler::is_simm13(block_zero_size)) { // < 4096
+    cmp(count, block_zero_size);
+  } else {
+    set(block_zero_size, temp);
+    cmp(count, temp);
+  }
+  br(Assembler::lessUnsigned, false, Assembler::pt, small_loop);
+  delayed()->add(to, count, end);
+
+  // Note: size is >= three (32 bytes) cache lines.
+
+  // Clean the beginning of space up to next cache line.
+  for (int offs = 0; offs < cache_line_size; offs += 8) {
+    stx(G0, to, offs);
+  }
+
+  // align to next cache line
+  add(to, cache_line_size, to);
+  and3(to, -cache_line_size, to);
+
+  // Note: size left >= two (32 bytes) cache lines.
+
+  // BIS should not be used to zero tail (64 bytes)
+  // to avoid zeroing a header of the following object.
+  sub(end, (cache_line_size*2)-8, end);
+
+  Label bis_loop;
+  bind(bis_loop);
+  stxa(G0, to, G0, Assembler::ASI_ST_BLKINIT_PRIMARY);
+  add(to, cache_line_size, to);
+  cmp_and_brx_short(to, end, Assembler::lessUnsigned, Assembler::pt, bis_loop);
+
+  // BIS needs membar.
+  membar(Assembler::StoreLoad);
+
+  add(end, (cache_line_size*2)-8, end); // restore end
+  cmp_and_brx_short(to, end, Assembler::greaterEqualUnsigned, Assembler::pn, Ldone);
+
+  // Clean the tail.
+  bind(small_loop);
+  stx(G0, to, 0);
+  add(to, 8, to);
+  cmp_and_brx_short(to, end, Assembler::lessUnsigned, Assembler::pt, small_loop);
+  nop(); // Separate short branches
+}
+
--- a/src/cpu/sparc/vm/assembler_sparc.hpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/cpu/sparc/vm/assembler_sparc.hpp	Wed Sep 07 11:52:00 2011 -0700
@@ -885,8 +885,9 @@
   }
 
   enum ASIs { // page 72, v9
-    ASI_PRIMARY        = 0x80,
-    ASI_PRIMARY_LITTLE = 0x88,
+    ASI_PRIMARY            = 0x80,
+    ASI_PRIMARY_NOFAULT    = 0x82,
+    ASI_PRIMARY_LITTLE     = 0x88,
     // Block initializing store
     ASI_ST_BLKINIT_PRIMARY = 0xE2,
     // Most-Recently-Used (MRU) BIS variant
@@ -1786,9 +1787,12 @@
                                                                            rs1(s) |
                                                                            op3(wrreg_op3) |
                                                                            u_field(2, 29, 25) |
-                                                                           u_field(1, 13, 13) |
+                                                                           immed(true) |
                                                                            simm(simm13a, 13)); }
-  inline void wrasi(  Register d) { v9_only(); emit_long( op(arith_op) | rs1(d) | op3(wrreg_op3) | u_field(3, 29, 25)); }
+  inline void wrasi(Register d) { v9_only(); emit_long( op(arith_op) | rs1(d) | op3(wrreg_op3) | u_field(3, 29, 25)); }
+  // wrasi(d, imm) stores (d xor imm) to asi
+  inline void wrasi(Register d, int simm13a) { v9_only(); emit_long( op(arith_op) | rs1(d) | op3(wrreg_op3) |
+                                               u_field(3, 29, 25) | immed(true) | simm(simm13a, 13)); }
   inline void wrfprs( Register d) { v9_only(); emit_long( op(arith_op) | rs1(d) | op3(wrreg_op3) | u_field(6, 29, 25)); }
 
 
@@ -2625,6 +2629,8 @@
   void char_arrays_equals(Register ary1, Register ary2,
                           Register limit, Register result,
                           Register chr1, Register chr2, Label& Ldone);
+  // Use BIS for zeroing
+  void bis_zeroing(Register to, Register count, Register temp, Label& Ldone);
 
 #undef VIRTUAL
 
--- a/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp	Wed Sep 07 11:52:00 2011 -0700
@@ -142,11 +142,6 @@
 }
 
 
-LIR_Opr LIR_Assembler::incomingReceiverOpr() {
-  return FrameMap::I0_oop_opr;
-}
-
-
 LIR_Opr LIR_Assembler::osrBufferPointer() {
   return FrameMap::I0_opr;
 }
--- a/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp	Wed Sep 07 11:52:00 2011 -0700
@@ -782,13 +782,6 @@
       }
       break;
 
-    case jvmti_exception_throw_id:
-      { // Oexception : exception
-        __ set_info("jvmti_exception_throw", dont_gc_arguments);
-        oop_maps = generate_stub_call(sasm, noreg, CAST_FROM_FN_PTR(address, Runtime1::post_jvmti_exception_throw), I0);
-      }
-      break;
-
     case dtrace_object_alloc_id:
       { // O0: object
         __ set_info("dtrace_object_alloc", dont_gc_arguments);
--- a/src/cpu/sparc/vm/copy_sparc.hpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/cpu/sparc/vm/copy_sparc.hpp	Wed Sep 07 11:52:00 2011 -0700
@@ -156,9 +156,16 @@
 #endif // _LP64
 }
 
+typedef void (*_zero_Fn)(HeapWord* to, size_t count);
+
 static void pd_fill_to_aligned_words(HeapWord* tohw, size_t count, juint value) {
   assert(MinObjAlignmentInBytes >= BytesPerLong, "need alternate implementation");
 
+  if (value == 0 && UseBlockZeroing &&
+      (count > (BlockZeroingLowLimit >> LogHeapWordSize))) {
+   // Call it only when block zeroing is used
+   ((_zero_Fn)StubRoutines::zero_aligned_words())(tohw, count);
+  } else {
    julong* to = (julong*)tohw;
    julong  v  = ((julong)value << 32) | value;
    // If count is odd, odd will be equal to 1 on 32-bit platform
@@ -176,6 +183,7 @@
      *((juint*)to) = value;
 
    }
+  }
 }
 
 static void pd_fill_to_bytes(void* to, size_t count, jubyte value) {
--- a/src/cpu/sparc/vm/frame_sparc.hpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/cpu/sparc/vm/frame_sparc.hpp	Wed Sep 07 11:52:00 2011 -0700
@@ -259,13 +259,8 @@
   };
 #endif /* CC_INTERP */
 
-  // the compiler frame has many of the same fields as the interpreter frame
-  // %%%%% factor out declarations of the shared fields
   enum compiler_frame_fixed_locals {
-       compiler_frame_d_scratch_fp_offset          = -2,
-       compiler_frame_vm_locals_fp_offset          = -2, // should be same as above
-
-       compiler_frame_vm_local_words = -compiler_frame_vm_locals_fp_offset
+       compiler_frame_vm_locals_fp_offset          = -2
   };
 
  private:
@@ -283,9 +278,6 @@
 
   inline void interpreter_frame_set_tos_address(intptr_t* x);
 
-
-  // %%%%% Another idea: instead of defining 3 fns per item, just define one returning a ref
-
   // monitors:
 
   // next two fns read and write Lmonitors value,
@@ -298,22 +290,8 @@
     return ((interpreterState)sp_at(interpreter_state_ptr_offset));
   }
 
-
 #endif /* CC_INTERP */
 
-
-
- // Compiled frames
-
  public:
-  // Tells if this register can hold 64 bits on V9 (really, V8+).
-  static bool holds_a_doubleword(Register reg) {
-#ifdef _LP64
-    //    return true;
-    return reg->is_out() || reg->is_global();
-#else
-    return reg->is_out() || reg->is_global();
-#endif
-  }
 
 #endif // CPU_SPARC_VM_FRAME_SPARC_HPP
--- a/src/cpu/sparc/vm/methodHandles_sparc.cpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/cpu/sparc/vm/methodHandles_sparc.cpp	Wed Sep 07 11:52:00 2011 -0700
@@ -1262,6 +1262,15 @@
     }
     break;
 
+  case _adapter_opt_profiling:
+    if (java_lang_invoke_CountingMethodHandle::vmcount_offset_in_bytes() != 0) {
+      Address G3_mh_vmcount(G3_method_handle, java_lang_invoke_CountingMethodHandle::vmcount_offset_in_bytes());
+      __ ld(G3_mh_vmcount, O1_scratch);
+      __ add(O1_scratch, 1, O1_scratch);
+      __ st(O1_scratch, G3_mh_vmcount);
+    }
+    // fall through
+
   case _adapter_retype_only:
   case _adapter_retype_raw:
     // Immediately jump to the next MH layer:
--- a/src/cpu/sparc/vm/sparc.ad	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/cpu/sparc/vm/sparc.ad	Wed Sep 07 11:52:00 2011 -0700
@@ -460,6 +460,8 @@
 // Must be visible to the DFA in dfa_sparc.cpp
 extern bool can_branch_register( Node *bol, Node *cmp );
 
+extern bool use_block_zeroing(Node* count);
+
 // Macros to extract hi & lo halves from a long pair.
 // G0 is not part of any long pair, so assert on that.
 // Prevents accidentally using G1 instead of G0.
@@ -521,6 +523,12 @@
   return false;
 }
 
+bool use_block_zeroing(Node* count) {
+  // Use BIS for zeroing if count is not constant
+  // or it is >= BlockZeroingLowLimit.
+  return UseBlockZeroing && (count->find_intptr_t_con(BlockZeroingLowLimit) >= BlockZeroingLowLimit);
+}
+
 // ****************************************************************************
 
 // REQUIRED FUNCTIONALITY
@@ -832,6 +840,7 @@
           !(n->ideal_Opcode()==Op_ConvI2D   && ld_op==Op_LoadF) &&
           !(n->ideal_Opcode()==Op_PrefetchRead  && ld_op==Op_LoadI) &&
           !(n->ideal_Opcode()==Op_PrefetchWrite && ld_op==Op_LoadI) &&
+          !(n->ideal_Opcode()==Op_PrefetchAllocation && ld_op==Op_LoadI) &&
           !(n->ideal_Opcode()==Op_Load2I    && ld_op==Op_LoadD) &&
           !(n->ideal_Opcode()==Op_Load4C    && ld_op==Op_LoadD) &&
           !(n->ideal_Opcode()==Op_Load4S    && ld_op==Op_LoadD) &&
@@ -2810,25 +2819,6 @@
     __ float_cmp( $primary, -1, Fsrc1, Fsrc2, Rdst);
   %}
 
-  // Compiler ensures base is doubleword aligned and cnt is count of doublewords
-  enc_class enc_Clear_Array(iRegX cnt, iRegP base, iRegX temp) %{
-    MacroAssembler _masm(&cbuf);
-    Register    nof_bytes_arg   = reg_to_register_object($cnt$$reg);
-    Register    nof_bytes_tmp    = reg_to_register_object($temp$$reg);
-    Register    base_pointer_arg = reg_to_register_object($base$$reg);
-  
-    Label loop;
-    __ mov(nof_bytes_arg, nof_bytes_tmp);
-  
-    // Loop and clear, walking backwards through the array.
-    // nof_bytes_tmp (if >0) is always the number of bytes to zero
-    __ bind(loop);
-    __ deccc(nof_bytes_tmp, 8);
-    __ br(Assembler::greaterEqual, true, Assembler::pt, loop);
-    __ delayed()-> stx(G0, base_pointer_arg, nof_bytes_tmp);
-    // %%%% this mini-loop must not cross a cache boundary!
-  %}
-
 
   enc_class enc_String_Compare(o0RegP str1, o1RegP str2, g3RegI cnt1, g4RegI cnt2, notemp_iRegI result) %{
     Label Ldone, Lloop;
@@ -10257,9 +10247,9 @@
   ins_pipe(long_memory_op);
 %}
 
-// Count and Base registers are fixed because the allocator cannot
-// kill unknown registers.  The encodings are generic.
+// The encodings are generic.
 instruct clear_array(iRegX cnt, iRegP base, iRegX temp, Universe dummy, flagsReg ccr) %{
+  predicate(!use_block_zeroing(n->in(2)) );
   match(Set dummy (ClearArray cnt base));
   effect(TEMP temp, KILL ccr);
   ins_cost(300);
@@ -10267,7 +10257,71 @@
     "loop:   SUBcc  $temp,8,$temp\t! Count down a dword of bytes\n"
     "        BRge   loop\t\t! Clearing loop\n"
     "        STX    G0,[$base+$temp]\t! delay slot" %}
-  ins_encode( enc_Clear_Array(cnt, base, temp) );
+
+  ins_encode %{
+    // Compiler ensures base is doubleword aligned and cnt is count of doublewords
+    Register nof_bytes_arg    = $cnt$$Register;
+    Register nof_bytes_tmp    = $temp$$Register;
+    Register base_pointer_arg = $base$$Register;
+
+    Label loop;
+    __ mov(nof_bytes_arg, nof_bytes_tmp);
+
+    // Loop and clear, walking backwards through the array.
+    // nof_bytes_tmp (if >0) is always the number of bytes to zero
+    __ bind(loop);
+    __ deccc(nof_bytes_tmp, 8);
+    __ br(Assembler::greaterEqual, true, Assembler::pt, loop);
+    __ delayed()-> stx(G0, base_pointer_arg, nof_bytes_tmp);
+    // %%%% this mini-loop must not cross a cache boundary!
+  %}
+  ins_pipe(long_memory_op);
+%}
+
+instruct clear_array_bis(g1RegX cnt, o0RegP base, Universe dummy, flagsReg ccr) %{
+  predicate(use_block_zeroing(n->in(2)));
+  match(Set dummy (ClearArray cnt base));
+  effect(USE_KILL cnt, USE_KILL base, KILL ccr);
+  ins_cost(300);
+  format %{ "CLEAR  [$base, $cnt]\t! ClearArray" %}
+
+  ins_encode %{
+
+    assert(MinObjAlignmentInBytes >= BytesPerLong, "need alternate implementation");
+    Register to    = $base$$Register;
+    Register count = $cnt$$Register;
+
+    Label Ldone;
+    __ nop(); // Separate short branches
+    // Use BIS for zeroing (temp is not used).
+    __ bis_zeroing(to, count, G0, Ldone);
+    __ bind(Ldone);
+
+  %}
+  ins_pipe(long_memory_op);
+%}
+
+instruct clear_array_bis_2(g1RegX cnt, o0RegP base, iRegX tmp, Universe dummy, flagsReg ccr) %{
+  predicate(use_block_zeroing(n->in(2)) && !Assembler::is_simm13((int)BlockZeroingLowLimit));
+  match(Set dummy (ClearArray cnt base));
+  effect(TEMP tmp, USE_KILL cnt, USE_KILL base, KILL ccr);
+  ins_cost(300);
+  format %{ "CLEAR  [$base, $cnt]\t! ClearArray" %}
+
+  ins_encode %{
+
+    assert(MinObjAlignmentInBytes >= BytesPerLong, "need alternate implementation");
+    Register to    = $base$$Register;
+    Register count = $cnt$$Register;
+    Register temp  = $tmp$$Register;
+
+    Label Ldone;
+    __ nop(); // Separate short branches
+    // Use BIS for zeroing
+    __ bis_zeroing(to, count, temp, Ldone);
+    __ bind(Ldone);
+
+  %}
   ins_pipe(long_memory_op);
 %}
 
--- a/src/cpu/sparc/vm/stubGenerator_sparc.cpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/cpu/sparc/vm/stubGenerator_sparc.cpp	Wed Sep 07 11:52:00 2011 -0700
@@ -1124,6 +1124,126 @@
     }
   }
 
+  //
+  // Generate main code for disjoint arraycopy
+  //
+  typedef void (StubGenerator::*CopyLoopFunc)(Register from, Register to, Register count, int count_dec,
+                                              Label& L_loop, bool use_prefetch, bool use_bis);
+
+  void disjoint_copy_core(Register from, Register to, Register count, int log2_elem_size,
+                          int iter_size, CopyLoopFunc copy_loop_func) {
+    Label L_copy;
+
+    assert(log2_elem_size <= 3, "the following code should be changed");
+    int count_dec = 16>>log2_elem_size;
+
+    int prefetch_dist = MAX2(ArraycopySrcPrefetchDistance, ArraycopyDstPrefetchDistance);
+    assert(prefetch_dist < 4096, "invalid value");
+    prefetch_dist = (prefetch_dist + (iter_size-1)) & (-iter_size); // round up to one iteration copy size
+    int prefetch_count = (prefetch_dist >> log2_elem_size); // elements count
+
+    if (UseBlockCopy) {
+      Label L_block_copy, L_block_copy_prefetch, L_skip_block_copy;
+
+      // 64 bytes tail + bytes copied in one loop iteration
+      int tail_size = 64 + iter_size;
+      int block_copy_count = (MAX2(tail_size, (int)BlockCopyLowLimit)) >> log2_elem_size;
+      // Use BIS copy only for big arrays since it requires membar.
+      __ set(block_copy_count, O4);
+      __ cmp_and_br_short(count, O4, Assembler::lessUnsigned, Assembler::pt, L_skip_block_copy);
+      // This code is for disjoint source and destination:
+      //   to <= from || to >= from+count
+      // but BIS will stomp over 'from' if (to > from-tail_size && to <= from)
+      __ sub(from, to, O4);
+      __ srax(O4, 4, O4); // divide by 16 since following short branch have only 5 bits for imm.
+      __ cmp_and_br_short(O4, (tail_size>>4), Assembler::lessEqualUnsigned, Assembler::pn, L_skip_block_copy);
+
+      __ wrasi(G0, Assembler::ASI_ST_BLKINIT_PRIMARY);
+      // BIS should not be used to copy tail (64 bytes+iter_size)
+      // to avoid zeroing of following values.
+      __ sub(count, (tail_size>>log2_elem_size), count); // count is still positive >= 0
+
+      if (prefetch_count > 0) { // rounded up to one iteration count
+        // Do prefetching only if copy size is bigger
+        // than prefetch distance.
+        __ set(prefetch_count, O4);
+        __ cmp_and_brx_short(count, O4, Assembler::less, Assembler::pt, L_block_copy);
+        __ sub(count, prefetch_count, count);
+
+        (this->*copy_loop_func)(from, to, count, count_dec, L_block_copy_prefetch, true, true);
+        __ add(count, prefetch_count, count); // restore count
+
+      } // prefetch_count > 0
+
+      (this->*copy_loop_func)(from, to, count, count_dec, L_block_copy, false, true);
+      __ add(count, (tail_size>>log2_elem_size), count); // restore count
+
+      __ wrasi(G0, Assembler::ASI_PRIMARY_NOFAULT);
+      // BIS needs membar.
+      __ membar(Assembler::StoreLoad);
+      // Copy tail
+      __ ba_short(L_copy);
+
+      __ BIND(L_skip_block_copy);
+    } // UseBlockCopy
+
+    if (prefetch_count > 0) { // rounded up to one iteration count
+      // Do prefetching only if copy size is bigger
+      // than prefetch distance.
+      __ set(prefetch_count, O4);
+      __ cmp_and_brx_short(count, O4, Assembler::lessUnsigned, Assembler::pt, L_copy);
+      __ sub(count, prefetch_count, count);
+
+      Label L_copy_prefetch;
+      (this->*copy_loop_func)(from, to, count, count_dec, L_copy_prefetch, true, false);
+      __ add(count, prefetch_count, count); // restore count
+
+    } // prefetch_count > 0
+
+    (this->*copy_loop_func)(from, to, count, count_dec, L_copy, false, false);
+  }
+
+
+
+  //
+  // Helper methods for copy_16_bytes_forward_with_shift()
+  //
+  void copy_16_bytes_shift_loop(Register from, Register to, Register count, int count_dec,
+                                Label& L_loop, bool use_prefetch, bool use_bis) {
+
+    const Register left_shift  = G1; // left  shift bit counter
+    const Register right_shift = G5; // right shift bit counter
+
+    __ align(OptoLoopAlignment);
+    __ BIND(L_loop);
+    if (use_prefetch) {
+      if (ArraycopySrcPrefetchDistance > 0) {
+        __ prefetch(from, ArraycopySrcPrefetchDistance, Assembler::severalReads);
+      }
+      if (ArraycopyDstPrefetchDistance > 0) {
+        __ prefetch(to, ArraycopyDstPrefetchDistance, Assembler::severalWritesAndPossiblyReads);
+      }
+    }
+    __ ldx(from, 0, O4);
+    __ ldx(from, 8, G4);
+    __ inc(to, 16);
+    __ inc(from, 16);
+    __ deccc(count, count_dec); // Can we do next iteration after this one?
+    __ srlx(O4, right_shift, G3);
+    __ bset(G3, O3);
+    __ sllx(O4, left_shift,  O4);
+    __ srlx(G4, right_shift, G3);
+    __ bset(G3, O4);
+    if (use_bis) {
+      __ stxa(O3, to, -16);
+      __ stxa(O4, to, -8);
+    } else {
+      __ stx(O3, to, -16);
+      __ stx(O4, to, -8);
+    }
+    __ brx(Assembler::greaterEqual, false, Assembler::pt, L_loop);
+    __ delayed()->sllx(G4, left_shift,  O3);
+  }
 
   // Copy big chunks forward with shift
   //
@@ -1135,64 +1255,51 @@
   //   L_copy_bytes - copy exit label
   //
   void copy_16_bytes_forward_with_shift(Register from, Register to,
-                     Register count, int count_dec, Label& L_copy_bytes) {
-    Label L_loop, L_aligned_copy, L_copy_last_bytes;
+                     Register count, int log2_elem_size, Label& L_copy_bytes) {
+    Label L_aligned_copy, L_copy_last_bytes;
+    assert(log2_elem_size <= 3, "the following code should be changed");
+    int count_dec = 16>>log2_elem_size;
 
     // if both arrays have the same alignment mod 8, do 8 bytes aligned copy
-      __ andcc(from, 7, G1); // misaligned bytes
-      __ br(Assembler::zero, false, Assembler::pt, L_aligned_copy);
-      __ delayed()->nop();
+    __ andcc(from, 7, G1); // misaligned bytes
+    __ br(Assembler::zero, false, Assembler::pt, L_aligned_copy);
+    __ delayed()->nop();
 
     const Register left_shift  = G1; // left  shift bit counter
     const Register right_shift = G5; // right shift bit counter
 
-      __ sll(G1, LogBitsPerByte, left_shift);
-      __ mov(64, right_shift);
-      __ sub(right_shift, left_shift, right_shift);
+    __ sll(G1, LogBitsPerByte, left_shift);
+    __ mov(64, right_shift);
+    __ sub(right_shift, left_shift, right_shift);
 
     //
     // Load 2 aligned 8-bytes chunks and use one from previous iteration
     // to form 2 aligned 8-bytes chunks to store.
     //
-      __ deccc(count, count_dec); // Pre-decrement 'count'
-      __ andn(from, 7, from);     // Align address
-      __ ldx(from, 0, O3);
-      __ inc(from, 8);
-      __ align(OptoLoopAlignment);
-    __ BIND(L_loop);
-      __ ldx(from, 0, O4);
-      __ deccc(count, count_dec); // Can we do next iteration after this one?
-      __ ldx(from, 8, G4);
-      __ inc(to, 16);
-      __ inc(from, 16);
-      __ sllx(O3, left_shift,  O3);
-      __ srlx(O4, right_shift, G3);
-      __ bset(G3, O3);
-      __ stx(O3, to, -16);
-      __ sllx(O4, left_shift,  O4);
-      __ srlx(G4, right_shift, G3);
-      __ bset(G3, O4);
-      __ stx(O4, to, -8);
-      __ brx(Assembler::greaterEqual, false, Assembler::pt, L_loop);
-      __ delayed()->mov(G4, O3);
-
-      __ inccc(count, count_dec>>1 ); // + 8 bytes
-      __ brx(Assembler::negative, true, Assembler::pn, L_copy_last_bytes);
-      __ delayed()->inc(count, count_dec>>1); // restore 'count'
-
-      // copy 8 bytes, part of them already loaded in O3
-      __ ldx(from, 0, O4);
-      __ inc(to, 8);
-      __ inc(from, 8);
-      __ sllx(O3, left_shift,  O3);
-      __ srlx(O4, right_shift, G3);
-      __ bset(O3, G3);
-      __ stx(G3, to, -8);
+    __ dec(count, count_dec);   // Pre-decrement 'count'
+    __ andn(from, 7, from);     // Align address
+    __ ldx(from, 0, O3);
+    __ inc(from, 8);
+    __ sllx(O3, left_shift,  O3);
+
+    disjoint_copy_core(from, to, count, log2_elem_size, 16, copy_16_bytes_shift_loop);
+
+    __ inccc(count, count_dec>>1 ); // + 8 bytes
+    __ brx(Assembler::negative, true, Assembler::pn, L_copy_last_bytes);
+    __ delayed()->inc(count, count_dec>>1); // restore 'count'
+
+    // copy 8 bytes, part of them already loaded in O3
+    __ ldx(from, 0, O4);
+    __ inc(to, 8);
+    __ inc(from, 8);
+    __ srlx(O4, right_shift, G3);
+    __ bset(O3, G3);
+    __ stx(G3, to, -8);
 
     __ BIND(L_copy_last_bytes);
-      __ srl(right_shift, LogBitsPerByte, right_shift); // misaligned bytes
-      __ br(Assembler::always, false, Assembler::pt, L_copy_bytes);
-      __ delayed()->sub(from, right_shift, from);       // restore address
+    __ srl(right_shift, LogBitsPerByte, right_shift); // misaligned bytes
+    __ br(Assembler::always, false, Assembler::pt, L_copy_bytes);
+    __ delayed()->sub(from, right_shift, from);       // restore address
 
     __ BIND(L_aligned_copy);
   }
@@ -1348,7 +1455,7 @@
       // The compare above (count >= 23) guarantes 'count' >= 16 bytes.
       // Also jump over aligned copy after the copy with shift completed.
 
-      copy_16_bytes_forward_with_shift(from, to, count, 16, L_copy_byte);
+      copy_16_bytes_forward_with_shift(from, to, count, 0, L_copy_byte);
     }
 
     // Both array are 8 bytes aligned, copy 16 bytes at a time
@@ -1576,7 +1683,7 @@
       // The compare above (count >= 11) guarantes 'count' >= 16 bytes.
       // Also jump over aligned copy after the copy with shift completed.
 
-      copy_16_bytes_forward_with_shift(from, to, count, 8, L_copy_2_bytes);
+      copy_16_bytes_forward_with_shift(from, to, count, 1, L_copy_2_bytes);
     }
 
     // Both array are 8 bytes aligned, copy 16 bytes at a time
@@ -1950,6 +2057,45 @@
   }
 
   //
+  // Helper methods for generate_disjoint_int_copy_core()
+  //
+  void copy_16_bytes_loop(Register from, Register to, Register count, int count_dec,
+                          Label& L_loop, bool use_prefetch, bool use_bis) {
+
+    __ align(OptoLoopAlignment);
+    __ BIND(L_loop);
+    if (use_prefetch) {
+      if (ArraycopySrcPrefetchDistance > 0) {
+        __ prefetch(from, ArraycopySrcPrefetchDistance, Assembler::severalReads);
+      }
+      if (ArraycopyDstPrefetchDistance > 0) {
+        __ prefetch(to, ArraycopyDstPrefetchDistance, Assembler::severalWritesAndPossiblyReads);
+      }
+    }
+    __ ldx(from, 4, O4);
+    __ ldx(from, 12, G4);
+    __ inc(to, 16);
+    __ inc(from, 16);
+    __ deccc(count, 4); // Can we do next iteration after this one?
+
+    __ srlx(O4, 32, G3);
+    __ bset(G3, O3);
+    __ sllx(O4, 32, O4);
+    __ srlx(G4, 32, G3);
+    __ bset(G3, O4);
+    if (use_bis) {
+      __ stxa(O3, to, -16);
+      __ stxa(O4, to, -8);
+    } else {
+      __ stx(O3, to, -16);
+      __ stx(O4, to, -8);
+    }
+    __ brx(Assembler::greaterEqual, false, Assembler::pt, L_loop);
+    __ delayed()->sllx(G4, 32,  O3);
+
+  }
+
+  //
   //  Generate core code for disjoint int copy (and oop copy on 32-bit).
   //  If "aligned" is true, the "from" and "to" addresses are assumed
   //  to be heapword aligned.
@@ -1962,7 +2108,7 @@
   void generate_disjoint_int_copy_core(bool aligned) {
 
     Label L_skip_alignment, L_aligned_copy;
-    Label L_copy_16_bytes,  L_copy_4_bytes, L_copy_4_bytes_loop, L_exit;
+    Label L_copy_4_bytes, L_copy_4_bytes_loop, L_exit;
 
     const Register from      = O0;   // source array address
     const Register to        = O1;   // destination array address
@@ -2013,30 +2159,16 @@
 
     // copy with shift 4 elements (16 bytes) at a time
       __ dec(count, 4);   // The cmp at the beginning guaranty count >= 4
-
-      __ align(OptoLoopAlignment);
-    __ BIND(L_copy_16_bytes);
-      __ ldx(from, 4, O4);
-      __ deccc(count, 4); // Can we do next iteration after this one?
-      __ ldx(from, 12, G4);
-      __ inc(to, 16);
-      __ inc(from, 16);
-      __ sllx(O3, 32, O3);
-      __ srlx(O4, 32, G3);
-      __ bset(G3, O3);
-      __ stx(O3, to, -16);
-      __ sllx(O4, 32, O4);
-      __ srlx(G4, 32, G3);
-      __ bset(G3, O4);
-      __ stx(O4, to, -8);
-      __ brx(Assembler::greaterEqual, false, Assembler::pt, L_copy_16_bytes);
-      __ delayed()->mov(G4, O3);
+      __ sllx(O3, 32,  O3);
+
+      disjoint_copy_core(from, to, count, 2, 16, copy_16_bytes_loop);
 
       __ br(Assembler::always, false, Assembler::pt, L_copy_4_bytes);
       __ delayed()->inc(count, 4); // restore 'count'
 
     __ BIND(L_aligned_copy);
-    }
+    } // !aligned
+
     // copy 4 elements (16 bytes) at a time
       __ and3(count, 1, G4); // Save
       __ srl(count, 1, count);
@@ -2223,6 +2355,38 @@
   }
 
   //
+  // Helper methods for generate_disjoint_long_copy_core()
+  //
+  void copy_64_bytes_loop(Register from, Register to, Register count, int count_dec,
+                          Label& L_loop, bool use_prefetch, bool use_bis) {
+    __ align(OptoLoopAlignment);
+    __ BIND(L_loop);
+    for (int off = 0; off < 64; off += 16) {
+      if (use_prefetch && (off & 31) == 0) {
+        if (ArraycopySrcPrefetchDistance > 0) {
+          __ prefetch(from, ArraycopySrcPrefetchDistance, Assembler::severalReads);
+        }
+        if (ArraycopyDstPrefetchDistance > 0) {
+          __ prefetch(to, ArraycopyDstPrefetchDistance, Assembler::severalWritesAndPossiblyReads);
+        }
+      }
+      __ ldx(from,  off+0, O4);
+      __ ldx(from,  off+8, O5);
+      if (use_bis) {
+        __ stxa(O4, to,  off+0);
+        __ stxa(O5, to,  off+8);
+      } else {
+        __ stx(O4, to,  off+0);
+        __ stx(O5, to,  off+8);
+      }
+    }
+    __ deccc(count, 8);
+    __ inc(from, 64);
+    __ brx(Assembler::greaterEqual, false, Assembler::pt, L_loop);
+    __ delayed()->inc(to, 64);
+  }
+
+  //
   //  Generate core code for disjoint long copy (and oop copy on 64-bit).
   //  "aligned" is ignored, because we must make the stronger
   //  assumption that both addresses are always 64-bit aligned.
@@ -2261,38 +2425,28 @@
     const Register offset0 = O4;  // element offset
     const Register offset8 = O5;  // next element offset
 
-      __ deccc(count, 2);
-      __ mov(G0, offset0);   // offset from start of arrays (0)
-      __ brx(Assembler::negative, false, Assembler::pn, L_copy_8_bytes );
-      __ delayed()->add(offset0, 8, offset8);
+    __ deccc(count, 2);
+    __ mov(G0, offset0);   // offset from start of arrays (0)
+    __ brx(Assembler::negative, false, Assembler::pn, L_copy_8_bytes );
+    __ delayed()->add(offset0, 8, offset8);
 
     // Copy by 64 bytes chunks
-    Label L_copy_64_bytes;
+
     const Register from64 = O3;  // source address
     const Register to64   = G3;  // destination address
-      __ subcc(count, 6, O3);
-      __ brx(Assembler::negative, false, Assembler::pt, L_copy_16_bytes );
-      __ delayed()->mov(to,   to64);
-      // Now we can use O4(offset0), O5(offset8) as temps
-      __ mov(O3, count);
-      __ mov(from, from64);
-
-      __ align(OptoLoopAlignment);
-    __ BIND(L_copy_64_bytes);
-      for( int off = 0; off < 64; off += 16 ) {
-        __ ldx(from64,  off+0, O4);
-        __ ldx(from64,  off+8, O5);
-        __ stx(O4, to64,  off+0);
-        __ stx(O5, to64,  off+8);
-      }
-      __ deccc(count, 8);
-      __ inc(from64, 64);
-      __ brx(Assembler::greaterEqual, false, Assembler::pt, L_copy_64_bytes);
-      __ delayed()->inc(to64, 64);
+    __ subcc(count, 6, O3);
+    __ brx(Assembler::negative, false, Assembler::pt, L_copy_16_bytes );
+    __ delayed()->mov(to,   to64);
+    // Now we can use O4(offset0), O5(offset8) as temps
+    __ mov(O3, count);
+    // count >= 0 (original count - 8)
+    __ mov(from, from64);
+
+    disjoint_copy_core(from64, to64, count, 3, 64, copy_64_bytes_loop);
 
       // Restore O4(offset0), O5(offset8)
       __ sub(from64, from, offset0);
-      __ inccc(count, 6);
+      __ inccc(count, 6); // restore count
       __ brx(Assembler::negative, false, Assembler::pn, L_copy_8_bytes );
       __ delayed()->add(offset0, 8, offset8);
 
@@ -3069,6 +3223,34 @@
     return start;
   }
 
+  //
+  //  Generate stub for heap zeroing.
+  //  "to" address is aligned to jlong (8 bytes).
+  //
+  // Arguments for generated stub:
+  //      to:    O0
+  //      count: O1 treated as signed (count of HeapWord)
+  //             count could be 0
+  //
+  address generate_zero_aligned_words(const char* name) {
+    __ align(CodeEntryAlignment);
+    StubCodeMark mark(this, "StubRoutines", name);
+    address start = __ pc();
+
+    const Register to    = O0;   // source array address
+    const Register count = O1;   // HeapWords count
+    const Register temp  = O2;   // scratch
+
+    Label Ldone;
+    __ sllx(count, LogHeapWordSize, count); // to bytes count
+    // Use BIS for zeroing
+    __ bis_zeroing(to, count, temp, Ldone);
+    __ bind(Ldone);
+    __ retl();
+    __ delayed()->nop();
+    return start;
+}
+
   void generate_arraycopy_stubs() {
     address entry;
     address entry_jbyte_arraycopy;
@@ -3195,6 +3377,10 @@
     StubRoutines::_arrayof_jbyte_fill = generate_fill(T_BYTE, true, "arrayof_jbyte_fill");
     StubRoutines::_arrayof_jshort_fill = generate_fill(T_SHORT, true, "arrayof_jshort_fill");
     StubRoutines::_arrayof_jint_fill = generate_fill(T_INT, true, "arrayof_jint_fill");
+
+    if (UseBlockZeroing) {
+      StubRoutines::_zero_aligned_words = generate_zero_aligned_words("zero_aligned_words");
+    }
   }
 
   void generate_initial() {
--- a/src/cpu/sparc/vm/templateTable_sparc.cpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/cpu/sparc/vm/templateTable_sparc.cpp	Wed Sep 07 11:52:00 2011 -0700
@@ -3374,7 +3374,7 @@
 
   if(UseTLAB) {
     Register RoldTopValue = RallocatedObject;
-    Register RtopAddr = G3_scratch, RtlabWasteLimitValue = G3_scratch;
+    Register RtlabWasteLimitValue = G3_scratch;
     Register RnewTopValue = G1_scratch;
     Register RendValue = Rscratch;
     Register RfreeValue = RnewTopValue;
@@ -3455,7 +3455,11 @@
     __ delayed()->add(RallocatedObject, sizeof(oopDesc), G3_scratch);
 
     // initialize remaining object fields
-    { Label loop;
+    if (UseBlockZeroing) {
+      // Use BIS for zeroing
+      __ bis_zeroing(G3_scratch, Roffset, G1_scratch, initialize_header);
+    } else {
+      Label loop;
       __ subcc(Roffset, wordSize, Roffset);
       __ bind(loop);
       //__ subcc(Roffset, wordSize, Roffset);      // executed above loop or in delay slot
--- a/src/cpu/sparc/vm/vm_version_sparc.cpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/cpu/sparc/vm/vm_version_sparc.cpp	Wed Sep 07 11:52:00 2011 -0700
@@ -75,6 +75,24 @@
     FLAG_SET_DEFAULT(AllocatePrefetchStyle, 1);
   }
 
+  if (has_v9()) {
+    assert(ArraycopySrcPrefetchDistance < 4096, "invalid value");
+    if (ArraycopySrcPrefetchDistance >= 4096)
+      ArraycopySrcPrefetchDistance = 4064;
+    assert(ArraycopyDstPrefetchDistance < 4096, "invalid value");
+    if (ArraycopyDstPrefetchDistance >= 4096)
+      ArraycopyDstPrefetchDistance = 4064;
+  } else {
+    if (ArraycopySrcPrefetchDistance > 0) {
+      warning("prefetch instructions are not available on this CPU");
+      FLAG_SET_DEFAULT(ArraycopySrcPrefetchDistance, 0);
+    }
+    if (ArraycopyDstPrefetchDistance > 0) {
+      warning("prefetch instructions are not available on this CPU");
+      FLAG_SET_DEFAULT(ArraycopyDstPrefetchDistance, 0);
+    }
+  }
+
   UseSSE = 0; // Only on x86 and x64
 
   _supports_cx8 = has_v9();
@@ -170,6 +188,26 @@
     FLAG_SET_DEFAULT(UseCBCond, false);
   }
 
+  assert(BlockZeroingLowLimit > 0, "invalid value");
+  if (has_block_zeroing()) {
+    if (FLAG_IS_DEFAULT(UseBlockZeroing)) {
+      FLAG_SET_DEFAULT(UseBlockZeroing, true);
+    }
+  } else if (UseBlockZeroing) {
+    warning("BIS zeroing instructions are not available on this CPU");
+    FLAG_SET_DEFAULT(UseBlockZeroing, false);
+  }
+
+  assert(BlockCopyLowLimit > 0, "invalid value");
+  if (has_block_zeroing()) { // has_blk_init() && is_T4(): core's local L2 cache
+    if (FLAG_IS_DEFAULT(UseBlockCopy)) {
+      FLAG_SET_DEFAULT(UseBlockCopy, true);
+    }
+  } else if (UseBlockCopy) {
+    warning("BIS instructions are not available or expensive on this CPU");
+    FLAG_SET_DEFAULT(UseBlockCopy, false);
+  }
+
 #ifdef COMPILER2
   // T4 and newer Sparc cpus have fast RDPC.
   if (has_fast_rdpc() && FLAG_IS_DEFAULT(UseRDPCForConstantTableBase)) {
--- a/src/cpu/sparc/vm/vm_version_sparc.hpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/cpu/sparc/vm/vm_version_sparc.hpp	Wed Sep 07 11:52:00 2011 -0700
@@ -135,8 +135,8 @@
   // T4 and newer Sparc have fast RDPC instruction.
   static bool has_fast_rdpc()           { return is_T4(); }
 
-  // T4 and newer Sparc have Most-Recently-Used (MRU) BIS.
-  static bool has_mru_blk_init()        { return has_blk_init() && is_T4(); }
+  // On T4 and newer Sparc BIS to the beginning of cache line always zeros it.
+  static bool has_block_zeroing()       { return has_blk_init() && is_T4(); }
 
   static const char* cpu_features()     { return _features_str; }
 
--- a/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Wed Sep 07 11:52:00 2011 -0700
@@ -129,10 +129,6 @@
   return FrameMap::receiver_opr;
 }
 
-LIR_Opr LIR_Assembler::incomingReceiverOpr() {
-  return receiverOpr();
-}
-
 LIR_Opr LIR_Assembler::osrBufferPointer() {
   return FrameMap::as_pointer_opr(receiverOpr()->as_register());
 }
@@ -371,55 +367,6 @@
 }
 
 
-void LIR_Assembler::monitorexit(LIR_Opr obj_opr, LIR_Opr lock_opr, Register new_hdr, int monitor_no, Register exception) {
-  if (exception->is_valid()) {
-    // preserve exception
-    // note: the monitor_exit runtime call is a leaf routine
-    //       and cannot block => no GC can happen
-    // The slow case (MonitorAccessStub) uses the first two stack slots
-    // ([esp+0] and [esp+4]), therefore we store the exception at [esp+8]
-    __ movptr (Address(rsp, 2*wordSize), exception);
-  }
-
-  Register obj_reg  = obj_opr->as_register();
-  Register lock_reg = lock_opr->as_register();
-
-  // setup registers (lock_reg must be rax, for lock_object)
-  assert(obj_reg != SYNC_header && lock_reg != SYNC_header, "rax, must be available here");
-  Register hdr = lock_reg;
-  assert(new_hdr == SYNC_header, "wrong register");
-  lock_reg = new_hdr;
-  // compute pointer to BasicLock
-  Address lock_addr = frame_map()->address_for_monitor_lock(monitor_no);
-  __ lea(lock_reg, lock_addr);
-  // unlock object
-  MonitorAccessStub* slow_case = new MonitorExitStub(lock_opr, true, monitor_no);
-  // _slow_case_stubs->append(slow_case);
-  // temporary fix: must be created after exceptionhandler, therefore as call stub
-  _slow_case_stubs->append(slow_case);
-  if (UseFastLocking) {
-    // try inlined fast unlocking first, revert to slow locking if it fails
-    // note: lock_reg points to the displaced header since the displaced header offset is 0!
-    assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header");
-    __ unlock_object(hdr, obj_reg, lock_reg, *slow_case->entry());
-  } else {
-    // always do slow unlocking
-    // note: the slow unlocking code could be inlined here, however if we use
-    //       slow unlocking, speed doesn't matter anyway and this solution is
-    //       simpler and requires less duplicated code - additionally, the
-    //       slow unlocking code is the same in either case which simplifies
-    //       debugging
-    __ jmp(*slow_case->entry());
-  }
-  // done
-  __ bind(*slow_case->continuation());
-
-  if (exception->is_valid()) {
-    // restore exception
-    __ movptr (exception, Address(rsp, 2 * wordSize));
-  }
-}
-
 // This specifies the rsp decrement needed to build the frame
 int LIR_Assembler::initial_frame_size_in_bytes() {
   // if rounding, must let FrameMap know!
--- a/src/cpu/x86/vm/c1_LIRAssembler_x86.hpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/cpu/x86/vm/c1_LIRAssembler_x86.hpp	Wed Sep 07 11:52:00 2011 -0700
@@ -29,8 +29,6 @@
 
   Address::ScaleFactor array_element_size(BasicType type) const;
 
-  void monitorexit(LIR_Opr obj_opr, LIR_Opr lock_opr, Register new_hdr, int monitor_no, Register exception);
-
   void arith_fpu_implementation(LIR_Code code, int left_index, int right_index, int dest_index, bool pop_fpu_stack);
 
   // helper functions which checks for overflow and sets bailout if it
--- a/src/cpu/x86/vm/c1_Runtime1_x86.cpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/cpu/x86/vm/c1_Runtime1_x86.cpp	Wed Sep 07 11:52:00 2011 -0700
@@ -1465,19 +1465,6 @@
       }
       break;
 
-    case jvmti_exception_throw_id:
-      { // rax,: exception oop
-        StubFrame f(sasm, "jvmti_exception_throw", dont_gc_arguments);
-        // Preserve all registers across this potentially blocking call
-        const int num_rt_args = 2;  // thread, exception oop
-        OopMap* map = save_live_registers(sasm, num_rt_args);
-        int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, Runtime1::post_jvmti_exception_throw), rax);
-        oop_maps = new OopMapSet();
-        oop_maps->add_gc_map(call_offset, map);
-        restore_live_registers(sasm);
-      }
-      break;
-
     case dtrace_object_alloc_id:
       { // rax,: object
         StubFrame f(sasm, "dtrace_object_alloc", dont_gc_arguments);
--- a/src/cpu/x86/vm/methodHandles_x86.cpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/cpu/x86/vm/methodHandles_x86.cpp	Wed Sep 07 11:52:00 2011 -0700
@@ -1343,6 +1343,13 @@
     }
     break;
 
+  case _adapter_opt_profiling:
+    if (java_lang_invoke_CountingMethodHandle::vmcount_offset_in_bytes() != 0) {
+      Address rcx_mh_vmcount(rcx_recv, java_lang_invoke_CountingMethodHandle::vmcount_offset_in_bytes());
+      __ incrementl(rcx_mh_vmcount);
+    }
+    // fall through
+
   case _adapter_retype_only:
   case _adapter_retype_raw:
     // immediately jump to the next MH layer:
--- a/src/cpu/x86/vm/methodHandles_x86.hpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/cpu/x86/vm/methodHandles_x86.hpp	Wed Sep 07 11:52:00 2011 -0700
@@ -110,6 +110,7 @@
 
 class RicochetFrame {
   friend class MethodHandles;
+  friend class VMStructs;
 
  private:
   intptr_t* _continuation;          // what to do when control gets back here
--- a/src/share/vm/c1/c1_Compilation.cpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/c1/c1_Compilation.cpp	Wed Sep 07 11:52:00 2011 -0700
@@ -346,7 +346,6 @@
     implicit_exception_table(),
     compiler(),
     _env->comp_level(),
-    true,
     has_unsafe_access()
   );
 }
--- a/src/share/vm/c1/c1_GraphBuilder.cpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/c1/c1_GraphBuilder.cpp	Wed Sep 07 11:52:00 2011 -0700
@@ -28,8 +28,10 @@
 #include "c1/c1_Compilation.hpp"
 #include "c1/c1_GraphBuilder.hpp"
 #include "c1/c1_InstructionPrinter.hpp"
+#include "ci/ciCallSite.hpp"
 #include "ci/ciField.hpp"
 #include "ci/ciKlass.hpp"
+#include "ci/ciMethodHandle.hpp"
 #include "compiler/compileBroker.hpp"
 #include "interpreter/bytecode.hpp"
 #include "runtime/sharedRuntime.hpp"
@@ -1424,7 +1426,7 @@
     // See whether this is the first return; if so, store off some
     // of the state for later examination
     if (num_returns() == 0) {
-      set_inline_cleanup_info(_block, _last, state());
+      set_inline_cleanup_info();
     }
 
     // The current bci() is in the wrong scope, so use the bci() of
@@ -1582,6 +1584,8 @@
     code = Bytecodes::_invokespecial;
   }
 
+  bool is_invokedynamic = code == Bytecodes::_invokedynamic;
+
   // NEEDS_CLEANUP
   // I've added the target-is_loaded() test below but I don't really understand
   // how klass->is_loaded() can be true and yet target->is_loaded() is false.
@@ -1693,26 +1697,31 @@
       && target->will_link(klass, callee_holder, code)) {
     // callee is known => check if we have static binding
     assert(target->is_loaded(), "callee must be known");
-    if (code == Bytecodes::_invokestatic
-     || code == Bytecodes::_invokespecial
-     || code == Bytecodes::_invokevirtual && target->is_final_method()
-    ) {
-      // static binding => check if callee is ok
-      ciMethod* inline_target = (cha_monomorphic_target != NULL)
-                                  ? cha_monomorphic_target
-                                  : target;
-      bool res = try_inline(inline_target, (cha_monomorphic_target != NULL) || (exact_target != NULL));
+    if (code == Bytecodes::_invokestatic  ||
+        code == Bytecodes::_invokespecial ||
+        code == Bytecodes::_invokevirtual && target->is_final_method() ||
+        code == Bytecodes::_invokedynamic) {
+      ciMethod* inline_target = (cha_monomorphic_target != NULL) ? cha_monomorphic_target : target;
+      bool success = false;
+      if (target->is_method_handle_invoke()) {
+        // method handle invokes
+        success = !is_invokedynamic ? for_method_handle_inline(target) : for_invokedynamic_inline(target);
+      }
+      if (!success) {
+        // static binding => check if callee is ok
+        success = try_inline(inline_target, (cha_monomorphic_target != NULL) || (exact_target != NULL));
+      }
       CHECK_BAILOUT();
 
 #ifndef PRODUCT
       // printing
-      if (PrintInlining && !res) {
+      if (PrintInlining && !success) {
         // if it was successfully inlined, then it was already printed.
-        print_inline_result(inline_target, res);
+        print_inline_result(inline_target, success);
       }
 #endif
       clear_inline_bailout();
-      if (res) {
+      if (success) {
         // Register dependence if JVMTI has either breakpoint
         // setting or hotswapping of methods capabilities since they may
         // cause deoptimization.
@@ -1740,7 +1749,6 @@
     code == Bytecodes::_invokespecial   ||
     code == Bytecodes::_invokevirtual   ||
     code == Bytecodes::_invokeinterface;
-  bool is_invokedynamic = code == Bytecodes::_invokedynamic;
   ValueType* result_type = as_ValueType(target->return_type());
 
   // We require the debug info to be the "state before" because
@@ -3038,7 +3046,7 @@
     INLINE_BAILOUT("disallowed by CompilerOracle")
   } else if (!callee->can_be_compiled()) {
     // callee is not compilable (prob. has breakpoints)
-    INLINE_BAILOUT("not compilable")
+    INLINE_BAILOUT("not compilable (disabled)")
   } else if (callee->intrinsic_id() != vmIntrinsics::_none && try_inline_intrinsics(callee)) {
     // intrinsics can be native or not
     return true;
@@ -3397,7 +3405,7 @@
 }
 
 
-bool GraphBuilder::try_inline_full(ciMethod* callee, bool holder_known) {
+bool GraphBuilder::try_inline_full(ciMethod* callee, bool holder_known, BlockBegin* cont_block) {
   assert(!callee->is_native(), "callee must not be native");
   if (CompilationPolicy::policy()->should_not_inline(compilation()->env(), callee)) {
     INLINE_BAILOUT("inlining prohibited by policy");
@@ -3430,7 +3438,7 @@
   } else {
     if (inline_level() > MaxInlineLevel                         ) INLINE_BAILOUT("too-deep inlining");
     if (recursive_inline_level(callee) > MaxRecursiveInlineLevel) INLINE_BAILOUT("too-deep recursive inlining");
-    if (callee->code_size() > max_inline_size()                 ) INLINE_BAILOUT("callee is too large");
+    if (callee->code_size_for_inlining() > max_inline_size()    ) INLINE_BAILOUT("callee is too large");
 
     // don't inline throwable methods unless the inlining tree is rooted in a throwable class
     if (callee->name() == ciSymbol::object_initializer_name() &&
@@ -3468,7 +3476,8 @@
 
   // Insert null check if necessary
   Value recv = NULL;
-  if (code() != Bytecodes::_invokestatic) {
+  if (code() != Bytecodes::_invokestatic &&
+      code() != Bytecodes::_invokedynamic) {
     // note: null check must happen even if first instruction of callee does
     //       an implicit null check since the callee is in a different scope
     //       and we must make sure exception handling does the right thing
@@ -3496,7 +3505,7 @@
   // fall-through of control flow, all return instructions of the
   // callee will need to be replaced by Goto's pointing to this
   // continuation point.
-  BlockBegin* cont = block_at(next_bci());
+  BlockBegin* cont = cont_block != NULL ? cont_block : block_at(next_bci());
   bool continuation_existed = true;
   if (cont == NULL) {
     cont = new BlockBegin(next_bci());
@@ -3608,27 +3617,29 @@
   // block merging. This allows load elimination and CSE to take place
   // across multiple callee scopes if they are relatively simple, and
   // is currently essential to making inlining profitable.
-  if (   num_returns() == 1
-      && block() == orig_block
-      && block() == inline_cleanup_block()) {
-    _last = inline_cleanup_return_prev();
-    _state = inline_cleanup_state();
-  } else if (continuation_preds == cont->number_of_preds()) {
-    // Inlining caused that the instructions after the invoke in the
-    // caller are not reachable any more. So skip filling this block
-    // with instructions!
-    assert (cont == continuation(), "");
-    assert(_last && _last->as_BlockEnd(), "");
-    _skip_block = true;
-  } else {
-    // Resume parsing in continuation block unless it was already parsed.
-    // Note that if we don't change _last here, iteration in
-    // iterate_bytecodes_for_block will stop when we return.
-    if (!continuation()->is_set(BlockBegin::was_visited_flag)) {
-      // add continuation to work list instead of parsing it immediately
+  if (cont_block == NULL) {
+    if (num_returns() == 1
+        && block() == orig_block
+        && block() == inline_cleanup_block()) {
+      _last  = inline_cleanup_return_prev();
+      _state = inline_cleanup_state();
+    } else if (continuation_preds == cont->number_of_preds()) {
+      // Inlining caused that the instructions after the invoke in the
+      // caller are not reachable any more. So skip filling this block
+      // with instructions!
+      assert(cont == continuation(), "");
       assert(_last && _last->as_BlockEnd(), "");
-      scope_data()->parent()->add_to_work_list(continuation());
       _skip_block = true;
+    } else {
+      // Resume parsing in continuation block unless it was already parsed.
+      // Note that if we don't change _last here, iteration in
+      // iterate_bytecodes_for_block will stop when we return.
+      if (!continuation()->is_set(BlockBegin::was_visited_flag)) {
+        // add continuation to work list instead of parsing it immediately
+        assert(_last && _last->as_BlockEnd(), "");
+        scope_data()->parent()->add_to_work_list(continuation());
+        _skip_block = true;
+      }
     }
   }
 
@@ -3645,6 +3656,114 @@
 }
 
 
+bool GraphBuilder::for_method_handle_inline(ciMethod* callee) {
+  assert(!callee->is_static(), "change next line");
+  int index = state()->stack_size() - (callee->arg_size_no_receiver() + 1);
+  Value receiver = state()->stack_at(index);
+
+  if (receiver->type()->is_constant()) {
+    ciMethodHandle* method_handle = receiver->type()->as_ObjectType()->constant_value()->as_method_handle();
+
+    // Set the callee to have access to the class and signature in
+    // the MethodHandleCompiler.
+    method_handle->set_callee(callee);
+    method_handle->set_caller(method());
+
+    // Get an adapter for the MethodHandle.
+    ciMethod* method_handle_adapter = method_handle->get_method_handle_adapter();
+    if (method_handle_adapter != NULL) {
+      return try_inline(method_handle_adapter, /*holder_known=*/ true);
+    }
+  } else if (receiver->as_CheckCast()) {
+    // Match MethodHandle.selectAlternative idiom
+    Phi* phi = receiver->as_CheckCast()->obj()->as_Phi();
+
+    if (phi != NULL && phi->operand_count() == 2) {
+      // Get the two MethodHandle inputs from the Phi.
+      Value op1 = phi->operand_at(0);
+      Value op2 = phi->operand_at(1);
+      ciMethodHandle* mh1 = op1->type()->as_ObjectType()->constant_value()->as_method_handle();
+      ciMethodHandle* mh2 = op2->type()->as_ObjectType()->constant_value()->as_method_handle();
+
+      // Set the callee to have access to the class and signature in
+      // the MethodHandleCompiler.
+      mh1->set_callee(callee);
+      mh1->set_caller(method());
+      mh2->set_callee(callee);
+      mh2->set_caller(method());
+
+      // Get adapters for the MethodHandles.
+      ciMethod* mh1_adapter = mh1->get_method_handle_adapter();
+      ciMethod* mh2_adapter = mh2->get_method_handle_adapter();
+
+      if (mh1_adapter != NULL && mh2_adapter != NULL) {
+        set_inline_cleanup_info();
+
+        // Build the If guard
+        BlockBegin* one = new BlockBegin(next_bci());
+        BlockBegin* two = new BlockBegin(next_bci());
+        BlockBegin* end = new BlockBegin(next_bci());
+        Instruction* iff = append(new If(phi, If::eql, false, op1, one, two, NULL, false));
+        block()->set_end(iff->as_BlockEnd());
+
+        // Connect up the states
+        one->merge(block()->end()->state());
+        two->merge(block()->end()->state());
+
+        // Save the state for the second inlinee
+        ValueStack* state_before = copy_state_before();
+
+        // Parse first adapter
+        _last = _block = one;
+        if (!try_inline_full(mh1_adapter, /*holder_known=*/ true, end)) {
+          restore_inline_cleanup_info();
+          block()->clear_end();  // remove appended iff
+          return false;
+        }
+
+        // Parse second adapter
+        _last = _block = two;
+        _state = state_before;
+        if (!try_inline_full(mh2_adapter, /*holder_known=*/ true, end)) {
+          restore_inline_cleanup_info();
+          block()->clear_end();  // remove appended iff
+          return false;
+        }
+
+        connect_to_end(end);
+        return true;
+      }
+    }
+  }
+  return false;
+}
+
+
+bool GraphBuilder::for_invokedynamic_inline(ciMethod* callee) {
+  // Get the MethodHandle from the CallSite.
+  ciCallSite*     call_site     = stream()->get_call_site();
+  ciMethodHandle* method_handle = call_site->get_target();
+
+  // Set the callee to have access to the class and signature in the
+  // MethodHandleCompiler.
+  method_handle->set_callee(callee);
+  method_handle->set_caller(method());
+
+  // Get an adapter for the MethodHandle.
+  ciMethod* method_handle_adapter = method_handle->get_invokedynamic_adapter();
+  if (method_handle_adapter != NULL) {
+    if (try_inline(method_handle_adapter, /*holder_known=*/ true)) {
+      // Add a dependence for invalidation of the optimization.
+      if (!call_site->is_constant_call_site()) {
+        dependency_recorder()->assert_call_site_target_value(call_site, method_handle);
+      }
+      return true;
+    }
+  }
+  return false;
+}
+
+
 void GraphBuilder::inline_bailout(const char* msg) {
   assert(msg != NULL, "inline bailout msg must exist");
   _inline_bailout_msg = msg;
--- a/src/share/vm/c1/c1_GraphBuilder.hpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/c1/c1_GraphBuilder.hpp	Wed Sep 07 11:52:00 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -315,9 +315,17 @@
                                ValueStack* return_state) { scope_data()->set_inline_cleanup_info(block,
                                                                                                   return_prev,
                                                                                                   return_state); }
+  void set_inline_cleanup_info() {
+    set_inline_cleanup_info(_block, _last, _state);
+  }
   BlockBegin*  inline_cleanup_block() const              { return scope_data()->inline_cleanup_block();  }
   Instruction* inline_cleanup_return_prev() const        { return scope_data()->inline_cleanup_return_prev(); }
   ValueStack*  inline_cleanup_state() const              { return scope_data()->inline_cleanup_state();  }
+  void restore_inline_cleanup_info() {
+    _block = inline_cleanup_block();
+    _last  = inline_cleanup_return_prev();
+    _state = inline_cleanup_state();
+  }
   void incr_num_returns()                                { scope_data()->incr_num_returns();             }
   int  num_returns() const                               { return scope_data()->num_returns();           }
   intx max_inline_size() const                           { return scope_data()->max_inline_size();       }
@@ -329,11 +337,15 @@
   void fill_sync_handler(Value lock, BlockBegin* sync_handler, bool default_handler = false);
 
   // inliners
-  bool try_inline(ciMethod* callee, bool holder_known);
+  bool try_inline(           ciMethod* callee, bool holder_known);
   bool try_inline_intrinsics(ciMethod* callee);
-  bool try_inline_full      (ciMethod* callee, bool holder_known);
+  bool try_inline_full(      ciMethod* callee, bool holder_known, BlockBegin* cont_block = NULL);
   bool try_inline_jsr(int jsr_dest_bci);
 
+  // JSR 292 support
+  bool for_method_handle_inline(ciMethod* callee);
+  bool for_invokedynamic_inline(ciMethod* callee);
+
   // helpers
   void inline_bailout(const char* msg);
   BlockBegin* header_block(BlockBegin* entry, BlockBegin::Flag f, ValueStack* state);
--- a/src/share/vm/c1/c1_Instruction.cpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/c1/c1_Instruction.cpp	Wed Sep 07 11:52:00 2011 -0700
@@ -514,28 +514,17 @@
 
 void BlockBegin::set_end(BlockEnd* end) {
   assert(end != NULL, "should not reset block end to NULL");
-  BlockEnd* old_end = _end;
-  if (end == old_end) {
+  if (end == _end) {
     return;
   }
-  // Must make the predecessors/successors match up with the
-  // BlockEnd's notion.
-  int i, n;
-  if (old_end != NULL) {
-    // disconnect from the old end
-    old_end->set_begin(NULL);
+  clear_end();
 
-    // disconnect this block from it's current successors
-    for (i = 0; i < _successors.length(); i++) {
-      _successors.at(i)->remove_predecessor(this);
-    }
-  }
+  // Set the new end
   _end = end;
 
   _successors.clear();
   // Now reset successors list based on BlockEnd
-  n = end->number_of_sux();
-  for (i = 0; i < n; i++) {
+  for (int i = 0; i < end->number_of_sux(); i++) {
     BlockBegin* sux = end->sux_at(i);
     _successors.append(sux);
     sux->_predecessors.append(this);
@@ -544,6 +533,22 @@
 }
 
 
+void BlockBegin::clear_end() {
+  // Must make the predecessors/successors match up with the
+  // BlockEnd's notion.
+  if (_end != NULL) {
+    // disconnect from the old end
+    _end->set_begin(NULL);
+
+    // disconnect this block from it's current successors
+    for (int i = 0; i < _successors.length(); i++) {
+      _successors.at(i)->remove_predecessor(this);
+    }
+    _end = NULL;
+  }
+}
+
+
 void BlockBegin::disconnect_edge(BlockBegin* from, BlockBegin* to) {
   // disconnect any edges between from and to
 #ifndef PRODUCT
--- a/src/share/vm/c1/c1_Instruction.hpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/c1/c1_Instruction.hpp	Wed Sep 07 11:52:00 2011 -0700
@@ -1601,6 +1601,7 @@
   void set_depth_first_number(int dfn)           { _depth_first_number = dfn; }
   void set_linear_scan_number(int lsn)           { _linear_scan_number = lsn; }
   void set_end(BlockEnd* end);
+  void clear_end();
   void disconnect_from_graph();
   static void disconnect_edge(BlockBegin* from, BlockBegin* to);
   BlockBegin* insert_block_between(BlockBegin* sux);
--- a/src/share/vm/c1/c1_LIRAssembler.cpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/c1/c1_LIRAssembler.cpp	Wed Sep 07 11:52:00 2011 -0700
@@ -121,7 +121,7 @@
 
 void LIR_Assembler::check_codespace() {
   CodeSection* cs = _masm->code_section();
-  if (cs->remaining() < (int)(1*K)) {
+  if (cs->remaining() < (int)(NOT_LP64(1*K)LP64_ONLY(2*K))) {
     BAILOUT("CodeBuffer overflow");
   }
 }
--- a/src/share/vm/c1/c1_LIRAssembler.hpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/c1/c1_LIRAssembler.hpp	Wed Sep 07 11:52:00 2011 -0700
@@ -133,7 +133,6 @@
   static bool is_small_constant(LIR_Opr opr);
 
   static LIR_Opr receiverOpr();
-  static LIR_Opr incomingReceiverOpr();
   static LIR_Opr osrBufferPointer();
 
   // stubs
--- a/src/share/vm/c1/c1_LinearScan.cpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/c1/c1_LinearScan.cpp	Wed Sep 07 11:52:00 2011 -0700
@@ -2404,7 +2404,7 @@
       assert(!is_call_site || assigned_reg >= nof_regs || !is_caller_save(assigned_reg), "interval is in a caller-save register at a call -> register will be overwritten");
 
       VMReg name = vm_reg_for_interval(interval);
-      map->set_oop(name);
+      set_oop(map, name);
 
       // Spill optimization: when the stack value is guaranteed to be always correct,
       // then it must be added to the oop map even if the interval is currently in a register
@@ -2415,7 +2415,7 @@
         assert(interval->canonical_spill_slot() >= LinearScan::nof_regs, "no spill slot assigned");
         assert(interval->assigned_reg() < LinearScan::nof_regs, "interval is on stack, so stack slot is registered twice");
 
-        map->set_oop(frame_map()->slot_regname(interval->canonical_spill_slot() - LinearScan::nof_regs));
+        set_oop(map, frame_map()->slot_regname(interval->canonical_spill_slot() - LinearScan::nof_regs));
       }
     }
   }
@@ -2424,7 +2424,7 @@
   assert(info->stack() != NULL, "CodeEmitInfo must always have a stack");
   int locks_count = info->stack()->total_locks_size();
   for (int i = 0; i < locks_count; i++) {
-    map->set_oop(frame_map()->monitor_object_regname(i));
+    set_oop(map, frame_map()->monitor_object_regname(i));
   }
 
   return map;
--- a/src/share/vm/c1/c1_LinearScan.hpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/c1/c1_LinearScan.hpp	Wed Sep 07 11:52:00 2011 -0700
@@ -352,6 +352,13 @@
 
   MonitorValue*  location_for_monitor_index(int monitor_index);
   LocationValue* location_for_name(int name, Location::Type loc_type);
+  void set_oop(OopMap* map, VMReg name) {
+    if (map->legal_vm_reg_name(name)) {
+      map->set_oop(name);
+    } else {
+      bailout("illegal oopMap register name");
+    }
+  }
 
   int append_scope_value_for_constant(LIR_Opr opr, GrowableArray<ScopeValue*>* scope_values);
   int append_scope_value_for_operand(LIR_Opr opr, GrowableArray<ScopeValue*>* scope_values);
--- a/src/share/vm/c1/c1_Runtime1.cpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/c1/c1_Runtime1.cpp	Wed Sep 07 11:52:00 2011 -0700
@@ -375,14 +375,6 @@
 JRT_END
 
 
-JRT_ENTRY(void, Runtime1::post_jvmti_exception_throw(JavaThread* thread))
-  if (JvmtiExport::can_post_on_exceptions()) {
-    vframeStream vfst(thread, true);
-    address bcp = vfst.method()->bcp_from(vfst.bci());
-    JvmtiExport::post_exception_throw(thread, vfst.method(), bcp, thread->exception_oop());
-  }
-JRT_END
-
 // counter_overflow() is called from within C1-compiled methods. The enclosing method is the method
 // associated with the top activation record. The inlinee (that is possibly included in the enclosing
 // method) method oop is passed as an argument. In order to do that it is embedded in the code as
--- a/src/share/vm/c1/c1_Runtime1.hpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/c1/c1_Runtime1.hpp	Wed Sep 07 11:52:00 2011 -0700
@@ -65,7 +65,6 @@
   stub(monitorexit_nofpu)              /* optimized version that does not preserve fpu registers */ \
   stub(access_field_patching)        \
   stub(load_klass_patching)          \
-  stub(jvmti_exception_throw)        \
   stub(g1_pre_barrier_slow)          \
   stub(g1_post_barrier_slow)         \
   stub(fpu2long_stub)                \
@@ -141,7 +140,6 @@
   static void unimplemented_entry   (JavaThread* thread, StubID id);
 
   static address exception_handler_for_pc(JavaThread* thread);
-  static void post_jvmti_exception_throw(JavaThread* thread);
 
   static void throw_range_check_exception(JavaThread* thread, int index);
   static void throw_index_exception(JavaThread* thread, int index);
--- a/src/share/vm/c1/c1_globals.hpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/c1/c1_globals.hpp	Wed Sep 07 11:52:00 2011 -0700
@@ -278,7 +278,7 @@
   product(intx, CompilationRepeat, 0,                                       \
           "Number of times to recompile method before returning result")    \
                                                                             \
-  develop(intx, NMethodSizeLimit, (32*K)*wordSize,                          \
+  develop(intx, NMethodSizeLimit, (64*K)*wordSize,                          \
           "Maximum size of a compiled method.")                             \
                                                                             \
   develop(bool, TraceFPUStack, false,                                       \
--- a/src/share/vm/ci/ciCallProfile.hpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/ci/ciCallProfile.hpp	Wed Sep 07 11:52:00 2011 -0700
@@ -79,6 +79,17 @@
     assert(i < _limit, "out of Call Profile MorphismLimit");
     return _receiver[i];
   }
+
+  // Rescale the current profile based on the incoming scale
+  ciCallProfile rescale(double scale) {
+    assert(scale >= 0 && scale <= 1.0, "out of range");
+    ciCallProfile call = *this;
+    call._count = (int)(call._count * scale);
+    for (int i = 0; i < _morphism; i++) {
+      call._receiver_count[i] = (int)(call._receiver_count[i] * scale);
+    }
+    return call;
+  }
 };
 
 #endif // SHARE_VM_CI_CICALLPROFILE_HPP
--- a/src/share/vm/ci/ciConstant.hpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/ci/ciConstant.hpp	Wed Sep 07 11:52:00 2011 -0700
@@ -46,9 +46,6 @@
     ciObject* _object;
   } _value;
 
-  // Implementation of the print method.
-  void print_impl(outputStream* st);
-
 public:
 
   ciConstant() {
--- a/src/share/vm/ci/ciEnv.cpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/ci/ciEnv.cpp	Wed Sep 07 11:52:00 2011 -0700
@@ -884,19 +884,31 @@
 }
 
 // ------------------------------------------------------------------
-// ciEnv::check_for_system_dictionary_modification
-// Check for changes to the system dictionary during compilation
-// class loads, evolution, breakpoints
-void ciEnv::check_for_system_dictionary_modification(ciMethod* target) {
+// ciEnv::validate_compile_task_dependencies
+//
+// Check for changes during compilation (e.g. class loads, evolution,
+// breakpoints, call site invalidation).
+void ciEnv::validate_compile_task_dependencies(ciMethod* target) {
   if (failing())  return;  // no need for further checks
 
-  // Dependencies must be checked when the system dictionary changes.
-  // If logging is enabled all violated dependences will be recorded in
-  // the log.  In debug mode check dependencies even if the system
-  // dictionary hasn't changed to verify that no invalid dependencies
-  // were inserted.  Any violated dependences in this case are dumped to
-  // the tty.
+  // First, check non-klass dependencies as we might return early and
+  // not check klass dependencies if the system dictionary
+  // modification counter hasn't changed (see below).
+  for (Dependencies::DepStream deps(dependencies()); deps.next(); ) {
+    if (deps.is_klass_type())  continue;  // skip klass dependencies
+    klassOop witness = deps.check_dependency();
+    if (witness != NULL) {
+      record_failure("invalid non-klass dependency");
+      return;
+    }
+  }
 
+  // Klass dependencies must be checked when the system dictionary
+  // changes.  If logging is enabled all violated dependences will be
+  // recorded in the log.  In debug mode check dependencies even if
+  // the system dictionary hasn't changed to verify that no invalid
+  // dependencies were inserted.  Any violated dependences in this
+  // case are dumped to the tty.
   bool counter_changed = system_dictionary_modification_counter_changed();
   bool test_deps = counter_changed;
   DEBUG_ONLY(test_deps = true);
@@ -904,22 +916,21 @@
 
   bool print_failures = false;
   DEBUG_ONLY(print_failures = !counter_changed);
-
   bool keep_going = (print_failures || xtty != NULL);
-
-  int violated = 0;
+  int klass_violations = 0;
 
   for (Dependencies::DepStream deps(dependencies()); deps.next(); ) {
+    if (!deps.is_klass_type())  continue;  // skip non-klass dependencies
     klassOop witness = deps.check_dependency();
     if (witness != NULL) {
-      ++violated;
+      klass_violations++;
       if (print_failures)  deps.print_dependency(witness, /*verbose=*/ true);
-      // If there's no log and we're not sanity-checking, we're done.
-      if (!keep_going)     break;
     }
+    // If there's no log and we're not sanity-checking, we're done.
+    if (!keep_going)  break;
   }
 
-  if (violated != 0) {
+  if (klass_violations != 0) {
     assert(counter_changed, "failed dependencies, but counter didn't change");
     record_failure("concurrent class loading");
   }
@@ -938,7 +949,6 @@
                             ImplicitExceptionTable* inc_table,
                             AbstractCompiler* compiler,
                             int comp_level,
-                            bool has_debug_info,
                             bool has_unsafe_access) {
   VM_ENTRY_MARK;
   nmethod* nm = NULL;
@@ -978,8 +988,8 @@
       // Encode the dependencies now, so we can check them right away.
       dependencies()->encode_content_bytes();
 
-      // Check for {class loads, evolution, breakpoints} during compilation
-      check_for_system_dictionary_modification(target);
+      // Check for {class loads, evolution, breakpoints, ...} during compilation
+      validate_compile_task_dependencies(target);
     }
 
     methodHandle method(THREAD, target->get_methodOop());
@@ -1033,7 +1043,6 @@
         CompileBroker::handle_full_code_cache();
       }
     } else {
-      NOT_PRODUCT(nm->set_has_debug_info(has_debug_info); )
       nm->set_has_unsafe_access(has_unsafe_access);
 
       // Record successful registration.
--- a/src/share/vm/ci/ciEnv.hpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/ci/ciEnv.hpp	Wed Sep 07 11:52:00 2011 -0700
@@ -247,9 +247,9 @@
   // Is this thread currently in the VM state?
   static bool is_in_vm();
 
-  // Helper routine for determining the validity of a compilation
-  // with respect to concurrent class loading.
-  void check_for_system_dictionary_modification(ciMethod* target);
+  // Helper routine for determining the validity of a compilation with
+  // respect to method dependencies (e.g. concurrent class loading).
+  void validate_compile_task_dependencies(ciMethod* target);
 
 public:
   enum {
@@ -317,8 +317,7 @@
                        ImplicitExceptionTable*   inc_table,
                        AbstractCompiler*         compiler,
                        int                       comp_level,
-                       bool                      has_debug_info = true,
-                       bool                      has_unsafe_access = false);
+                       bool                      has_unsafe_access);
 
 
   // Access to certain well known ciObjects.
--- a/src/share/vm/ci/ciField.hpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/ci/ciField.hpp	Wed Sep 07 11:52:00 2011 -0700
@@ -64,9 +64,6 @@
   // shared constructor code
   void initialize_from(fieldDescriptor* fd);
 
-  // The implementation of the print method.
-  void print_impl(outputStream* st);
-
 public:
   ciFlags flags() { return _flags; }
 
@@ -178,7 +175,12 @@
   bool is_volatile    () { return flags().is_volatile(); }
   bool is_transient   () { return flags().is_transient(); }
 
-  bool is_call_site_target() { return ((holder() == CURRENT_ENV->CallSite_klass()) && (name() == ciSymbol::target_name())); }
+  bool is_call_site_target() {
+    ciInstanceKlass* callsite_klass = CURRENT_ENV->CallSite_klass();
+    if (callsite_klass == NULL)
+      return false;
+    return (holder()->is_subclass_of(callsite_klass) && (name() == ciSymbol::target_name()));
+  }
 
   // Debugging output
   void print();
--- a/src/share/vm/ci/ciMethod.cpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/ci/ciMethod.cpp	Wed Sep 07 11:52:00 2011 -0700
@@ -1017,6 +1017,34 @@
 }
 
 // ------------------------------------------------------------------
+// ciMethod::code_size_for_inlining
+//
+// Code size for inlining decisions.
+//
+// Don't fully count method handle adapters against inlining budgets:
+// the metric we use here is the number of call sites in the adapter
+// as they are probably the instructions which generate some code.
+int ciMethod::code_size_for_inlining() {
+  check_is_loaded();
+
+  // Method handle adapters
+  if (is_method_handle_adapter()) {
+    // Count call sites
+    int call_site_count = 0;
+    ciBytecodeStream iter(this);
+    while (iter.next() != ciBytecodeStream::EOBC()) {
+      if (Bytecodes::is_invoke(iter.cur_bc())) {
+        call_site_count++;
+      }
+    }
+    return call_site_count;
+  }
+
+  // Normal method
+  return code_size();
+}
+
+// ------------------------------------------------------------------
 // ciMethod::instructions_size
 //
 // This is a rough metric for "fat" methods, compared before inlining
--- a/src/share/vm/ci/ciMethod.hpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/ci/ciMethod.hpp	Wed Sep 07 11:52:00 2011 -0700
@@ -157,6 +157,9 @@
   int interpreter_invocation_count() const       { check_is_loaded(); return _interpreter_invocation_count; }
   int interpreter_throwout_count() const         { check_is_loaded(); return _interpreter_throwout_count; }
 
+  // Code size for inlining decisions.
+  int code_size_for_inlining();
+
   int comp_level();
   int highest_osr_comp_level();
 
--- a/src/share/vm/ci/ciMethodHandle.cpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/ci/ciMethodHandle.cpp	Wed Sep 07 11:52:00 2011 -0700
@@ -37,7 +37,7 @@
 // ciMethodHandle::get_adapter
 //
 // Return an adapter for this MethodHandle.
-ciMethod* ciMethodHandle::get_adapter_impl(bool is_invokedynamic) const {
+ciMethod* ciMethodHandle::get_adapter_impl(bool is_invokedynamic) {
   VM_ENTRY_MARK;
   Handle h(get_oop());
   methodHandle callee(_callee->get_methodOop());
@@ -73,7 +73,7 @@
 // ciMethodHandle::get_adapter
 //
 // Return an adapter for this MethodHandle.
-ciMethod* ciMethodHandle::get_adapter(bool is_invokedynamic) const {
+ciMethod* ciMethodHandle::get_adapter(bool is_invokedynamic) {
   ciMethod* result = get_adapter_impl(is_invokedynamic);
   if (result) {
     // Fake up the MDO maturity.
@@ -86,11 +86,22 @@
 }
 
 
+#ifndef PRODUCT
 // ------------------------------------------------------------------
-// ciMethodHandle::print_impl
+// ciMethodHandle::print_chain_impl
 //
 // Implementation of the print method.
-void ciMethodHandle::print_impl(outputStream* st) {
-  st->print(" type=");
-  get_oop()->print();
+void ciMethodHandle::print_chain_impl(outputStream* st) {
+  ASSERT_IN_VM;
+  MethodHandleChain::print(get_oop());
 }
+
+
+// ------------------------------------------------------------------
+// ciMethodHandle::print_chain
+//
+// Implementation of the print_chain method.
+void ciMethodHandle::print_chain(outputStream* st) {
+  GUARDED_VM_ENTRY(print_chain_impl(st););
+}
+#endif
--- a/src/share/vm/ci/ciMethodHandle.hpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/ci/ciMethodHandle.hpp	Wed Sep 07 11:52:00 2011 -0700
@@ -37,19 +37,23 @@
   ciMethod*      _callee;
   ciMethod*      _caller;
   ciCallProfile  _profile;
+  ciMethod*      _method_handle_adapter;
+  ciMethod*      _invokedynamic_adapter;
 
   // Return an adapter for this MethodHandle.
-  ciMethod* get_adapter_impl(bool is_invokedynamic) const;
-  ciMethod* get_adapter(     bool is_invokedynamic) const;
+  ciMethod* get_adapter_impl(bool is_invokedynamic);
+  ciMethod* get_adapter(     bool is_invokedynamic);
 
 protected:
-  void print_impl(outputStream* st);
+  void print_chain_impl(outputStream* st) PRODUCT_RETURN;
 
 public:
   ciMethodHandle(instanceHandle h_i) :
     ciInstance(h_i),
     _callee(NULL),
-    _caller(NULL)
+    _caller(NULL),
+    _method_handle_adapter(NULL),
+    _invokedynamic_adapter(NULL)
   {}
 
   // What kind of ciObject is this?
@@ -60,10 +64,22 @@
   void set_call_profile(ciCallProfile profile)  { _profile = profile; }
 
   // Return an adapter for a MethodHandle call.
-  ciMethod* get_method_handle_adapter() const { return get_adapter(false); }
+  ciMethod* get_method_handle_adapter() {
+    if (_method_handle_adapter == NULL) {
+      _method_handle_adapter = get_adapter(false);
+    }
+    return _method_handle_adapter;
+  }
 
   // Return an adapter for an invokedynamic call.
-  ciMethod* get_invokedynamic_adapter() const { return get_adapter(true);  }
+  ciMethod* get_invokedynamic_adapter() {
+    if (_invokedynamic_adapter == NULL) {
+      _invokedynamic_adapter = get_adapter(true);
+    }
+    return _invokedynamic_adapter;
+  }
+
+  void print_chain(outputStream* st = tty) PRODUCT_RETURN;
 };
 
 #endif // SHARE_VM_CI_CIMETHODHANDLE_HPP
--- a/src/share/vm/ci/ciObject.cpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/ci/ciObject.cpp	Wed Sep 07 11:52:00 2011 -0700
@@ -194,16 +194,26 @@
 // ciObject::should_be_constant()
 bool ciObject::should_be_constant() {
   if (ScavengeRootsInCode >= 2)  return true;  // force everybody to be a constant
-  if (!JavaObjectsInPerm && !is_null_object()) {
+  if (is_null_object()) return true;
+
+  ciEnv* env = CURRENT_ENV;
+  if (!JavaObjectsInPerm) {
     // We want Strings and Classes to be embeddable by default since
     // they used to be in the perm world.  Not all Strings used to be
     // embeddable but there's no easy way to distinguish the interned
     // from the regulars ones so just treat them all that way.
-    ciEnv* env = CURRENT_ENV;
     if (klass() == env->String_klass() || klass() == env->Class_klass()) {
       return true;
     }
   }
+  if (EnableInvokeDynamic &&
+      (klass()->is_subclass_of(env->MethodHandle_klass()) ||
+       klass()->is_subclass_of(env->CallSite_klass()))) {
+    assert(ScavengeRootsInCode >= 1, "must be");
+    // We want to treat these aggressively.
+    return true;
+  }
+
   return handle() == NULL || is_perm();
 }
 
--- a/src/share/vm/ci/ciStreams.hpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/ci/ciStreams.hpp	Wed Sep 07 11:52:00 2011 -0700
@@ -129,7 +129,8 @@
   // Return current ByteCode and increment PC to next bytecode, skipping all
   // intermediate constants.  Returns EOBC at end.
   // Expected usage:
-  //     while( (bc = iter.next()) != EOBC() ) { ... }
+  //     ciBytecodeStream iter(m);
+  //     while (iter.next() != ciBytecodeStream::EOBC()) { ... }
   Bytecodes::Code next() {
     _bc_start = _pc;                        // Capture start of bc
     if( _pc >= _end ) return EOBC();        // End-Of-Bytecodes
--- a/src/share/vm/classfile/javaClasses.cpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/classfile/javaClasses.cpp	Wed Sep 07 11:52:00 2011 -0700
@@ -28,6 +28,7 @@
 #include "classfile/vmSymbols.hpp"
 #include "code/debugInfo.hpp"
 #include "code/pcDesc.hpp"
+#include "compiler/compilerOracle.hpp"
 #include "interpreter/interpreter.hpp"
 #include "memory/oopFactory.hpp"
 #include "memory/resourceArea.hpp"
@@ -2323,6 +2324,8 @@
 
 int java_lang_invoke_AdapterMethodHandle::_conversion_offset;
 
+int java_lang_invoke_CountingMethodHandle::_vmcount_offset;
+
 void java_lang_invoke_MethodHandle::compute_offsets() {
   klassOop k = SystemDictionary::MethodHandle_klass();
   if (k != NULL && EnableInvokeDynamic) {
@@ -2371,6 +2374,23 @@
   }
 }
 
+void java_lang_invoke_CountingMethodHandle::compute_offsets() {
+  klassOop k = SystemDictionary::CountingMethodHandle_klass();
+  if (k != NULL && EnableInvokeDynamic) {
+    compute_offset(_vmcount_offset, k, vmSymbols::vmcount_name(), vmSymbols::int_signature(), true);
+  }
+}
+
+int java_lang_invoke_CountingMethodHandle::vmcount(oop mh) {
+  assert(is_instance(mh), "CMH only");
+  return mh->int_field(_vmcount_offset);
+}
+
+void java_lang_invoke_CountingMethodHandle::set_vmcount(oop mh, int count) {
+  assert(is_instance(mh), "CMH only");
+  mh->int_field_put(_vmcount_offset, count);
+}
+
 oop java_lang_invoke_MethodHandle::type(oop mh) {
   return mh->obj_field(_type_offset);
 }
@@ -2674,6 +2694,17 @@
   if (k != NULL) {
     compute_offset(_target_offset, k, vmSymbols::target_name(), vmSymbols::java_lang_invoke_MethodHandle_signature());
   }
+
+  // Disallow compilation of CallSite.setTargetNormal and CallSite.setTargetVolatile
+  // (For C2:  keep this until we have throttling logic for uncommon traps.)
+  if (k != NULL) {
+    instanceKlass* ik = instanceKlass::cast(k);
+    methodOop m_normal   = ik->lookup_method(vmSymbols::setTargetNormal_name(),   vmSymbols::setTarget_signature());
+    methodOop m_volatile = ik->lookup_method(vmSymbols::setTargetVolatile_name(), vmSymbols::setTarget_signature());
+    guarantee(m_normal && m_volatile, "must exist");
+    m_normal->set_not_compilable_quietly();
+    m_volatile->set_not_compilable_quietly();
+  }
 }
 
 oop java_lang_invoke_CallSite::target(oop site) {
@@ -3031,6 +3062,7 @@
     java_lang_invoke_MethodType::compute_offsets();
     java_lang_invoke_MethodTypeForm::compute_offsets();
     java_lang_invoke_CallSite::compute_offsets();
+    java_lang_invoke_CountingMethodHandle::compute_offsets();
   }
   java_security_AccessControlContext::compute_offsets();
   // Initialize reflection classes. The layouts of these classes
--- a/src/share/vm/classfile/javaClasses.hpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/classfile/javaClasses.hpp	Wed Sep 07 11:52:00 2011 -0700
@@ -981,6 +981,34 @@
 };
 
 
+// A simple class that maintains an invocation count
+class java_lang_invoke_CountingMethodHandle: public java_lang_invoke_MethodHandle {
+  friend class JavaClasses;
+
+ private:
+  static int _vmcount_offset;
+  static void compute_offsets();
+
+ public:
+  // Accessors
+  static int            vmcount(oop mh);
+  static void       set_vmcount(oop mh, int count);
+
+  // Testers
+  static bool is_subclass(klassOop klass) {
+    return SystemDictionary::CountingMethodHandle_klass() != NULL &&
+      Klass::cast(klass)->is_subclass_of(SystemDictionary::CountingMethodHandle_klass());
+  }
+  static bool is_instance(oop obj) {
+    return obj != NULL && is_subclass(obj->klass());
+  }
+
+  // Accessors for code generation:
+  static int vmcount_offset_in_bytes()          { return _vmcount_offset; }
+};
+
+
+
 // Interface to java.lang.invoke.MemberName objects
 // (These are a private interface for Java code to query the class hierarchy.)
 
--- a/src/share/vm/classfile/systemDictionary.hpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/classfile/systemDictionary.hpp	Wed Sep 07 11:52:00 2011 -0700
@@ -133,14 +133,14 @@
   template(reflect_Method_klass,         java_lang_reflect_Method,       Pre) \
   template(reflect_Constructor_klass,    java_lang_reflect_Constructor,  Pre) \
                                                                               \
-  /* NOTE: needed too early in bootstrapping process to have checks based on JDK version */ \
-  /* Universe::is_gte_jdk14x_version() is not set up by this point. */        \
-  /* It's okay if this turns out to be NULL in non-1.4 JDKs. */               \
-  template(reflect_MagicAccessorImpl_klass,          sun_reflect_MagicAccessorImpl,  Opt) \
-  template(reflect_MethodAccessorImpl_klass, sun_reflect_MethodAccessorImpl, Opt_Only_JDK14NewRef) \
-  template(reflect_ConstructorAccessorImpl_klass, sun_reflect_ConstructorAccessorImpl, Opt_Only_JDK14NewRef) \
-  template(reflect_DelegatingClassLoader_klass, sun_reflect_DelegatingClassLoader, Opt) \
-  template(reflect_ConstantPool_klass,  sun_reflect_ConstantPool,       Opt_Only_JDK15) \
+  /* NOTE: needed too early in bootstrapping process to have checks based on JDK version */                        \
+  /* Universe::is_gte_jdk14x_version() is not set up by this point. */                                             \
+  /* It's okay if this turns out to be NULL in non-1.4 JDKs. */                                                    \
+  template(reflect_MagicAccessorImpl_klass,          sun_reflect_MagicAccessorImpl,  Opt)                          \
+  template(reflect_MethodAccessorImpl_klass, sun_reflect_MethodAccessorImpl, Opt_Only_JDK14NewRef)                 \
+  template(reflect_ConstructorAccessorImpl_klass, sun_reflect_ConstructorAccessorImpl, Opt_Only_JDK14NewRef)       \
+  template(reflect_DelegatingClassLoader_klass, sun_reflect_DelegatingClassLoader, Opt)                            \
+  template(reflect_ConstantPool_klass,  sun_reflect_ConstantPool,       Opt_Only_JDK15)                            \
   template(reflect_UnsafeStaticFieldAccessorImpl_klass, sun_reflect_UnsafeStaticFieldAccessorImpl, Opt_Only_JDK15) \
                                                                               \
   /* support for dynamic typing; it's OK if these are NULL in earlier JDKs */ \
@@ -155,6 +155,7 @@
   template(BootstrapMethodError_klass,     java_lang_BootstrapMethodError,            Pre_JSR292) \
   template(WrongMethodTypeException_klass, java_lang_invoke_WrongMethodTypeException, Pre_JSR292) \
   template(CallSite_klass,                 java_lang_invoke_CallSite,                 Pre_JSR292) \
+  template(CountingMethodHandle_klass,     java_lang_invoke_CountingMethodHandle,     Opt)        \
   template(ConstantCallSite_klass,         java_lang_invoke_ConstantCallSite,         Pre_JSR292) \
   template(MutableCallSite_klass,          java_lang_invoke_MutableCallSite,          Pre_JSR292) \
   template(VolatileCallSite_klass,         java_lang_invoke_VolatileCallSite,         Pre_JSR292) \
--- a/src/share/vm/classfile/vmSymbols.hpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/classfile/vmSymbols.hpp	Wed Sep 07 11:52:00 2011 -0700
@@ -218,6 +218,7 @@
   template(returnType_name,                           "returnType")                               \
   template(signature_name,                            "signature")                                \
   template(slot_name,                                 "slot")                                     \
+  template(selectAlternative_name,                    "selectAlternative")                        \
                                                                                                   \
   /* Support for annotations (JDK 1.5 and above) */                                               \
                                                                                                   \
@@ -246,9 +247,11 @@
   template(java_lang_invoke_MethodTypeForm_signature, "Ljava/lang/invoke/MethodTypeForm;")        \
   template(java_lang_invoke_MemberName,               "java/lang/invoke/MemberName")              \
   template(java_lang_invoke_MethodHandleNatives,      "java/lang/invoke/MethodHandleNatives")     \
+  template(java_lang_invoke_MethodHandleImpl,         "java/lang/invoke/MethodHandleImpl")        \
   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")      \
+  template(java_lang_invoke_CountingMethodHandle,     "java/lang/invoke/CountingMethodHandle")    \
   /* 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;") \
@@ -258,8 +261,12 @@
   template(linkMethodHandleConstant_signature, "(Ljava/lang/Class;ILjava/lang/Class;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/invoke/MethodHandle;") \
   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(setTargetNormal_name,                      "setTargetNormal")                          \
+  template(setTargetVolatile_name,                    "setTargetVolatile")                        \
+  template(setTarget_signature,                       "(Ljava/lang/invoke/MethodHandle;)V")       \
   NOT_LP64(  do_alias(machine_word_signature,         int_signature)  )                           \
   LP64_ONLY( do_alias(machine_word_signature,         long_signature) )                           \
+  template(selectAlternative_signature, "(ZLjava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodHandle;)Ljava/lang/invoke/MethodHandle;") \
                                                                                                   \
   /* common method and field names */                                                             \
   template(object_initializer_name,                   "<init>")                                   \
@@ -344,6 +351,7 @@
   template(vmmethod_name,                             "vmmethod")                                 \
   template(vmtarget_name,                             "vmtarget")                                 \
   template(vmentry_name,                              "vmentry")                                  \
+  template(vmcount_name,                              "vmcount")                                  \
   template(vmslots_name,                              "vmslots")                                  \
   template(vmlayout_name,                             "vmlayout")                                 \
   template(vmindex_name,                              "vmindex")                                  \
@@ -907,6 +915,8 @@
   do_intrinsic(_invokeVarargs,            java_lang_invoke_MethodHandle, invokeVarargs_name, object_array_object_signature, F_R)  \
   do_intrinsic(_invokeDynamic,            java_lang_invoke_InvokeDynamic, star_name,         object_array_object_signature, F_SN) \
                                                                                                                         \
+  do_intrinsic(_selectAlternative,        java_lang_invoke_MethodHandleImpl, selectAlternative_name, selectAlternative_signature, F_S)  \
+                                                                                                                        \
   /* unboxing methods: */                                                                                               \
   do_intrinsic(_booleanValue,             java_lang_Boolean,      booleanValue_name, void_boolean_signature, F_R)       \
    do_name(     booleanValue_name,       "booleanValue")                                                                \
--- a/src/share/vm/code/dependencies.cpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/code/dependencies.cpp	Wed Sep 07 11:52:00 2011 -0700
@@ -113,9 +113,9 @@
   assert_common_1(no_finalizable_subclasses, ctxk);
 }
 
-void Dependencies::assert_call_site_target_value(ciKlass* ctxk, ciCallSite* call_site, ciMethodHandle* method_handle) {
-  check_ctxk(ctxk);
-  assert_common_3(call_site_target_value, ctxk, call_site, method_handle);
+void Dependencies::assert_call_site_target_value(ciCallSite* call_site, ciMethodHandle* method_handle) {
+  check_ctxk(call_site->klass());
+  assert_common_2(call_site_target_value, call_site, method_handle);
 }
 
 // Helper function.  If we are adding a new dep. under ctxk2,
@@ -135,7 +135,7 @@
   }
 }
 
-void Dependencies::assert_common_1(Dependencies::DepType dept, ciObject* x) {
+void Dependencies::assert_common_1(DepType dept, ciObject* x) {
   assert(dep_args(dept) == 1, "sanity");
   log_dependency(dept, x);
   GrowableArray<ciObject*>* deps = _deps[dept];
@@ -148,21 +148,37 @@
   }
 }
 
-void Dependencies::assert_common_2(Dependencies::DepType dept,
-                                   ciKlass* ctxk, ciObject* x) {
-  assert(dep_context_arg(dept) == 0, "sanity");
+void Dependencies::assert_common_2(DepType dept,
+                                   ciObject* x0, ciObject* x1) {
   assert(dep_args(dept) == 2, "sanity");
-  log_dependency(dept, ctxk, x);
+  log_dependency(dept, x0, x1);
   GrowableArray<ciObject*>* deps = _deps[dept];
 
   // see if the same (or a similar) dep is already recorded
-  if (note_dep_seen(dept, x)) {
-    // look in this bucket for redundant assertions
-    const int stride = 2;
-    for (int i = deps->length(); (i -= stride) >= 0; ) {
-      ciObject* x1 = deps->at(i+1);
-      if (x == x1) {  // same subject; check the context
-        if (maybe_merge_ctxk(deps, i+0, ctxk)) {
+  bool has_ctxk = has_explicit_context_arg(dept);
+  if (has_ctxk) {
+    assert(dep_context_arg(dept) == 0, "sanity");
+    if (note_dep_seen(dept, x1)) {
+      // look in this bucket for redundant assertions
+      const int stride = 2;
+      for (int i = deps->length(); (i -= stride) >= 0; ) {
+        ciObject* y1 = deps->at(i+1);
+        if (x1 == y1) {  // same subject; check the context
+          if (maybe_merge_ctxk(deps, i+0, x0->as_klass())) {
+            return;
+          }
+        }
+      }
+    }
+  } else {
+    assert(dep_implicit_context_arg(dept) == 0, "sanity");
+    if (note_dep_seen(dept, x0) && note_dep_seen(dept, x1)) {
+      // look in this bucket for redundant assertions
+      const int stride = 2;
+      for (int i = deps->length(); (i -= stride) >= 0; ) {
+        ciObject* y0 = deps->at(i+0);
+        ciObject* y1 = deps->at(i+1);
+        if (x0 == y0 && x1 == y1) {
           return;
         }
       }
@@ -170,11 +186,11 @@
   }
 
   // append the assertion in the correct bucket:
-  deps->append(ctxk);
-  deps->append(x);
+  deps->append(x0);
+  deps->append(x1);
 }
 
-void Dependencies::assert_common_3(Dependencies::DepType dept,
+void Dependencies::assert_common_3(DepType dept,
                                    ciKlass* ctxk, ciObject* x, ciObject* x2) {
   assert(dep_context_arg(dept) == 0, "sanity");
   assert(dep_args(dept) == 3, "sanity");
@@ -361,7 +377,7 @@
   3, // unique_concrete_subtypes_2 ctxk, k1, k2
   3, // unique_concrete_methods_2 ctxk, m1, m2
   1, // no_finalizable_subclasses ctxk
-  3  // call_site_target_value ctxk, call_site, method_handle
+  2  // call_site_target_value call_site, method_handle
 };
 
 const char* Dependencies::dep_name(Dependencies::DepType dept) {
@@ -375,10 +391,7 @@
 }
 
 void Dependencies::check_valid_dependency_type(DepType dept) {
-  for (int deptv = (int) FIRST_TYPE; deptv < (int) TYPE_LIMIT; deptv++) {
-    if (dept == ((DepType) deptv))  return;
-  }
-  ShouldNotReachHere();
+  guarantee(FIRST_TYPE <= dept && dept < TYPE_LIMIT, err_msg("invalid dependency type: %d", (int) dept));
 }
 
 // for the sake of the compiler log, print out current dependencies:
@@ -586,8 +599,7 @@
     code_byte -= ctxk_bit;
     DepType dept = (DepType)code_byte;
     _type = dept;
-    guarantee((dept - FIRST_TYPE) < (TYPE_LIMIT - FIRST_TYPE),
-              "bad dependency type tag");
+    Dependencies::check_valid_dependency_type(dept);
     int stride = _dep_args[dept];
     assert(stride == dep_args(dept), "sanity");
     int skipj = -1;
@@ -615,18 +627,35 @@
 
 klassOop Dependencies::DepStream::context_type() {
   assert(must_be_in_vm(), "raw oops here");
-  int ctxkj = dep_context_arg(_type);  // -1 if no context arg
-  if (ctxkj < 0) {
-    return NULL;           // for example, evol_method
-  } else {
-    oop k = recorded_oop_at(_xi[ctxkj]);
-    if (k != NULL) {       // context type was not compressed away
+
+  // Most dependencies have an explicit context type argument.
+  {
+    int ctxkj = dep_context_arg(_type);  // -1 if no explicit context arg
+    if (ctxkj >= 0) {
+      oop k = argument(ctxkj);
+      if (k != NULL) {       // context type was not compressed away
+        assert(k->is_klass(), "type check");
+        return (klassOop) k;
+      }
+      // recompute "default" context type
+      return ctxk_encoded_as_null(_type, argument(ctxkj+1));
+    }
+  }
+
+  // Some dependencies are using the klass of the first object
+  // argument as implicit context type (e.g. call_site_target_value).
+  {
+    int ctxkj = dep_implicit_context_arg(_type);
+    if (ctxkj >= 0) {
+      oop k = argument(ctxkj)->klass();
       assert(k->is_klass(), "type check");
       return (klassOop) k;
-    } else {               // recompute "default" context type
-      return ctxk_encoded_as_null(_type, recorded_oop_at(_xi[ctxkj+1]));
     }
   }
+
+  // And some dependencies don't have a context type at all,
+  // e.g. evol_method.
+  return NULL;
 }
 
 /// Checking dependencies:
@@ -1409,21 +1438,20 @@
 }
 
 
-klassOop Dependencies::check_call_site_target_value(klassOop ctxk, oop call_site, oop method_handle, CallSiteDepChange* changes) {
+klassOop Dependencies::check_call_site_target_value(oop call_site, oop method_handle, CallSiteDepChange* changes) {
   assert(call_site    ->is_a(SystemDictionary::CallSite_klass()),     "sanity");
   assert(method_handle->is_a(SystemDictionary::MethodHandle_klass()), "sanity");
   if (changes == NULL) {
     // Validate all CallSites
     if (java_lang_invoke_CallSite::target(call_site) != method_handle)
-      return ctxk;  // assertion failed
+      return call_site->klass();  // assertion failed
   } else {
     // Validate the given CallSite
     if (call_site == changes->call_site() && java_lang_invoke_CallSite::target(call_site) != changes->method_handle()) {
       assert(method_handle != changes->method_handle(), "must be");
-      return ctxk;  // assertion failed
+      return call_site->klass();  // assertion failed
     }
   }
-  assert(java_lang_invoke_CallSite::target(call_site) == method_handle, "should still be valid");
   return NULL;  // assertion still valid
 }
 
@@ -1488,7 +1516,7 @@
   klassOop witness = NULL;
   switch (type()) {
   case call_site_target_value:
-    witness = check_call_site_target_value(context_type(), argument(1), argument(2), changes);
+    witness = check_call_site_target_value(argument(0), argument(1), changes);
     break;
   default:
     witness = NULL;
--- a/src/share/vm/code/dependencies.hpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/code/dependencies.hpp	Wed Sep 07 11:52:00 2011 -0700
@@ -166,9 +166,14 @@
     LG2_TYPE_LIMIT = 4,  // assert(TYPE_LIMIT <= (1<<LG2_TYPE_LIMIT))
 
     // handy categorizations of dependency types:
-    all_types      = ((1<<TYPE_LIMIT)-1) & ((-1)<<FIRST_TYPE),
-    non_ctxk_types = (1<<evol_method),
-    ctxk_types     = all_types & ~non_ctxk_types,
+    all_types           = ((1 << TYPE_LIMIT) - 1) & ((-1) << FIRST_TYPE),
+
+    non_klass_types     = (1 << call_site_target_value),
+    klass_types         = all_types & ~non_klass_types,
+
+    non_ctxk_types      = (1 << evol_method),
+    implicit_ctxk_types = (1 << call_site_target_value),
+    explicit_ctxk_types = all_types & ~(non_ctxk_types | implicit_ctxk_types),
 
     max_arg_count = 3,   // current maximum number of arguments (incl. ctxk)
 
@@ -184,9 +189,15 @@
 
   static const char* dep_name(DepType dept);
   static int         dep_args(DepType dept);
-  static int  dep_context_arg(DepType dept) {
-    return dept_in_mask(dept, ctxk_types)? 0: -1;
-  }
+
+  static bool is_klass_type(           DepType dept) { return dept_in_mask(dept, klass_types        ); }
+
+  static bool has_explicit_context_arg(DepType dept) { return dept_in_mask(dept, explicit_ctxk_types); }
+  static bool has_implicit_context_arg(DepType dept) { return dept_in_mask(dept, implicit_ctxk_types); }
+
+  static int           dep_context_arg(DepType dept) { return has_explicit_context_arg(dept) ? 0 : -1; }
+  static int  dep_implicit_context_arg(DepType dept) { return has_implicit_context_arg(dept) ? 0 : -1; }
+
   static void check_valid_dependency_type(DepType dept);
 
  private:
@@ -250,8 +261,8 @@
   }
 
   void assert_common_1(DepType dept, ciObject* x);
-  void assert_common_2(DepType dept, ciKlass* ctxk, ciObject* x);
-  void assert_common_3(DepType dept, ciKlass* ctxk, ciObject* x, ciObject* x2);
+  void assert_common_2(DepType dept, ciObject* x0, ciObject* x1);
+  void assert_common_3(DepType dept, ciKlass* ctxk, ciObject* x1, ciObject* x2);
 
  public:
   // Adding assertions to a new dependency set at compile time:
@@ -264,7 +275,7 @@
   void assert_abstract_with_exclusive_concrete_subtypes(ciKlass* ctxk, ciKlass* k1, ciKlass* k2);
   void assert_exclusive_concrete_methods(ciKlass* ctxk, ciMethod* m1, ciMethod* m2);
   void assert_has_no_finalizable_subclasses(ciKlass* ctxk);
-  void assert_call_site_target_value(ciKlass* ctxk, ciCallSite* call_site, ciMethodHandle* method_handle);
+  void assert_call_site_target_value(ciCallSite* call_site, ciMethodHandle* method_handle);
 
   // Define whether a given method or type is concrete.
   // These methods define the term "concrete" as used in this module.
@@ -318,7 +329,7 @@
   static klassOop check_exclusive_concrete_methods(klassOop ctxk, methodOop m1, methodOop m2,
                                                    KlassDepChange* changes = NULL);
   static klassOop check_has_no_finalizable_subclasses(klassOop ctxk, KlassDepChange* changes = NULL);
-  static klassOop check_call_site_target_value(klassOop ctxk, oop call_site, oop method_handle, CallSiteDepChange* changes = NULL);
+  static klassOop check_call_site_target_value(oop call_site, oop method_handle, CallSiteDepChange* changes = NULL);
   // A returned klassOop is NULL if the dependency assertion is still
   // valid.  A non-NULL klassOop is a 'witness' to the assertion
   // failure, a point in the class hierarchy where the assertion has
@@ -455,6 +466,8 @@
     oop argument(int i);         // => recorded_oop_at(argument_index(i))
     klassOop context_type();
 
+    bool is_klass_type()         { return Dependencies::is_klass_type(type()); }
+
     methodOop method_argument(int i) {
       oop x = argument(i);
       assert(x->is_method(), "type");
--- a/src/share/vm/code/nmethod.cpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/code/nmethod.cpp	Wed Sep 07 11:52:00 2011 -0700
@@ -451,7 +451,6 @@
   _stack_traversal_mark       = 0;
   _unload_reported            = false;           // jvmti state
 
-  NOT_PRODUCT(_has_debug_info = false);
 #ifdef ASSERT
   _oops_are_stale             = false;
 #endif
--- a/src/share/vm/code/nmethod.hpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/code/nmethod.hpp	Wed Sep 07 11:52:00 2011 -0700
@@ -191,8 +191,6 @@
 
   jbyte _scavenge_root_state;
 
-  NOT_PRODUCT(bool _has_debug_info; )
-
   // Nmethod Flushing lock. If non-zero, then the nmethod is not removed
   // and is not made into a zombie. However, once the nmethod is made into
   // a zombie, it will be locked one final time if CompiledMethodUnload
@@ -329,11 +327,6 @@
   methodOop method() const                        { return _method; }
   AbstractCompiler* compiler() const              { return _compiler; }
 
-#ifndef PRODUCT
-  bool has_debug_info() const                     { return _has_debug_info; }
-  void set_has_debug_info(bool f)                 { _has_debug_info = false; }
-#endif // NOT PRODUCT
-
   // type info
   bool is_nmethod() const                         { return true; }
   bool is_java_method() const                     { return !method()->is_native(); }
--- a/src/share/vm/code/pcDesc.cpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/code/pcDesc.cpp	Wed Sep 07 11:52:00 2011 -0700
@@ -30,11 +30,10 @@
 #include "memory/resourceArea.hpp"
 
 PcDesc::PcDesc(int pc_offset, int scope_decode_offset, int obj_decode_offset) {
-  assert(sizeof(PcDescFlags) <= 4, "occupies more than a word");
   _pc_offset           = pc_offset;
   _scope_decode_offset = scope_decode_offset;
   _obj_decode_offset   = obj_decode_offset;
-  _flags.word          = 0;
+  _flags               = 0;
 }
 
 address PcDesc::real_pc(const nmethod* code) const {
@@ -44,7 +43,7 @@
 void PcDesc::print(nmethod* code) {
 #ifndef PRODUCT
   ResourceMark rm;
-  tty->print_cr("PcDesc(pc=0x%lx offset=%x bits=%x):", real_pc(code), pc_offset(), _flags.bits);
+  tty->print_cr("PcDesc(pc=0x%lx offset=%x bits=%x):", real_pc(code), pc_offset(), _flags);
 
   if (scope_decode_offset() == DebugInformationRecorder::serialized_null) {
     return;
--- a/src/share/vm/code/pcDesc.hpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/code/pcDesc.hpp	Wed Sep 07 11:52:00 2011 -0700
@@ -39,15 +39,17 @@
   int _scope_decode_offset; // offset for scope in nmethod
   int _obj_decode_offset;
 
-  union PcDescFlags {
-    int word;
-    struct {
-      unsigned int reexecute: 1;
-      unsigned int is_method_handle_invoke: 1;
-      unsigned int return_oop: 1;
-    } bits;
-    bool operator ==(const PcDescFlags& other) { return word == other.word; }
-  } _flags;
+  enum {
+    PCDESC_reexecute               = 1 << 0,
+    PCDESC_is_method_handle_invoke = 1 << 1,
+    PCDESC_return_oop              = 1 << 2
+  };
+
+  int _flags;
+
+  void set_flag(int mask, bool z) {
+    _flags = z ? (_flags | mask) : (_flags & ~mask);
+  }
 
  public:
   int pc_offset() const           { return _pc_offset;   }
@@ -69,8 +71,8 @@
   };
 
   // Flags
-  bool     should_reexecute()              const { return _flags.bits.reexecute; }
-  void set_should_reexecute(bool z)              { _flags.bits.reexecute = z;    }
+  bool     should_reexecute()              const { return (_flags & PCDESC_reexecute) != 0; }
+  void set_should_reexecute(bool z)              { set_flag(PCDESC_reexecute, z); }
 
   // Does pd refer to the same information as pd?
   bool is_same_info(const PcDesc* pd) {
@@ -79,11 +81,11 @@
       _flags == pd->_flags;
   }
 
-  bool     is_method_handle_invoke()       const { return _flags.bits.is_method_handle_invoke;     }
-  void set_is_method_handle_invoke(bool z)       {        _flags.bits.is_method_handle_invoke = z; }
+  bool     is_method_handle_invoke()       const { return (_flags & PCDESC_is_method_handle_invoke) != 0;     }
+  void set_is_method_handle_invoke(bool z)       { set_flag(PCDESC_is_method_handle_invoke, z); }
 
-  bool     return_oop()                    const { return _flags.bits.return_oop;     }
-  void set_return_oop(bool z)                    {        _flags.bits.return_oop = z; }
+  bool     return_oop()                    const { return (_flags & PCDESC_return_oop) != 0;     }
+  void set_return_oop(bool z)                    { set_flag(PCDESC_return_oop, z); }
 
   // Returns the real pc
   address real_pc(const nmethod* code) const;
--- a/src/share/vm/gc_interface/collectedHeap.cpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/gc_interface/collectedHeap.cpp	Wed Sep 07 11:52:00 2011 -0700
@@ -157,8 +157,14 @@
     // ..and clear it.
     Copy::zero_to_words(obj, new_tlab_size);
   } else {
-    // ...and clear just the allocated object.
-    Copy::zero_to_words(obj, size);
+    // ...and zap just allocated object.
+#ifdef ASSERT
+    // Skip mangling the space corresponding to the object header to
+    // ensure that the returned space is not considered parsable by
+    // any concurrent GC thread.
+    size_t hdr_size = oopDesc::header_size();
+    Copy::fill_to_words(obj + hdr_size, new_tlab_size - hdr_size, badHeapWordVal);
+#endif // ASSERT
   }
   thread->tlab().fill(obj, obj + size, new_tlab_size);
   return obj;
--- a/src/share/vm/gc_interface/collectedHeap.inline.hpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/gc_interface/collectedHeap.inline.hpp	Wed Sep 07 11:52:00 2011 -0700
@@ -287,7 +287,10 @@
   assert(size >= 0, "int won't convert to size_t");
   HeapWord* obj = common_permanent_mem_allocate_init(size, CHECK_NULL);
   post_allocation_setup_no_klass_install(klass, obj, size);
-  NOT_PRODUCT(Universe::heap()->check_for_bad_heap_word_value(obj, size));
+#ifndef PRODUCT
+  const size_t hs = oopDesc::header_size();
+  Universe::heap()->check_for_bad_heap_word_value(obj+hs, size-hs);
+#endif
   return (oop)obj;
 }
 
--- a/src/share/vm/interpreter/bytecodes.hpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/interpreter/bytecodes.hpp	Wed Sep 07 11:52:00 2011 -0700
@@ -419,6 +419,8 @@
 
   static bool        is_zero_const  (Code code)    { return (code == _aconst_null || code == _iconst_0
                                                            || code == _fconst_0 || code == _dconst_0); }
+  static bool        is_invoke      (Code code)    { return (_invokevirtual <= code && code <= _invokedynamic); }
+
   static int         compute_flags  (const char* format, int more_flags = 0);  // compute the flags
   static int         flags          (int code, bool is_wide) {
     assert(code == (u_char)code, "must be a byte");
--- a/src/share/vm/interpreter/interpreterRuntime.cpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/interpreter/interpreterRuntime.cpp	Wed Sep 07 11:52:00 2011 -0700
@@ -555,7 +555,7 @@
     assert(method_handle->is_a(SystemDictionary::MethodHandle_klass()), "must be");
 
     {
-      // Walk all nmethods depending on CallSite
+      // Walk all nmethods depending on this call site.
       MutexLocker mu(Compile_lock, thread);
       Universe::flush_dependents_on(call_site, method_handle);
     }
--- a/src/share/vm/memory/universe.cpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/memory/universe.cpp	Wed Sep 07 11:52:00 2011 -0700
@@ -1203,12 +1203,12 @@
   // Compute the dependent nmethods that have a reference to a
   // CallSite object.  We use instanceKlass::mark_dependent_nmethod
   // directly instead of CodeCache::mark_for_deoptimization because we
-  // want dependents on the class CallSite only not all classes in the
-  // ContextStream.
+  // want dependents on the call site class only not all classes in
+  // the ContextStream.
   int marked = 0;
   {
     MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
-    instanceKlass* call_site_klass = instanceKlass::cast(SystemDictionary::CallSite_klass());
+    instanceKlass* call_site_klass = instanceKlass::cast(call_site->klass());
     marked = call_site_klass->mark_dependent_nmethods(changes);
   }
   if (marked > 0) {
--- a/src/share/vm/oops/constMethodKlass.cpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/oops/constMethodKlass.cpp	Wed Sep 07 11:52:00 2011 -0700
@@ -172,11 +172,6 @@
 int constMethodKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) {
   assert(obj->is_constMethod(), "should be constMethod");
   constMethodOop cm_oop = constMethodOop(obj);
-#if 0
-  PSParallelCompact::adjust_pointer(cm_oop->adr_method());
-  PSParallelCompact::adjust_pointer(cm_oop->adr_exception_table());
-  PSParallelCompact::adjust_pointer(cm_oop->adr_stackmap_data());
-#endif
   oop* const beg_oop = cm_oop->oop_block_beg();
   oop* const end_oop = cm_oop->oop_block_end();
   for (oop* cur_oop = beg_oop; cur_oop < end_oop; ++cur_oop) {
--- a/src/share/vm/oops/cpCacheKlass.cpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/oops/cpCacheKlass.cpp	Wed Sep 07 11:52:00 2011 -0700
@@ -63,8 +63,10 @@
   //   CollectedHeap::permanent_obj_allocate(klass, size, CHECK_NULL);
 
   oop obj = CollectedHeap::permanent_obj_allocate_no_klass_install(klass, size, CHECK_NULL);
-  NOT_PRODUCT(Universe::heap()->check_for_bad_heap_word_value((HeapWord*) obj,
-                                                              size));
+#ifndef PRODUCT
+  const size_t hs = oopDesc::header_size();
+  Universe::heap()->check_for_bad_heap_word_value(((HeapWord*) obj)+hs, size-hs);
+#endif
   constantPoolCacheOop cache = (constantPoolCacheOop) obj;
   assert(!UseConcMarkSweepGC || obj->klass_or_null() == NULL,
          "klass should be NULL here when using CMS");
--- a/src/share/vm/oops/methodDataOop.hpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/oops/methodDataOop.hpp	Wed Sep 07 11:52:00 2011 -0700
@@ -600,6 +600,11 @@
   uint taken() {
     return uint_at(taken_off_set);
   }
+
+  void set_taken(uint cnt) {
+    set_uint_at(taken_off_set, cnt);
+  }
+
   // Saturating counter
   uint inc_taken() {
     uint cnt = taken() + 1;
@@ -926,6 +931,10 @@
     return uint_at(not_taken_off_set);
   }
 
+  void set_not_taken(uint cnt) {
+    set_uint_at(not_taken_off_set, cnt);
+  }
+
   uint inc_not_taken() {
     uint cnt = not_taken() + 1;
     // Did we wrap? Will compiler screw us??
--- a/src/share/vm/oops/methodOop.cpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/oops/methodOop.cpp	Wed Sep 07 11:52:00 2011 -0700
@@ -914,6 +914,7 @@
                                                Symbol* name,
                                                Symbol* signature,
                                                Handle method_type, TRAPS) {
+  ResourceMark rm;
   methodHandle empty;
 
   assert(holder() == SystemDictionary::MethodHandle_klass(),
--- a/src/share/vm/opto/bytecodeInfo.cpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/opto/bytecodeInfo.cpp	Wed Sep 07 11:52:00 2011 -0700
@@ -45,7 +45,7 @@
   _method(callee),
   _site_invoke_ratio(site_invoke_ratio),
   _max_inline_level(max_inline_level),
-  _count_inline_bcs(method()->code_size())
+  _count_inline_bcs(method()->code_size_for_inlining())
 {
   NOT_PRODUCT(_count_inlines = 0;)
   if (_caller_jvms != NULL) {
@@ -107,7 +107,7 @@
 
   // positive filter: should send be inlined?  returns NULL (--> yes)
   // or rejection msg
-  int size = callee_method->code_size();
+  int size = callee_method->code_size_for_inlining();
 
   // Check for too many throws (and not too huge)
   if(callee_method->interpreter_throwout_count() > InlineThrowCount &&
@@ -141,7 +141,21 @@
     assert(mha_profile, "must exist");
     CounterData* cd = mha_profile->as_CounterData();
     invoke_count = cd->count();
-    call_site_count = invoke_count;  // use the same value
+    if (invoke_count == 0) {
+      return "method handle not reached";
+    }
+
+    if (_caller_jvms != NULL && _caller_jvms->method() != NULL &&
+        _caller_jvms->method()->method_data() != NULL &&
+        !_caller_jvms->method()->method_data()->is_empty()) {
+      ciMethodData* mdo = _caller_jvms->method()->method_data();
+      ciProfileData* mha_profile = mdo->bci_to_data(_caller_jvms->bci());
+      assert(mha_profile, "must exist");
+      CounterData* cd = mha_profile->as_CounterData();
+      call_site_count = cd->count();
+    } else {
+      call_site_count = invoke_count;  // use the same value
+    }
   }
 
   assert(invoke_count != 0, "require invocation count greater than zero");
@@ -244,7 +258,7 @@
   }
 
   // use frequency-based objections only for non-trivial methods
-  if (callee_method->code_size() <= MaxTrivialSize) return NULL;
+  if (callee_method->code_size_for_inlining() <= MaxTrivialSize) return NULL;
 
   // don't use counts with -Xcomp or CTW
   if (UseInterpreter && !CompileTheWorld) {
@@ -305,7 +319,7 @@
   }
 
   // suppress a few checks for accessors and trivial methods
-  if (callee_method->code_size() > MaxTrivialSize) {
+  if (callee_method->code_size_for_inlining() > MaxTrivialSize) {
 
     // don't inline into giant methods
     if (C->unique() > (uint)NodeCountInliningCutoff) {
@@ -349,7 +363,7 @@
     }
   }
 
-  int size = callee_method->code_size();
+  int size = callee_method->code_size_for_inlining();
 
   if (UseOldInlining && ClipInlining
       && (int)count_inline_bcs() + size >= DesiredMethodLimit) {
@@ -394,6 +408,16 @@
   return true;
 }
 
+//------------------------------check_can_parse--------------------------------
+const char* InlineTree::check_can_parse(ciMethod* callee) {
+  // Certain methods cannot be parsed at all:
+  if ( callee->is_native())                     return "native method";
+  if (!callee->can_be_compiled())               return "not compilable (disabled)";
+  if (!callee->has_balanced_monitors())         return "not compilable (unbalanced monitors)";
+  if ( callee->get_flow_analysis()->failing())  return "not compilable (flow analysis failed)";
+  return NULL;
+}
+
 //------------------------------print_inlining---------------------------------
 // Really, the failure_msg can be a success message also.
 void InlineTree::print_inlining(ciMethod* callee_method, int caller_bci, const char* failure_msg) const {
@@ -423,14 +447,22 @@
   int         caller_bci    = jvms->bci();
   ciMethod   *caller_method = jvms->method();
 
-  if( !pass_initial_checks(caller_method, caller_bci, callee_method)) {
-    if( PrintInlining ) {
+  // Do some initial checks.
+  if (!pass_initial_checks(caller_method, caller_bci, callee_method)) {
+    if (PrintInlining) {
       failure_msg = "failed_initial_checks";
-      print_inlining( callee_method, caller_bci, failure_msg);
+      print_inlining(callee_method, caller_bci, failure_msg);
     }
     return NULL;
   }
 
+  // Do some parse checks.
+  failure_msg = check_can_parse(callee_method);
+  if (failure_msg != NULL) {
+    if (PrintInlining)  print_inlining(callee_method, caller_bci, failure_msg);
+    return NULL;
+  }
+
   // Check if inlining policy says no.
   WarmCallInfo wci = *(initial_wci);
   failure_msg = try_to_inline(callee_method, caller_method, caller_bci, profile, &wci);
@@ -471,7 +503,7 @@
     if (failure_msg == NULL)  failure_msg = "inline (hot)";
 
     // Inline!
-    if( PrintInlining ) print_inlining( callee_method, caller_bci, failure_msg);
+    if (PrintInlining)  print_inlining(callee_method, caller_bci, failure_msg);
     if (UseOldInlining)
       build_inline_tree_for_callee(callee_method, jvms, caller_bci);
     if (InlineWarmCalls && !wci.is_hot())
@@ -481,7 +513,7 @@
 
   // Do not inline
   if (failure_msg == NULL)  failure_msg = "too cold to inline";
-  if( PrintInlining ) print_inlining( callee_method, caller_bci, failure_msg);
+  if (PrintInlining)  print_inlining(callee_method, caller_bci, failure_msg);
   return NULL;
 }
 
--- a/src/share/vm/opto/callGenerator.cpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/opto/callGenerator.cpp	Wed Sep 07 11:52:00 2011 -0700
@@ -61,12 +61,9 @@
   {
     _is_osr        = is_osr;
     _expected_uses = expected_uses;
-    assert(can_parse(method, is_osr), "parse must be possible");
+    assert(InlineTree::check_can_parse(method) == NULL, "parse must be possible");
   }
 
-  // Can we build either an OSR or a regular parser for this method?
-  static bool can_parse(ciMethod* method, int is_osr = false);
-
   virtual bool      is_parse() const           { return true; }
   virtual JVMState* generate(JVMState* jvms);
   int is_osr() { return _is_osr; }
@@ -152,7 +149,6 @@
     call->set_optimized_virtual(true);
     if (method()->is_method_handle_invoke()) {
       call->set_method_handle_invoke(true);
-      kit.C->set_has_method_handle_invokes(true);
     }
   }
   kit.set_arguments_for_java_call(call);
@@ -210,7 +206,6 @@
   call->set_optimized_virtual(true);
   // Take extra care (in the presence of argument motion) not to trash the SP:
   call->set_method_handle_invoke(true);
-  kit.C->set_has_method_handle_invokes(true);
 
   // Pass the target MethodHandle as first argument and shift the
   // other arguments.
@@ -303,20 +298,8 @@
   return kit.transfer_exceptions_into_jvms();
 }
 
-bool ParseGenerator::can_parse(ciMethod* m, int entry_bci) {
-  // Certain methods cannot be parsed at all:
-  if (!m->can_be_compiled())              return false;
-  if (!m->has_balanced_monitors())        return false;
-  if (m->get_flow_analysis()->failing())  return false;
-
-  // (Methods may bail out for other reasons, after the parser is run.
-  // We try to avoid this, but if forced, we must return (Node*)NULL.
-  // The user of the CallGenerator must check for this condition.)
-  return true;
-}
-
 CallGenerator* CallGenerator::for_inline(ciMethod* m, float expected_uses) {
-  if (!ParseGenerator::can_parse(m))  return NULL;
+  if (InlineTree::check_can_parse(m) != NULL)  return NULL;
   return new ParseGenerator(m, expected_uses);
 }
 
@@ -324,7 +307,7 @@
 // for the method execution already in progress, not just the JVMS
 // of the caller.  Thus, this CallGenerator cannot be mixed with others!
 CallGenerator* CallGenerator::for_osr(ciMethod* m, int osr_bci) {
-  if (!ParseGenerator::can_parse(m, true))  return NULL;
+  if (InlineTree::check_can_parse(m) != NULL)  return NULL;
   float past_uses = m->interpreter_invocation_count();
   float expected_uses = past_uses;
   return new ParseGenerator(m, expected_uses, true);
@@ -336,7 +319,7 @@
 }
 
 CallGenerator* CallGenerator::for_dynamic_call(ciMethod* m) {
-  assert(m->is_method_handle_invoke(), "for_dynamic_call mismatch");
+  assert(m->is_method_handle_invoke() || m->is_method_handle_adapter(), "for_dynamic_call mismatch");
   return new DynamicCallGenerator(m);
 }
 
@@ -715,24 +698,36 @@
     // Get an adapter for the MethodHandle.
     ciMethod* target_method = method_handle->get_method_handle_adapter();
     if (target_method != NULL) {
-      CallGenerator* hit_cg = Compile::current()->call_generator(target_method, -1, false, jvms, true, 1);
-      if (hit_cg != NULL && hit_cg->is_inline())
-        return hit_cg;
+      CallGenerator* cg = Compile::current()->call_generator(target_method, -1, false, jvms, true, PROB_ALWAYS);
+      if (cg != NULL && cg->is_inline())
+        return cg;
     }
   } else if (method_handle->Opcode() == Op_Phi && method_handle->req() == 3 &&
              method_handle->in(1)->Opcode() == Op_ConP && method_handle->in(2)->Opcode() == Op_ConP) {
+    float prob = PROB_FAIR;
+    Node* meth_region = method_handle->in(0);
+    if (meth_region->is_Region() &&
+        meth_region->in(1)->is_Proj() && meth_region->in(2)->is_Proj() &&
+        meth_region->in(1)->in(0) == meth_region->in(2)->in(0) &&
+        meth_region->in(1)->in(0)->is_If()) {
+      // If diamond, so grab the probability of the test to drive the inlining below
+      prob = meth_region->in(1)->in(0)->as_If()->_prob;
+      if (meth_region->in(1)->is_IfTrue()) {
+        prob = 1 - prob;
+      }
+    }
+
     // selectAlternative idiom merging two constant MethodHandles.
     // Generate a guard so that each can be inlined.  We might want to
     // do more inputs at later point but this gets the most common
     // case.
-    const TypeOopPtr* oop_ptr = method_handle->in(1)->bottom_type()->is_oopptr();
-    ciObject* const_oop = oop_ptr->const_oop();
-    ciMethodHandle* mh = const_oop->as_method_handle();
-
-    CallGenerator* cg1 = for_method_handle_inline(method_handle->in(1), jvms, caller, callee, profile);
-    CallGenerator* cg2 = for_method_handle_inline(method_handle->in(2), jvms, caller, callee, profile);
+    CallGenerator* cg1 = for_method_handle_inline(method_handle->in(1), jvms, caller, callee, profile.rescale(1.0 - prob));
+    CallGenerator* cg2 = for_method_handle_inline(method_handle->in(2), jvms, caller, callee, profile.rescale(prob));
     if (cg1 != NULL && cg2 != NULL) {
-      return new PredictedDynamicCallGenerator(mh, cg2, cg1, PROB_FAIR);
+      const TypeOopPtr* oop_ptr = method_handle->in(1)->bottom_type()->is_oopptr();
+      ciObject* const_oop = oop_ptr->const_oop();
+      ciMethodHandle* mh = const_oop->as_method_handle();
+      return new PredictedDynamicCallGenerator(mh, cg2, cg1, prob);
     }
   }
   return NULL;
@@ -741,7 +736,6 @@
 
 CallGenerator* CallGenerator::for_invokedynamic_inline(ciCallSite* call_site, JVMState* jvms,
                                                        ciMethod* caller, ciMethod* callee, ciCallProfile profile) {
-  assert(call_site->is_constant_call_site() || call_site->is_mutable_call_site(), "must be");
   ciMethodHandle* method_handle = call_site->get_target();
 
   // Set the callee to have access to the class and signature in the
@@ -754,13 +748,13 @@
   ciMethod* target_method = method_handle->get_invokedynamic_adapter();
   if (target_method != NULL) {
     Compile *C = Compile::current();
-    CallGenerator* hit_cg = C->call_generator(target_method, -1, false, jvms, true, PROB_ALWAYS);
-    if (hit_cg != NULL && hit_cg->is_inline()) {
+    CallGenerator* cg = C->call_generator(target_method, -1, false, jvms, true, PROB_ALWAYS);
+    if (cg != NULL && cg->is_inline()) {
       // Add a dependence for invalidation of the optimization.
-      if (call_site->is_mutable_call_site()) {
-        C->dependencies()->assert_call_site_target_value(C->env()->CallSite_klass(), call_site, method_handle);
+      if (!call_site->is_constant_call_site()) {
+        C->dependencies()->assert_call_site_target_value(call_site, method_handle);
       }
-      return hit_cg;
+      return cg;
     }
   }
   return NULL;
--- a/src/share/vm/opto/compile.cpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/opto/compile.cpp	Wed Sep 07 11:52:00 2011 -0700
@@ -817,7 +817,6 @@
                            &_handler_table, &_inc_table,
                            compiler,
                            env()->comp_level(),
-                           true, /*has_debug_info*/
                            has_unsafe_access()
                            );
   }
--- a/src/share/vm/opto/connode.hpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/opto/connode.hpp	Wed Sep 07 11:52:00 2011 -0700
@@ -496,14 +496,6 @@
   virtual bool depends_only_on_test() const { return false; }
 };
 
-//------------------------------MemMoveNode------------------------------------
-// Memory to memory move.  Inserted very late, after allocation.
-class MemMoveNode : public Node {
-public:
-  MemMoveNode( Node *dst, Node *src ) : Node(0,dst,src) {}
-  virtual int Opcode() const;
-};
-
 //------------------------------ThreadLocalNode--------------------------------
 // Ideal Node which returns the base of ThreadLocalStorage.
 class ThreadLocalNode : public Node {
--- a/src/share/vm/opto/doCall.cpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/opto/doCall.cpp	Wed Sep 07 11:52:00 2011 -0700
@@ -136,15 +136,9 @@
       str.force_bci(jvms->bci());  // Set the stream to the invokedynamic bci.
       ciCallSite* call_site = str.get_call_site();
 
-      // Inline constant and mutable call sites.  We don't inline
-      // volatile call sites optimistically since they are specified
-      // to change their value often and that would result in a lot of
-      // deoptimizations and recompiles.
-      if (call_site->is_constant_call_site() || call_site->is_mutable_call_site()) {
-        CallGenerator* cg = CallGenerator::for_invokedynamic_inline(call_site, jvms, caller, call_method, profile);
-        if (cg != NULL) {
-          return cg;
-        }
+      CallGenerator* cg = CallGenerator::for_invokedynamic_inline(call_site, jvms, caller, call_method, profile);
+      if (cg != NULL) {
+        return cg;
       }
       // If something failed, generate a normal dynamic call.
       return CallGenerator::for_dynamic_call(call_method);
--- a/src/share/vm/opto/idealGraphPrinter.cpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/opto/idealGraphPrinter.cpp	Wed Sep 07 11:52:00 2011 -0700
@@ -375,9 +375,9 @@
   return (intptr_t)(n);
 }
 
-void IdealGraphPrinter::visit_node(Node *n, void *param) {
+void IdealGraphPrinter::visit_node(Node *n, bool edges, VectorSet* temp_set) {
 
-  if(param) {
+  if (edges) {
 
     // Output edge
     intptr_t dest_id = get_node_id(n);
@@ -599,16 +599,11 @@
 
 #ifdef ASSERT
     if (node->debug_orig() != NULL) {
+      temp_set->Clear();
       stringStream dorigStream;
       Node* dorig = node->debug_orig();
-      if (dorig) {
+      while (dorig && temp_set->test_set(dorig->_idx)) {
         dorigStream.print("%d ", dorig->_idx);
-        Node* first = dorig;
-        dorig = first->debug_orig();
-        while (dorig && dorig != first) {
-          dorigStream.print("%d ", dorig->_idx);
-          dorig = dorig->debug_orig();
-        }
       }
       print_prop("debug_orig", dorigStream.as_string());
     }
@@ -629,7 +624,7 @@
   }
 }
 
-void IdealGraphPrinter::walk_nodes(Node *start, void *param) {
+void IdealGraphPrinter::walk_nodes(Node *start, bool edges, VectorSet* temp_set) {
 
 
   VectorSet visited(Thread::current()->resource_area());
@@ -650,7 +645,7 @@
   while(nodeStack.length() > 0) {
 
     Node *n = nodeStack.pop();
-    visit_node(n, param);
+    visit_node(n, edges, temp_set);
 
     if (_traverse_outs) {
       for (DUIterator i = n->outs(); n->has_out(i); i++) {
@@ -689,12 +684,14 @@
   print_attr(GRAPH_NAME_PROPERTY, (const char *)name);
   end_head();
 
+  VectorSet temp_set(Thread::current()->resource_area());
+
   head(NODES_ELEMENT);
-  walk_nodes(node, NULL);
+  walk_nodes(node, false, &temp_set);
   tail(NODES_ELEMENT);
 
   head(EDGES_ELEMENT);
-  walk_nodes(node, (void *)1);
+  walk_nodes(node, true, &temp_set);
   tail(EDGES_ELEMENT);
   if (C->cfg() != NULL) {
     head(CONTROL_FLOW_ELEMENT);
--- a/src/share/vm/opto/idealGraphPrinter.hpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/opto/idealGraphPrinter.hpp	Wed Sep 07 11:52:00 2011 -0700
@@ -104,8 +104,8 @@
   void print_indent();
   void print_method(ciMethod *method, int bci, InlineTree *tree);
   void print_inline_tree(InlineTree *tree);
-  void visit_node(Node *n, void *param);
-  void walk_nodes(Node *start, void *param);
+  void visit_node(Node *n, bool edges, VectorSet* temp_set);
+  void walk_nodes(Node *start, bool edges, VectorSet* temp_set);
   void begin_elem(const char *s);
   void end_elem();
   void begin_head(const char *s);
--- a/src/share/vm/opto/matcher.cpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/opto/matcher.cpp	Wed Sep 07 11:52:00 2011 -0700
@@ -501,6 +501,12 @@
      idealreg2spillmask[Op_RegP]->OR(*idealreg2regmask[Op_RegD]);
 #else
      idealreg2spillmask[Op_RegP]->OR(*idealreg2regmask[Op_RegF]);
+#ifdef ARM
+     // ARM has support for moving 64bit values between a pair of
+     // integer registers and a double register
+     idealreg2spillmask[Op_RegL]->OR(*idealreg2regmask[Op_RegD]);
+     idealreg2spillmask[Op_RegD]->OR(*idealreg2regmask[Op_RegL]);
+#endif
 #endif
    }
 
@@ -1106,6 +1112,9 @@
       mcall_java->_optimized_virtual = call_java->is_optimized_virtual();
       is_method_handle_invoke = call_java->is_method_handle_invoke();
       mcall_java->_method_handle_invoke = is_method_handle_invoke;
+      if (is_method_handle_invoke) {
+        C->set_has_method_handle_invokes(true);
+      }
       if( mcall_java->is_MachCallStaticJava() )
         mcall_java->as_MachCallStaticJava()->_name =
          call_java->as_CallStaticJava()->_name;
--- a/src/share/vm/opto/memnode.cpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/opto/memnode.cpp	Wed Sep 07 11:52:00 2011 -0700
@@ -1493,6 +1493,7 @@
   if (tp == NULL || tp->empty())  return Type::TOP;
   int off = tp->offset();
   assert(off != Type::OffsetTop, "case covered by TypePtr::empty");
+  Compile* C = phase->C;
 
   // Try to guess loaded type from pointer type
   if (tp->base() == Type::AryPtr) {
@@ -1536,7 +1537,7 @@
           Node* base = adr->in(AddPNode::Base);
           if (base != NULL &&
               !phase->type(base)->higher_equal(TypePtr::NULL_PTR)) {
-            Compile::AliasType* atp = phase->C->alias_type(base->adr_type());
+            Compile::AliasType* atp = C->alias_type(base->adr_type());
             if (is_autobox_cache(atp)) {
               return jt->join(TypePtr::NOTNULL)->is_ptr();
             }
@@ -1546,22 +1547,23 @@
       }
     }
   } else if (tp->base() == Type::InstPtr) {
+    ciEnv* env = C->env();
     const TypeInstPtr* tinst = tp->is_instptr();
     ciKlass* klass = tinst->klass();
     assert( off != Type::OffsetBot ||
             // arrays can be cast to Objects
             tp->is_oopptr()->klass()->is_java_lang_Object() ||
             // unsafe field access may not have a constant offset
-            phase->C->has_unsafe_access(),
+            C->has_unsafe_access(),
             "Field accesses must be precise" );
     // For oop loads, we expect the _type to be precise
-    if (klass == phase->C->env()->String_klass() &&
+    if (klass == env->String_klass() &&
         adr->is_AddP() && off != Type::OffsetBot) {
       // For constant Strings treat the final fields as compile time constants.
       Node* base = adr->in(AddPNode::Base);
       const TypeOopPtr* t = phase->type(base)->isa_oopptr();
       if (t != NULL && t->singleton()) {
-        ciField* field = phase->C->env()->String_klass()->get_field_by_offset(off, false);
+        ciField* field = env->String_klass()->get_field_by_offset(off, false);
         if (field != NULL && field->is_final()) {
           ciObject* string = t->const_oop();
           ciConstant constant = string->as_instance()->field_value(field);
@@ -1577,6 +1579,32 @@
         }
       }
     }
+    // Optimizations for constant objects
+    ciObject* const_oop = tinst->const_oop();
+    if (const_oop != NULL) {
+      // For constant CallSites treat the target field as a compile time constant.
+      if (const_oop->is_call_site()) {
+        ciCallSite* call_site = const_oop->as_call_site();
+        ciField* field = call_site->klass()->as_instance_klass()->get_field_by_offset(off, /*is_static=*/ false);
+        if (field != NULL && field->is_call_site_target()) {
+          ciMethodHandle* target = call_site->get_target();
+          if (target != NULL) {  // just in case
+            ciConstant constant(T_OBJECT, target);
+            const Type* t;
+            if (adr->bottom_type()->is_ptr_to_narrowoop()) {
+              t = TypeNarrowOop::make_from_constant(constant.as_object(), true);
+            } else {
+              t = TypeOopPtr::make_from_constant(constant.as_object(), true);
+            }
+            // Add a dependence for invalidation of the optimization.
+            if (!call_site->is_constant_call_site()) {
+              C->dependencies()->assert_call_site_target_value(call_site, target);
+            }
+            return t;
+          }
+        }
+      }
+    }
   } else if (tp->base() == Type::KlassPtr) {
     assert( off != Type::OffsetBot ||
             // arrays can be cast to Objects
--- a/src/share/vm/opto/parse.hpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/opto/parse.hpp	Wed Sep 07 11:52:00 2011 -0700
@@ -78,6 +78,8 @@
   int         stack_depth()       const { return _caller_jvms ? _caller_jvms->depth() : 0; }
 
 public:
+  static const char* check_can_parse(ciMethod* callee);
+
   static InlineTree* build_inline_tree_root();
   static InlineTree* find_subtree_from_root(InlineTree* root, JVMState* jvms, ciMethod* callee, bool create_if_not_found = false);
 
--- a/src/share/vm/opto/parse2.cpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/opto/parse2.cpp	Wed Sep 07 11:52:00 2011 -0700
@@ -752,20 +752,12 @@
 // Handle ret bytecode
 void Parse::do_ret() {
   // Find to whom we return.
-#if 0 // %%%% MAKE THIS WORK
-  Node* con = local();
-  const TypePtr* tp = con->bottom_type()->isa_ptr();
-  assert(tp && tp->singleton(), "");
-  int return_bci = (int) tp->get_con();
-  merge(return_bci);
-#else
   assert(block()->num_successors() == 1, "a ret can only go one place now");
   Block* target = block()->successor_at(0);
   assert(!target->is_ready(), "our arrival must be expected");
   profile_ret(target->flow()->start());
   int pnum = target->next_path_num();
   merge_common(target, pnum);
-#endif
 }
 
 //--------------------------dynamic_branch_prediction--------------------------
--- a/src/share/vm/opto/parse3.cpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/opto/parse3.cpp	Wed Sep 07 11:52:00 2011 -0700
@@ -100,11 +100,11 @@
     }
   }
 
-  // Deoptimize on putfield writes to CallSite.target
+  // Deoptimize on putfield writes to call site target field.
   if (!is_get && field->is_call_site_target()) {
     uncommon_trap(Deoptimization::Reason_unhandled,
                   Deoptimization::Action_reinterpret,
-                  NULL, "put to CallSite.target field");
+                  NULL, "put to call site target field");
     return;
   }
 
@@ -147,19 +147,21 @@
 void Parse::do_get_xxx(Node* obj, ciField* field, bool is_field) {
   // Does this field have a constant value?  If so, just push the value.
   if (field->is_constant()) {
+    // final field
     if (field->is_static()) {
       // final static field
       if (push_constant(field->constant_value()))
         return;
     }
     else {
-      // final non-static field of a trusted class (classes in
-      // java.lang.invoke and sun.invoke packages and subpackages).
+      // final non-static field
+      // Treat final non-static fields of trusted classes (classes in
+      // java.lang.invoke and sun.invoke packages and subpackages) as
+      // compile time constants.
       if (obj->is_Con()) {
         const TypeOopPtr* oop_ptr = obj->bottom_type()->isa_oopptr();
         ciObject* constant_oop = oop_ptr->const_oop();
         ciConstant constant = field->constant_value_of(constant_oop);
-
         if (push_constant(constant, true))
           return;
       }
--- a/src/share/vm/opto/runtime.cpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/opto/runtime.cpp	Wed Sep 07 11:52:00 2011 -0700
@@ -978,7 +978,6 @@
 
     thread->set_exception_pc(pc);
     thread->set_exception_handler_pc(handler_address);
-    thread->set_exception_stack_size(0);
 
     // Check if the exception PC is a MethodHandle call site.
     thread->set_is_method_handle_return(nm->is_method_handle_return(pc));
--- a/src/share/vm/opto/split_if.cpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/opto/split_if.cpp	Wed Sep 07 11:52:00 2011 -0700
@@ -500,19 +500,14 @@
   region_cache.lru_insert( new_false, new_false );
   region_cache.lru_insert( new_true , new_true  );
   // Now handle all uses of the splitting block
-  for (DUIterator_Last kmin, k = region->last_outs(kmin); k >= kmin; --k) {
-    Node* phi = region->last_out(k);
-    if( !phi->in(0) ) {         // Dead phi?  Remove it
+  for (DUIterator k = region->outs(); region->has_out(k); k++) {
+    Node* phi = region->out(k);
+    if (!phi->in(0)) {         // Dead phi?  Remove it
       _igvn.remove_dead_node(phi);
-      continue;
-    }
-    assert( phi->in(0) == region, "" );
-    if( phi == region ) {       // Found the self-reference
-      phi->set_req(0, NULL);
-      continue;                 // Break the self-cycle
-    }
-    // Expected common case: Phi hanging off of Region
-    if( phi->is_Phi() ) {
+    } else if (phi == region) { // Found the self-reference
+      continue;                 // No roll-back of DUIterator
+    } else if (phi->is_Phi()) { // Expected common case: Phi hanging off of Region
+      assert(phi->in(0) == region, "Inconsistent graph");
       // Need a per-def cache.  Phi represents a def, so make a cache
       small_cache phi_cache;
 
@@ -524,22 +519,24 @@
         // collection of PHI's merging values from different paths.  The Phis
         // inserted depend only on the location of the USE.  We use a
         // 2-element cache to handle multiple uses from the same block.
-        handle_use( use, phi, &phi_cache, region_dom, new_false, new_true, old_false, old_true );
+        handle_use(use, phi, &phi_cache, region_dom, new_false, new_true, old_false, old_true);
       } // End of while phi has uses
-
-      // Because handle_use might relocate region->_out,
-      // we must refresh the iterator.
-      k = region->last_outs(kmin);
-
       // Remove the dead Phi
       _igvn.remove_dead_node( phi );
-
     } else {
+      assert(phi->in(0) == region, "Inconsistent graph");
       // Random memory op guarded by Region.  Compute new DEF for USE.
-      handle_use( phi, region, &region_cache, region_dom, new_false, new_true, old_false, old_true );
+      handle_use(phi, region, &region_cache, region_dom, new_false, new_true, old_false, old_true);
     }
+    // Every path above deletes a use of the region, except for the region
+    // self-cycle (which is needed by handle_use calling find_use_block
+    // calling get_ctrl calling get_ctrl_no_update looking for dead
+    // regions).  So roll back the DUIterator innards.
+    --k;
+  } // End of while merge point has phis
 
-  } // End of while merge point has phis
+  assert(region->outcnt() == 1, "Only self reference should remain"); // Just Self on the Region
+  region->set_req(0, NULL);       // Break the self-cycle
 
   // Any leftover bits in the splitting block must not have depended on local
   // Phi inputs (these have already been split-up).  Hence it's safe to hoist
--- a/src/share/vm/precompiled.hpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/precompiled.hpp	Wed Sep 07 11:52:00 2011 -0700
@@ -206,7 +206,6 @@
 # include "runtime/perfMemory.hpp"
 # include "runtime/prefetch.hpp"
 # include "runtime/reflection.hpp"
-# include "runtime/reflectionCompat.hpp"
 # include "runtime/reflectionUtils.hpp"
 # include "runtime/registerMap.hpp"
 # include "runtime/safepoint.hpp"
--- a/src/share/vm/prims/forte.cpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/prims/forte.cpp	Wed Sep 07 11:52:00 2011 -0700
@@ -522,25 +522,6 @@
 extern "C" {
 JNIEXPORT
 void AsyncGetCallTrace(ASGCT_CallTrace *trace, jint depth, void* ucontext) {
-
-// This is if'd out because we no longer use thread suspension.
-// However if someone wanted to backport this to a 5.0 jvm then this
-// code would be important.
-#if 0
-  if (SafepointSynchronize::is_synchronizing()) {
-    // The safepoint mechanism is trying to synchronize all the threads.
-    // Since this can involve thread suspension, it is not safe for us
-    // to be here. We can reduce the deadlock risk window by quickly
-    // returning to the SIGPROF handler. However, it is still possible
-    // for VMThread to catch us here or in the SIGPROF handler. If we
-    // are suspended while holding a resource and another thread blocks
-    // on that resource in the SIGPROF handler, then we will have a
-    // three-thread deadlock (VMThread, this thread, the other thread).
-    trace->num_frames = ticks_safepoint; // -10
-    return;
-  }
-#endif
-
   JavaThread* thread;
 
   if (trace->env_id == NULL ||
--- a/src/share/vm/prims/jvm.cpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/prims/jvm.cpp	Wed Sep 07 11:52:00 2011 -0700
@@ -4020,249 +4020,6 @@
 #endif
 
 
-//---------------------------------------------------------------------------
-//
-// Support for old native code-based reflection (pre-JDK 1.4)
-// Disabled by default in the product build.
-//
-// See reflection.hpp for information on SUPPORT_OLD_REFLECTION
-//
-//---------------------------------------------------------------------------
-
-#ifdef SUPPORT_OLD_REFLECTION
-
-JVM_ENTRY(jobjectArray, JVM_GetClassFields(JNIEnv *env, jclass cls, jint which))
-  JVMWrapper("JVM_GetClassFields");
-  JvmtiVMObjectAllocEventCollector oam;
-  oop mirror = JNIHandles::resolve_non_null(cls);
-  objArrayOop result = Reflection::reflect_fields(mirror, which, CHECK_NULL);
-  return (jobjectArray) JNIHandles::make_local(env, result);
-JVM_END
-
-
-JVM_ENTRY(jobjectArray, JVM_GetClassMethods(JNIEnv *env, jclass cls, jint which))
-  JVMWrapper("JVM_GetClassMethods");
-  JvmtiVMObjectAllocEventCollector oam;
-  oop mirror = JNIHandles::resolve_non_null(cls);
-  objArrayOop result = Reflection::reflect_methods(mirror, which, CHECK_NULL);
-  //%note jvm_r4
-  return (jobjectArray) JNIHandles::make_local(env, result);
-JVM_END
-
-
-JVM_ENTRY(jobjectArray, JVM_GetClassConstructors(JNIEnv *env, jclass cls, jint which))
-  JVMWrapper("JVM_GetClassConstructors");
-  JvmtiVMObjectAllocEventCollector oam;
-  oop mirror = JNIHandles::resolve_non_null(cls);
-  objArrayOop result = Reflection::reflect_constructors(mirror, which, CHECK_NULL);
-  //%note jvm_r4
-  return (jobjectArray) JNIHandles::make_local(env, result);
-JVM_END
-
-
-JVM_ENTRY(jobject, JVM_GetClassField(JNIEnv *env, jclass cls, jstring name, jint which))
-  JVMWrapper("JVM_GetClassField");
-  JvmtiVMObjectAllocEventCollector oam;
-  if (name == NULL) return NULL;
-  Handle str (THREAD, JNIHandles::resolve_non_null(name));
-
-  const char* cstr = java_lang_String::as_utf8_string(str());
-  TempNewSymbol field_name = SymbolTable::probe(cstr, (int)strlen(cstr));
-  if (field_name == NULL) {
-    THROW_0(vmSymbols::java_lang_NoSuchFieldException());
-  }
-
-  oop mirror = JNIHandles::resolve_non_null(cls);
-  oop result = Reflection::reflect_field(mirror, field_name, which, CHECK_NULL);
-  if (result == NULL) {
-    THROW_0(vmSymbols::java_lang_NoSuchFieldException());
-  }
-  return JNIHandles::make_local(env, result);
-JVM_END
-
-
-JVM_ENTRY(jobject, JVM_GetClassMethod(JNIEnv *env, jclass cls, jstring name, jobjectArray types, jint which))
-  JVMWrapper("JVM_GetClassMethod");
-  JvmtiVMObjectAllocEventCollector oam;
-  if (name == NULL) {
-    THROW_0(vmSymbols::java_lang_NullPointerException());
-  }
-  Handle str (THREAD, JNIHandles::resolve_non_null(name));
-
-  const char* cstr = java_lang_String::as_utf8_string(str());
-  TempNewSymbol method_name = SymbolTable::probe(cstr, (int)strlen(cstr));
-  if (method_name == NULL) {
-    THROW_0(vmSymbols::java_lang_NoSuchMethodException());
-  }
-
-  oop mirror = JNIHandles::resolve_non_null(cls);
-  objArrayHandle tarray (THREAD, objArrayOop(JNIHandles::resolve(types)));
-  oop result = Reflection::reflect_method(mirror, method_name, tarray,
-                                          which, CHECK_NULL);
-  if (result == NULL) {
-    THROW_0(vmSymbols::java_lang_NoSuchMethodException());
-  }
-  return JNIHandles::make_local(env, result);
-JVM_END
-
-
-JVM_ENTRY(jobject, JVM_GetClassConstructor(JNIEnv *env, jclass cls, jobjectArray types, jint which))
-  JVMWrapper("JVM_GetClassConstructor");
-  JvmtiVMObjectAllocEventCollector oam;
-  oop mirror = JNIHandles::resolve_non_null(cls);
-  objArrayHandle tarray (THREAD, objArrayOop(JNIHandles::resolve(types)));
-  oop result = Reflection::reflect_constructor(mirror, tarray, which, CHECK_NULL);
-  if (result == NULL) {
-    THROW_0(vmSymbols::java_lang_NoSuchMethodException());
-  }
-  return (jobject) JNIHandles::make_local(env, result);
-JVM_END
-
-
-// Instantiation ///////////////////////////////////////////////////////////////////////////////
-
-JVM_ENTRY(jobject, JVM_NewInstance(JNIEnv *env, jclass cls))
-  JVMWrapper("JVM_NewInstance");
-  Handle mirror(THREAD, JNIHandles::resolve_non_null(cls));
-
-  methodOop resolved_constructor = java_lang_Class::resolved_constructor(mirror());
-  if (resolved_constructor == NULL) {
-    klassOop k = java_lang_Class::as_klassOop(mirror());
-    // The java.lang.Class object caches a resolved constructor if all the checks
-    // below were done successfully and a constructor was found.
-
-    // Do class based checks
-    if (java_lang_Class::is_primitive(mirror())) {
-      const char* msg = "";
-      if      (mirror == Universe::bool_mirror())   msg = "java/lang/Boolean";
-      else if (mirror == Universe::char_mirror())   msg = "java/lang/Character";
-      else if (mirror == Universe::float_mirror())  msg = "java/lang/Float";
-      else if (mirror == Universe::double_mirror()) msg = "java/lang/Double";
-      else if (mirror == Universe::byte_mirror())   msg = "java/lang/Byte";
-      else if (mirror == Universe::short_mirror())  msg = "java/lang/Short";
-      else if (mirror == Universe::int_mirror())    msg = "java/lang/Integer";
-      else if (mirror == Universe::long_mirror())   msg = "java/lang/Long";
-      THROW_MSG_0(vmSymbols::java_lang_NullPointerException(), msg);
-    }
-
-    // Check whether we are allowed to instantiate this class
-    Klass::cast(k)->check_valid_for_instantiation(false, CHECK_NULL); // Array classes get caught here
-    instanceKlassHandle klass(THREAD, k);
-    // Make sure class is initialized (also so all methods are rewritten)
-    klass->initialize(CHECK_NULL);
-
-    // Lookup default constructor
-    resolved_constructor = klass->find_method(vmSymbols::object_initializer_name(), vmSymbols::void_method_signature());
-    if (resolved_constructor == NULL) {
-      ResourceMark rm(THREAD);
-      THROW_MSG_0(vmSymbols::java_lang_InstantiationException(), klass->external_name());
-    }
-
-    // Cache result in java.lang.Class object. Does not have to be MT safe.
-    java_lang_Class::set_resolved_constructor(mirror(), resolved_constructor);
-  }
-
-  assert(resolved_constructor != NULL, "sanity check");
-  methodHandle constructor = methodHandle(THREAD, resolved_constructor);
-
-  // We have an initialized instanceKlass with a default constructor
-  instanceKlassHandle klass(THREAD, java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls)));
-  assert(klass->is_initialized() || klass->is_being_initialized(), "sanity check");
-
-  // Do security check
-  klassOop caller_klass = NULL;
-  if (UsePrivilegedStack) {
-    caller_klass = thread->security_get_caller_class(2);
-
-    if (!Reflection::verify_class_access(caller_klass, klass(), false) ||
-        !Reflection::verify_field_access(caller_klass,
-                                         klass(),
-                                         klass(),
-                                         constructor->access_flags(),
-                                         false,
-                                         true)) {
-      ResourceMark rm(THREAD);
-      THROW_MSG_0(vmSymbols::java_lang_IllegalAccessException(), klass->external_name());
-    }
-  }
-
-  // Allocate object and call constructor
-  Handle receiver = klass->allocate_instance_handle(CHECK_NULL);
-  JavaCalls::call_default_constructor(thread, constructor, receiver, CHECK_NULL);
-
-  jobject res = JNIHandles::make_local(env, receiver());
-  if (JvmtiExport::should_post_vm_object_alloc()) {
-    JvmtiExport::post_vm_object_alloc(JavaThread::current(), receiver());
-  }
-  return res;
-JVM_END
-
-
-// Field ////////////////////////////////////////////////////////////////////////////////////////////
-
-JVM_ENTRY(jobject, JVM_GetField(JNIEnv *env, jobject field, jobject obj))
-  JVMWrapper("JVM_GetField");
-  JvmtiVMObjectAllocEventCollector oam;
-  Handle field_mirror(thread, JNIHandles::resolve(field));
-  Handle receiver    (thread, JNIHandles::resolve(obj));
-  fieldDescriptor fd;
-  Reflection::resolve_field(field_mirror, receiver, &fd, false, CHECK_NULL);
-  jvalue value;
-  BasicType type = Reflection::field_get(&value, &fd, receiver);
-  oop box = Reflection::box(&value, type, CHECK_NULL);
-  return JNIHandles::make_local(env, box);
-JVM_END
-
-
-JVM_ENTRY(jvalue, JVM_GetPrimitiveField(JNIEnv *env, jobject field, jobject obj, unsigned char wCode))
-  JVMWrapper("JVM_GetPrimitiveField");
-  Handle field_mirror(thread, JNIHandles::resolve(field));
-  Handle receiver    (thread, JNIHandles::resolve(obj));
-  fieldDescriptor fd;
-  jvalue value;
-  value.j = 0;
-  Reflection::resolve_field(field_mirror, receiver, &fd, false, CHECK_(value));
-  BasicType type = Reflection::field_get(&value, &fd, receiver);
-  BasicType wide_type = (BasicType) wCode;
-  if (type != wide_type) {
-    Reflection::widen(&value, type, wide_type, CHECK_(value));
-  }
-  return value;
-JVM_END // should really be JVM_END, but that doesn't work for union types!
-
-
-JVM_ENTRY(void, JVM_SetField(JNIEnv *env, jobject field, jobject obj, jobject val))
-  JVMWrapper("JVM_SetField");
-  Handle field_mirror(thread, JNIHandles::resolve(field));
-  Handle receiver    (thread, JNIHandles::resolve(obj));
-  oop box = JNIHandles::resolve(val);
-  fieldDescriptor fd;
-  Reflection::resolve_field(field_mirror, receiver, &fd, true, CHECK);
-  BasicType field_type = fd.field_type();
-  jvalue value;
-  BasicType value_type;
-  if (field_type == T_OBJECT || field_type == T_ARRAY) {
-    // Make sure we do no unbox e.g. java/lang/Integer instances when storing into an object array
-    value_type = Reflection::unbox_for_regular_object(box, &value);
-    Reflection::field_set(&value, &fd, receiver, field_type, CHECK);
-  } else {
-    value_type = Reflection::unbox_for_primitive(box, &value, CHECK);
-    Reflection::field_set(&value, &fd, receiver, value_type, CHECK);
-  }
-JVM_END
-
-
-JVM_ENTRY(void, JVM_SetPrimitiveField(JNIEnv *env, jobject field, jobject obj, jvalue v, unsigned char vCode))
-  JVMWrapper("JVM_SetPrimitiveField");
-  Handle field_mirror(thread, JNIHandles::resolve(field));
-  Handle receiver    (thread, JNIHandles::resolve(obj));
-  fieldDescriptor fd;
-  Reflection::resolve_field(field_mirror, receiver, &fd, true, CHECK);
-  BasicType value_type = (BasicType) vCode;
-  Reflection::field_set(&v, &fd, receiver, value_type, CHECK);
-JVM_END
-
-
 // Method ///////////////////////////////////////////////////////////////////////////////////////////
 
 JVM_ENTRY(jobject, JVM_InvokeMethod(JNIEnv *env, jobject method, jobject obj, jobjectArray args0))
@@ -4302,8 +4059,6 @@
   return res;
 JVM_END
 
-#endif /* SUPPORT_OLD_REFLECTION */
-
 // Atomic ///////////////////////////////////////////////////////////////////////////////////////////
 
 JVM_LEAF(jboolean, JVM_SupportsCX8())
--- a/src/share/vm/prims/jvm.h	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/prims/jvm.h	Wed Sep 07 11:52:00 2011 -0700
@@ -26,7 +26,6 @@
 #define SHARE_VM_PRIMS_JVM_H
 
 #include "prims/jni.h"
-#include "runtime/reflectionCompat.hpp"
 #ifdef TARGET_OS_FAMILY_linux
 # include "jvm_linux.h"
 #endif
@@ -43,8 +42,7 @@
 // HotSpot integration note:
 //
 // This file and jvm.h used with the JDK are identical,
-// except for the three includes removed below and the
-// SUPPORT_OLD_REFLECTION sections cut out of the JDK's jvm.h.
+// except for the three includes removed below
 
 // #include <sys/stat.h>
 // #include "jni.h"
@@ -443,14 +441,6 @@
                               jsize len, jobject pd, const char *source,
                               jboolean verify);
 
-/* Define a class with a source (MLVM) */
-JNIEXPORT jclass JNICALL
-JVM_DefineClassWithCP(JNIEnv *env, const char *name, jobject loader,
-                      const jbyte *buf, jsize len, jobject pd,
-                      const char *source,
-                      // same args as JVM_DefineClassWithSource to this point
-                      jobjectArray constants);
-
 /*
  * Reflection support functions
  */
@@ -1442,65 +1432,6 @@
 JNIEXPORT void JNICALL
 JVM_RawMonitorExit(void *mon);
 
-
-#ifdef SUPPORT_OLD_REFLECTION
-
-/*
- * Support for old native code-based (pre-JDK 1.4) reflection implementation.
- * Disabled by default in the product build.
- *
- * See reflection.hpp for information on SUPPORT_OLD_REFLECTION
- */
-
-/*
- * reflecting fields and methods.
- * which: 0 --- MEMBER_PUBLIC
- *        1 --- MEMBER_DECLARED
- * NOTE: absent in product build by default
- */
-
-JNIEXPORT jobjectArray JNICALL
-JVM_GetClassFields(JNIEnv *env, jclass cls, jint which);
-
-JNIEXPORT jobjectArray JNICALL
-JVM_GetClassMethods(JNIEnv *env, jclass cls, jint which);
-
-JNIEXPORT jobjectArray JNICALL
-JVM_GetClassConstructors(JNIEnv *env, jclass cls, jint which);
-
-JNIEXPORT jobject JNICALL
-JVM_GetClassField(JNIEnv *env, jclass cls, jstring name, jint which);
-
-JNIEXPORT jobject JNICALL
-JVM_GetClassMethod(JNIEnv *env, jclass cls, jstring name, jobjectArray types,
-                   jint which);
-JNIEXPORT jobject JNICALL
-JVM_GetClassConstructor(JNIEnv *env, jclass cls, jobjectArray types,
-                        jint which);
-
-/*
- * Implements Class.newInstance
- */
-JNIEXPORT jobject JNICALL
-JVM_NewInstance(JNIEnv *env, jclass cls);
-
-/*
- * java.lang.reflect.Field
- */
-JNIEXPORT jobject JNICALL
-JVM_GetField(JNIEnv *env, jobject field, jobject obj);
-
-JNIEXPORT jvalue JNICALL
-JVM_GetPrimitiveField(JNIEnv *env, jobject field, jobject obj,
-                      unsigned char wCode);
-
-JNIEXPORT void JNICALL
-JVM_SetField(JNIEnv *env, jobject field, jobject obj, jobject val);
-
-JNIEXPORT void JNICALL
-JVM_SetPrimitiveField(JNIEnv *env, jobject field, jobject obj, jvalue v,
-                      unsigned char vCode);
-
 /*
  * java.lang.reflect.Method
  */
@@ -1513,8 +1444,6 @@
 JNIEXPORT jobject JNICALL
 JVM_NewInstanceFromConstructor(JNIEnv *env, jobject c, jobjectArray args0);
 
-#endif /* SUPPORT_OLD_REFLECTION */
-
 /*
  * java.lang.management support
  */
--- a/src/share/vm/prims/methodHandleWalk.cpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/prims/methodHandleWalk.cpp	Wed Sep 07 11:52:00 2011 -0700
@@ -182,10 +182,6 @@
   HandleMark hm;
   ResourceMark rm;
   Handle mh(m);
-  print(mh);
-}
-
-void MethodHandleChain::print(Handle mh) {
   EXCEPTION_MARK;
   MethodHandleChain mhc(mh, THREAD);
   if (HAS_PENDING_EXCEPTION) {
@@ -222,16 +218,33 @@
       if (o != NULL) {
         if (o->is_instance()) {
           tty->print(" instance %s", o->klass()->klass_part()->internal_name());
+          if (java_lang_invoke_CountingMethodHandle::is_instance(o)) {
+            tty->print(" vmcount: %d", java_lang_invoke_CountingMethodHandle::vmcount(o));
+          }
         } else {
           o->print();
         }
       }
+      oop vmt = chain.vmtarget_oop();
+      if (vmt != NULL) {
+        if (vmt->is_method()) {
+          tty->print(" ");
+          methodOop(vmt)->print_short_name(tty);
+        } else if (java_lang_invoke_MethodHandle::is_instance(vmt)) {
+          tty->print(" method handle " INTPTR_FORMAT, vmt);
+        } else {
+          ShouldNotReachHere();
+        }
+      }
     } else if (chain.is_adapter()) {
       tty->print("adapter: arg_slot %d conversion op %s",
                  chain.adapter_arg_slot(),
                  adapter_op_to_string(chain.adapter_conversion_op()));
       switch (chain.adapter_conversion_op()) {
         case java_lang_invoke_AdapterMethodHandle::OP_RETYPE_ONLY:
+          if (java_lang_invoke_CountingMethodHandle::is_instance(chain.method_handle_oop())) {
+            tty->print(" vmcount: %d", java_lang_invoke_CountingMethodHandle::vmcount(chain.method_handle_oop()));
+          }
         case java_lang_invoke_AdapterMethodHandle::OP_RETYPE_RAW:
         case java_lang_invoke_AdapterMethodHandle::OP_CHECK_CAST:
         case java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_PRIM:
@@ -907,7 +920,10 @@
     _non_bcp_klasses(THREAD, 5),
     _cur_stack(0),
     _max_stack(0),
-    _rtype(T_ILLEGAL)
+    _rtype(T_ILLEGAL),
+    _selectAlternative_bci(-1),
+    _taken_count(0),
+    _not_taken_count(0)
 {
 
   // Element zero is always the null constant.
@@ -1115,11 +1131,50 @@
     _bytecode.push(0);
     break;
 
+  case Bytecodes::_ifeq:
+    assert((unsigned short) index == index, "index does not fit in 16-bit");
+    _bytecode.push(op);
+    _bytecode.push(index >> 8);
+    _bytecode.push(index);
+    break;
+
   default:
     ShouldNotReachHere();
   }
 }
 
+void MethodHandleCompiler::update_branch_dest(int src, int dst) {
+  switch (_bytecode.at(src)) {
+    case Bytecodes::_ifeq:
+      dst -= src; // compute the offset
+      assert((unsigned short) dst == dst, "index does not fit in 16-bit");
+      _bytecode.at_put(src + 1, dst >> 8);
+      _bytecode.at_put(src + 2, dst);
+      break;
+    default:
+      ShouldNotReachHere();
+  }
+}
+
+void MethodHandleCompiler::emit_load(ArgToken arg) {
+  TokenType tt = arg.token_type();
+  BasicType bt = arg.basic_type();
+
+  switch (tt) {
+    case tt_parameter:
+    case tt_temporary:
+      emit_load(bt, arg.index());
+      break;
+    case tt_constant:
+      emit_load_constant(arg);
+      break;
+    case tt_illegal:
+    case tt_void:
+    default:
+      ShouldNotReachHere();
+  }
+}
+
 
 void MethodHandleCompiler::emit_load(BasicType bt, int index) {
   if (index <= 3) {
@@ -1318,6 +1373,29 @@
 jvalue MethodHandleCompiler::zero_jvalue = { 0 };
 jvalue MethodHandleCompiler::one_jvalue  = { 1 };
 
+// Fetch any values from CountingMethodHandles and capture them for profiles
+bool MethodHandleCompiler::fetch_counts(ArgToken arg1, ArgToken arg2) {
+  int count1 = -1, count2 = -1;
+  if (arg1.token_type() == tt_constant && arg1.basic_type() == T_OBJECT &&
+      java_lang_invoke_CountingMethodHandle::is_instance(arg1.object()())) {
+    count1 = java_lang_invoke_CountingMethodHandle::vmcount(arg1.object()());
+  }
+  if (arg2.token_type() == tt_constant && arg2.basic_type() == T_OBJECT &&
+      java_lang_invoke_CountingMethodHandle::is_instance(arg2.object()())) {
+    count2 = java_lang_invoke_CountingMethodHandle::vmcount(arg2.object()());
+  }
+  int total = count1 + count2;
+  if (count1 != -1 && count2 != -1 && total != 0) {
+    // Normalize the collect counts to the invoke_count
+    tty->print("counts %d %d scaled by %d = ", count2, count1, _invoke_count);
+    if (count1 != 0) _not_taken_count = (int)(_invoke_count * count1 / (double)total);
+    if (count2 != 0) _taken_count = (int)(_invoke_count * count2 / (double)total);
+    tty->print_cr("%d %d", _taken_count, _not_taken_count);
+    return true;
+  }
+  return false;
+}
+
 // Emit bytecodes for the given invoke instruction.
 MethodHandleWalker::ArgToken
 MethodHandleCompiler::make_invoke(methodHandle m, vmIntrinsics::ID iid,
@@ -1367,6 +1445,29 @@
     }
   }
 
+  if (m->intrinsic_id() == vmIntrinsics::_selectAlternative &&
+      fetch_counts(argv[1], argv[2])) {
+    assert(argc == 3, "three arguments");
+    assert(tailcall, "only");
+
+    // do inline bytecodes so we can drop profile data into it,
+    //   0:   iload_0
+    emit_load(argv[0]);
+    //   1:   ifeq    8
+    _selectAlternative_bci = _bytecode.length();
+    emit_bc(Bytecodes::_ifeq, 0); // emit placeholder offset
+    //   4:   aload_1
+    emit_load(argv[1]);
+    //   5:   areturn;
+    emit_bc(Bytecodes::_areturn);
+    //   8:   aload_2
+    update_branch_dest(_selectAlternative_bci, cur_bci());
+    emit_load(argv[2]);
+    //   9:   areturn
+    emit_bc(Bytecodes::_areturn);
+    return ArgToken();  // Dummy return value.
+  }
+
   check_non_bcp_klass(klass, CHECK_(zero));
   if (m->is_method_handle_invoke()) {
     check_non_bcp_klasses(m->method_handle_type(), CHECK_(zero));
@@ -1377,10 +1478,6 @@
   assert(argc == asc.size() + ((op == Bytecodes::_invokestatic || op == Bytecodes::_invokedynamic) ? 0 : 1),
          "argc mismatch");
 
-  // Inline the method.
-  InvocationCounter* ic = m->invocation_counter();
-  ic->set_carry_flag();
-
   for (int i = 0; i < argc; i++) {
     ArgToken arg = argv[i];
     TokenType tt = arg.token_type();
@@ -1686,7 +1783,7 @@
 }
 
 
-methodHandle MethodHandleCompiler::get_method_oop(TRAPS) const {
+methodHandle MethodHandleCompiler::get_method_oop(TRAPS) {
   methodHandle empty;
   // Create a method that holds the generated bytecode.  invokedynamic
   // has no receiver, normal MH calls do.
@@ -1765,6 +1862,7 @@
     assert(m->method_data() == NULL, "there should not be an MDO yet");
     m->set_method_data(mdo);
 
+    bool found_selectAlternative = false;
     // Iterate over all profile data and set the count of the counter
     // data entries to the original call site counter.
     for (ProfileData* profile_data = mdo->first_data();
@@ -1774,7 +1872,15 @@
         CounterData* counter_data = profile_data->as_CounterData();
         counter_data->set_count(_invoke_count);
       }
+      if (profile_data->is_BranchData() &&
+          profile_data->bci() == _selectAlternative_bci) {
+        BranchData* bd = profile_data->as_BranchData();
+        bd->set_taken(_taken_count);
+        bd->set_not_taken(_not_taken_count);
+        found_selectAlternative = true;
+      }
     }
+    assert(_selectAlternative_bci == -1 || found_selectAlternative, "must have found profile entry");
   }
 
 #ifndef PRODUCT
--- a/src/share/vm/prims/methodHandleWalk.hpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/prims/methodHandleWalk.hpp	Wed Sep 07 11:52:00 2011 -0700
@@ -74,6 +74,7 @@
     set_method_handle(MethodHandle_vmtarget_oop(), THREAD);
   }
 
+  Handle root()                 { return _root; }
   Handle method_handle()        { return _method_handle; }
   oop    method_handle_oop()    { return _method_handle(); }
   oop    method_type_oop()      { return MethodHandle_type_oop(); }
@@ -110,7 +111,6 @@
   // the signature for each method.  The signatures are printed in
   // slot order to make it easier to understand.
   void print();
-  static void print(Handle mh);
   static void print(oopDesc* mh);
 #endif
 };
@@ -277,6 +277,10 @@
   KlassHandle  _target_klass;
   Thread*      _thread;
 
+  int          _selectAlternative_bci; // These are used for capturing profiles from GWTs
+  int          _taken_count;
+  int          _not_taken_count;
+
   // Values used by the compiler.
   static jvalue zero_jvalue;
   static jvalue one_jvalue;
@@ -372,6 +376,7 @@
 
   unsigned char* bytecode()        const { return _bytecode.adr_at(0); }
   int            bytecode_length() const { return _bytecode.length(); }
+  int            cur_bci()         const { return _bytecode.length(); }
 
   // Fake constant pool.
   int cpool_oop_put(int tag, Handle con) {
@@ -436,6 +441,8 @@
   }
 
   void emit_bc(Bytecodes::Code op, int index = 0, int args_size = -1);
+  void update_branch_dest(int src, int dst);
+  void emit_load(ArgToken arg);
   void emit_load(BasicType bt, int index);
   void emit_store(BasicType bt, int index);
   void emit_load_constant(ArgToken arg);
@@ -455,11 +462,14 @@
   virtual ArgToken make_fetch(BasicType type, klassOop tk, Bytecodes::Code op, const ArgToken& base, const ArgToken& offset, TRAPS);
   virtual ArgToken make_invoke(methodHandle m, vmIntrinsics::ID iid, Bytecodes::Code op, bool tailcall, int argc, ArgToken* argv, TRAPS);
 
+  // Check for profiling information on a GWT and return true if it's found
+  bool fetch_counts(ArgToken a1, ArgToken a2);
+
   // Get a real constant pool.
   constantPoolHandle get_constant_pool(TRAPS) const;
 
   // Get a real methodOop.
-  methodHandle get_method_oop(TRAPS) const;
+  methodHandle get_method_oop(TRAPS);
 
 public:
   MethodHandleCompiler(Handle root, Symbol* name, Symbol* signature, int invoke_count, bool for_invokedynamic, TRAPS);
--- a/src/share/vm/prims/methodHandles.cpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/prims/methodHandles.cpp	Wed Sep 07 11:52:00 2011 -0700
@@ -158,6 +158,8 @@
   "adapter_fold/4/ref",
   "adapter_fold/5/ref",
 
+  "adapter_opt_profiling",
+
   NULL
 };
 
@@ -2653,6 +2655,11 @@
   // Finalize the conversion field.  (Note that it is final to Java code.)
   java_lang_invoke_AdapterMethodHandle::set_conversion(mh(), new_conversion);
 
+  if (java_lang_invoke_CountingMethodHandle::is_instance(mh())) {
+    assert(ek_orig == _adapter_retype_only, "only one handled");
+    ek_opt = _adapter_opt_profiling;
+  }
+
   // Done!
   java_lang_invoke_MethodHandle::set_vmentry(mh(), entry(ek_opt));
 
@@ -2905,8 +2912,12 @@
     return MethodHandles::stack_move_unit();
   case MethodHandles::GC_CONV_OP_IMPLEMENTED_MASK:
     return MethodHandles::adapter_conversion_ops_supported_mask();
-  case MethodHandles::GC_OP_ROT_ARGS_DOWN_LIMIT_BIAS:
-    return MethodHandles::OP_ROT_ARGS_DOWN_LIMIT_BIAS;
+  case MethodHandles::GC_COUNT_GWT:
+#ifdef COMPILER2
+    return true;
+#else
+    return false;
+#endif
   }
   return 0;
 }
--- a/src/share/vm/prims/methodHandles.hpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/prims/methodHandles.hpp	Wed Sep 07 11:52:00 2011 -0700
@@ -187,6 +187,8 @@
     _adapter_opt_fold_FIRST = _adapter_opt_fold_ref,
     _adapter_opt_fold_LAST  = _adapter_opt_fold_5_ref,
 
+    _adapter_opt_profiling,
+
     _EK_LIMIT,
     _EK_FIRST = 0
   };
@@ -266,6 +268,8 @@
       return _adapter_fold_args;
     if (ek >= _adapter_opt_return_FIRST && ek <= _adapter_opt_return_LAST)
       return _adapter_opt_return_any;
+    if (ek == _adapter_opt_profiling)
+      return _adapter_retype_only;
     assert(false, "oob");
     return _EK_LIMIT;
   }
@@ -582,6 +586,7 @@
     GC_JVM_STACK_MOVE_UNIT = 1,
     GC_CONV_OP_IMPLEMENTED_MASK = 2,
     GC_OP_ROT_ARGS_DOWN_LIMIT_BIAS = 3,
+    GC_COUNT_GWT = 4,
 
     // format of result from getTarget / encode_target:
     ETF_HANDLE_OR_METHOD_NAME = 0, // all available data (immediate MH or method)
--- a/src/share/vm/prims/unsafe.cpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/prims/unsafe.cpp	Wed Sep 07 11:52:00 2011 -0700
@@ -33,7 +33,6 @@
 #include "runtime/globals.hpp"
 #include "runtime/interfaceSupport.hpp"
 #include "runtime/reflection.hpp"
-#include "runtime/reflectionCompat.hpp"
 #include "runtime/synchronizer.hpp"
 #include "services/threadService.hpp"
 #include "utilities/copy.hpp"
@@ -303,6 +302,19 @@
   UnsafeWrapper("Unsafe_SetObjectVolatile");
   oop x = JNIHandles::resolve(x_h);
   oop p = JNIHandles::resolve(obj);
+  // Catch VolatileCallSite.target stores (via
+  // CallSite.setTargetVolatile) and check call site dependencies.
+  if ((offset == java_lang_invoke_CallSite::target_offset_in_bytes()) && p->is_a(SystemDictionary::CallSite_klass())) {
+    oop call_site     = p;
+    oop method_handle = x;
+    assert(call_site    ->is_a(SystemDictionary::CallSite_klass()),     "must be");
+    assert(method_handle->is_a(SystemDictionary::MethodHandle_klass()), "must be");
+    {
+      // Walk all nmethods depending on this call site.
+      MutexLocker mu(Compile_lock, thread);
+      Universe::flush_dependents_on(call_site, method_handle);
+    }
+  }
   void* addr = index_oop_from_field_offset_long(p, offset);
   OrderAccess::release();
   if (UseCompressedOops) {
--- a/src/share/vm/runtime/globals.hpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/runtime/globals.hpp	Wed Sep 07 11:52:00 2011 -0700
@@ -1985,6 +1985,18 @@
   product(bool, TLABStats, true,                                            \
           "Print various TLAB related information")                         \
                                                                             \
+  product(bool, UseBlockZeroing, false,                                     \
+          "Use special cpu instructions for block zeroing")                 \
+                                                                            \
+  product(intx, BlockZeroingLowLimit, 2048,                                 \
+          "Minimum size in bytes when block zeroing will be used")          \
+                                                                            \
+  product(bool, UseBlockCopy, false,                                        \
+          "Use special cpu instructions for block copy")                    \
+                                                                            \
+  product(intx, BlockCopyLowLimit, 2048,                                    \
+          "Minimum size in bytes when block copy will be used")             \
+                                                                            \
   product(bool, PrintRevisitStats, false,                                   \
           "Print revisit (klass and MDO) stack related information")        \
                                                                             \
@@ -2918,6 +2930,12 @@
   product(intx,  ReadPrefetchInstr, 0,                                      \
           "Prefetch instruction to prefetch ahead")                         \
                                                                             \
+  product(uintx,  ArraycopySrcPrefetchDistance, 0,                          \
+          "Distance to prefetch source array in arracopy")                  \
+                                                                            \
+  product(uintx,  ArraycopyDstPrefetchDistance, 0,                          \
+          "Distance to prefetch destination array in arracopy")             \
+                                                                            \
   /* deoptimization */                                                      \
   develop(bool, TraceDeoptimization, false,                                 \
           "Trace deoptimization")                                           \
--- a/src/share/vm/runtime/reflection.cpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/runtime/reflection.cpp	Wed Sep 07 11:52:00 2011 -0700
@@ -844,16 +844,6 @@
 }
 
 
-//---------------------------------------------------------------------------
-//
-// Supporting routines for old native code-based reflection (pre-JDK 1.4).
-//
-// See reflection.hpp for details.
-//
-//---------------------------------------------------------------------------
-
-#ifdef SUPPORT_OLD_REFLECTION
-
 methodHandle Reflection::resolve_interface_call(instanceKlassHandle klass, methodHandle method,
                                                 KlassHandle recv_klass, Handle receiver, TRAPS) {
   assert(!method.is_null() , "method should not be null");
@@ -1081,519 +1071,6 @@
   return java_lang_Class::primitive_type(basic_type_mirror);
 }
 
-
-bool Reflection::match_parameter_types(methodHandle method, objArrayHandle types, int parameter_count, TRAPS) {
-  int types_len = types.is_null() ? 0 : types->length();
-  if (types_len != parameter_count) return false;
-  if (parameter_count > 0) {
-    objArrayHandle method_types = get_parameter_types(method, parameter_count, NULL, CHECK_false);
-    for (int index = 0; index < parameter_count; index++) {
-      if (types->obj_at(index) != method_types->obj_at(index)) {
-        return false;
-      }
-    }
-  }
-  return true;
-}
-
-
-oop Reflection::new_field(FieldStream* st, TRAPS) {
-  Symbol*  field_name = st->name();
-  Handle name = java_lang_String::create_from_symbol(field_name, CHECK_NULL);
-  Symbol*  signature = st->signature();
-  Handle type = new_type(signature, st->klass(), CHECK_NULL);
-  Handle rh  = java_lang_reflect_Field::create(CHECK_NULL);
-  oop result = rh();
-
-  java_lang_reflect_Field::set_clazz(result, st->klass()->java_mirror());
-  java_lang_reflect_Field::set_slot(result, st->index());
-  java_lang_reflect_Field::set_name(result, name());
-  java_lang_reflect_Field::set_type(result, type());
-  // Note the ACC_ANNOTATION bit, which is a per-class access flag, is never set here.
-  java_lang_reflect_Field::set_modifiers(result, st->access_flags().as_int() & JVM_RECOGNIZED_FIELD_MODIFIERS);
-  java_lang_reflect_Field::set_override(result, false);
-  return result;
-}
-
-
-bool Reflection::resolve_field(Handle field_mirror, Handle& receiver, fieldDescriptor* fd, bool check_final, TRAPS) {
-  if (field_mirror.is_null()) {
-    THROW_(vmSymbols::java_lang_NullPointerException(), false);
-  }
-
-  instanceKlassHandle klass (THREAD, java_lang_Class::as_klassOop(java_lang_reflect_Field::clazz(field_mirror())));
-  int                 slot  = java_lang_reflect_Field::slot(field_mirror());
-
-  // Ensure klass is initialized
-  klass->initialize(CHECK_false);
-  fd->initialize(klass(), slot);
-
-  bool is_static = fd->is_static();
-  KlassHandle receiver_klass;
-
-  if (is_static) {
-    receiver = KlassHandle(THREAD, klass());
-    receiver_klass = klass;
-  } else {
-    // Check object is a non-null instance of declaring class
-    if (receiver.is_null()) {
-      THROW_(vmSymbols::java_lang_NullPointerException(), false);
-    }
-    if (!receiver->is_a(klass())) {
-      THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(), "object is not an instance of declaring class", false);
-    }
-    receiver_klass = KlassHandle(THREAD, receiver->klass());
-  }
-
-  // Access checking (unless overridden by Field)
-  if (!java_lang_reflect_Field::override(field_mirror())) {
-    if (!(klass->is_public() && fd->is_public())) {
-      bool access_check = reflect_check_access(klass(), fd->access_flags(), receiver_klass(), false, CHECK_false);
-      if (!access_check) {
-        return false; // exception
-      }
-    }
-  }
-
-  if (check_final && fd->is_final()) {
-    // In 1.3 we always throw an error when attempting to set a final field.
-    // In 1.2.x, this was allowed in the override bit was set by calling Field.setAccessible(true).
-    // We currently maintain backwards compatibility. See bug 4250960.
-    bool strict_final_check = !JDK_Version::is_jdk12x_version();
-    if (strict_final_check || !java_lang_reflect_Field::override(field_mirror())) {
-      THROW_MSG_(vmSymbols::java_lang_IllegalAccessException(), "field is final", false);
-    }
-  }
-  return true;
-}
-
-
-BasicType Reflection::field_get(jvalue* value, fieldDescriptor* fd, Handle receiver)  {
-  BasicType field_type = fd->field_type();
-  int offset = fd->offset();
-  switch (field_type) {
-    case T_BOOLEAN:
-      value->z = receiver->bool_field(offset);
-      break;
-    case T_CHAR:
-      value->c = receiver->char_field(offset);
-      break;
-    case T_FLOAT:
-      value->f = receiver->float_field(offset);
-      break;
-    case T_DOUBLE:
-      value->d = receiver->double_field(offset);
-      break;
-    case T_BYTE:
-      value->b = receiver->byte_field(offset);
-      break;
-    case T_SHORT:
-      value->s = receiver->short_field(offset);
-      break;
-    case T_INT:
-      value->i = receiver->int_field(offset);
-      break;
-    case T_LONG:
-      value->j = receiver->long_field(offset);
-      break;
-    case T_OBJECT:
-    case T_ARRAY:
-      value->l = (jobject) receiver->obj_field(offset);
-      break;
-    default:
-      return T_ILLEGAL;
-  }
-  return field_type;
-}
-
-
-void Reflection::field_set(jvalue* value, fieldDescriptor* fd, Handle receiver, BasicType value_type, TRAPS) {
-  BasicType field_type = fd->field_type();
-  if (field_type != value_type) {
-    widen(value, value_type, field_type, CHECK);
-  }
-
-  int offset = fd->offset();
-  switch (field_type) {
-    case T_BOOLEAN:
-      receiver->bool_field_put(offset, value->z);
-      break;
-    case T_CHAR:
-      receiver->char_field_put(offset, value->c);
-      break;
-    case T_FLOAT:
-      receiver->float_field_put(offset, value->f);
-      break;
-    case T_DOUBLE:
-      receiver->double_field_put(offset, value->d);
-      break;
-    case T_BYTE:
-      receiver->byte_field_put(offset, value->b);
-      break;
-    case T_SHORT:
-      receiver->short_field_put(offset, value->s);
-      break;
-    case T_INT:
-      receiver->int_field_put(offset, value->i);
-      break;
-    case T_LONG:
-      receiver->long_field_put(offset, value->j);
-      break;
-    case T_OBJECT:
-    case T_ARRAY: {
-      Handle obj(THREAD, (oop) value->l);
-      if (obj.not_null()) {
-        Symbol*  signature = fd->signature();
-        Handle       loader   (THREAD, fd->loader());
-        Handle       protect  (THREAD, Klass::cast(fd->field_holder())->protection_domain());
-        klassOop k = SystemDictionary::resolve_or_fail(signature, loader, protect, true, CHECK); // may block
-        if (!obj->is_a(k)) {
-          THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "field type mismatch");
-        }
-      }
-      receiver->obj_field_put(offset, obj());
-      break;
-    }
-    default:
-      THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "field type mismatch");
-  }
-}
-
-
-oop Reflection::reflect_field(oop mirror, Symbol* field_name, jint which, TRAPS) {
-  // Exclude primitive types and array types
-  if (java_lang_Class::is_primitive(mirror))                             return NULL;
-  if (Klass::cast(java_lang_Class::as_klassOop(mirror))->oop_is_array()) return NULL;
-
-  instanceKlassHandle k(THREAD, java_lang_Class::as_klassOop(mirror));
-  bool local_fields_only = (which == DECLARED);
-
-  // Ensure class is linked
-  k->link_class(CHECK_NULL);
-
-  // Search class and interface fields
-  for (FieldStream st(k, local_fields_only, false); !st.eos(); st.next()) {
-    if (st.name() == field_name) {
-      if (local_fields_only || st.access_flags().is_public()) {
-        return new_field(&st, THREAD);
-      }
-    }
-  }
-
-  return NULL;
-}
-
-
-objArrayOop Reflection::reflect_fields(oop mirror, jint which, TRAPS) {
-  // Exclude primitive types and array types
-  if (java_lang_Class::is_primitive(mirror)
-      || Klass::cast(java_lang_Class::as_klassOop(mirror))->oop_is_array()) {
-    Symbol* name = vmSymbols::java_lang_reflect_Field();
-    klassOop klass = SystemDictionary::resolve_or_fail(name, true, CHECK_NULL);
-    return oopFactory::new_objArray(klass, 0, CHECK_NULL);  // Return empty array
-  }
-
-  instanceKlassHandle k(THREAD, java_lang_Class::as_klassOop(mirror));
-
-  // Ensure class is linked
-  k->link_class(CHECK_NULL);
-
-  bool local_fields_only = (which == DECLARED);
-  int count = 0;
-  { // Compute fields count for class and interface fields
-    for (FieldStream st(k, local_fields_only, false); !st.eos(); st.next()) {
-      if (local_fields_only || st.access_flags().is_public()) {
-        count++;
-      }
-    }
-  }
-
-  // Allocate result
-  Symbol* name = vmSymbols::java_lang_reflect_Field();
-  klassOop klass = SystemDictionary::resolve_or_fail(name, true, CHECK_NULL);
-  objArrayOop r = oopFactory::new_objArray(klass, count, CHECK_NULL);
-  objArrayHandle result (THREAD, r);
-
-  // Fill in results backwards
-  {
-    for (FieldStream st(k, local_fields_only, false); !st.eos(); st.next()) {
-      if (local_fields_only || st.access_flags().is_public()) {
-        oop field = new_field(&st, CHECK_NULL);
-        result->obj_at_put(--count, field);
-      }
-    }
-    assert(count == 0, "just checking");
-  }
-  return result();
-}
-
-
-oop Reflection::reflect_method(oop mirror, Symbol* method_name, objArrayHandle types, jint which, TRAPS) {
-  if (java_lang_Class::is_primitive(mirror))  return NULL;
-  klassOop klass = java_lang_Class::as_klassOop(mirror);
-  if (Klass::cast(klass)->oop_is_array() && which == MEMBER_DECLARED)  return NULL;
-
-  if (Klass::cast(java_lang_Class::as_klassOop(mirror))->oop_is_array()) {
-    klass = SystemDictionary::Object_klass();
-  }
-  instanceKlassHandle h_k(THREAD, klass);
-
-  // Ensure klass is linked (need not be initialized)
-  h_k->link_class(CHECK_NULL);
-
-  // For interfaces include static initializers under jdk1.2.x (since classic does that)
-  bool include_clinit = JDK_Version::is_jdk12x_version() && h_k->is_interface();
-
-  switch (which) {
-    case MEMBER_PUBLIC:
-      // First the public non-static methods (works if method holder is an interface)
-      // Note that we can ignore checks for overridden methods, since we go up the hierarchy.
-      {
-        for (MethodStream st(h_k, false, false); !st.eos(); st.next()) {
-          methodHandle m(THREAD, st.method());
-          // For interfaces include static initializers since classic does that!
-          if (method_name == m->name() && (include_clinit || (m->is_public() && !m->is_static() && !m->is_initializer()))) {
-            Symbol*  signature = m->signature();
-            bool parameter_match = match_parameter_types(m, types, ArgumentCount(signature).size(), CHECK_NULL);
-            if (parameter_match) {
-              return new_method(m, false, false, THREAD);
-            }
-          }
-        }
-      }
-      // Then the public static methods (works if method holder is an interface)
-      {
-        for (MethodStream st(h_k, false, false); !st.eos(); st.next()) {
-          methodHandle m(THREAD, st.method());
-          if (method_name == m->name() && m->is_public() && m->is_static() && !m->is_initializer()) {
-            Symbol*  signature = m->signature();
-            bool parameter_match = match_parameter_types(m, types, ArgumentCount(signature).size(), CHECK_NULL);
-            if (parameter_match) {
-              return new_method(m, false, false, THREAD);
-            }
-          }
-        }
-      }
-      break;
-    case MEMBER_DECLARED:
-      // All local methods
-      {
-        for (MethodStream st(h_k, true, true); !st.eos(); st.next()) {
-          methodHandle m(THREAD, st.method());
-          if (method_name == m->name() && !m->is_initializer()) {
-            Symbol*  signature = m->signature();
-            bool parameter_match = match_parameter_types(m, types, ArgumentCount(signature).size(), CHECK_NULL);
-            if (parameter_match) {
-              return new_method(m, false, false, THREAD);
-            }
-          }
-        }
-      }
-      break;
-    default:
-      break;
-  }
-  return NULL;
-}
-
-
-objArrayOop Reflection::reflect_methods(oop mirror, jint which, TRAPS) {
-  // Exclude primitive types
-  if (java_lang_Class::is_primitive(mirror) ||
-     (Klass::cast(java_lang_Class::as_klassOop(mirror))->oop_is_array() && (which == MEMBER_DECLARED))) {
-    klassOop klass = SystemDictionary::reflect_Method_klass();
-    return oopFactory::new_objArray(klass, 0, CHECK_NULL);  // Return empty array
-  }
-
-  klassOop klass = java_lang_Class::as_klassOop(mirror);
-  if (Klass::cast(java_lang_Class::as_klassOop(mirror))->oop_is_array()) {
-    klass = SystemDictionary::Object_klass();
-  }
-  instanceKlassHandle h_k(THREAD, klass);
-
-  // Ensure klass is linked (need not be initialized)
-  h_k->link_class(CHECK_NULL);
-
-  // We search the (super)interfaces only if h_k is an interface itself
-  bool is_interface = h_k->is_interface();
-
-  // For interfaces include static initializers under jdk1.2.x (since classic does that)
-  bool include_clinit = JDK_Version::is_jdk12x_version() && is_interface;
-
-  switch (which) {
-    case MEMBER_PUBLIC:
-      {
-
-        // Count public methods (non-static and static)
-        int count = 0;
-        {
-          for (MethodStream st(h_k, false, false); !st.eos(); st.next()) {
-            methodOop m = st.method();
-            // For interfaces include static initializers since classic does that!
-            if (include_clinit || (!m->is_initializer() && m->is_public() && !m->is_overridden_in(h_k()))) {
-              count++;
-            }
-          }
-        }
-
-        // Allocate result
-        klassOop klass = SystemDictionary::reflect_Method_klass();
-        objArrayOop r = oopFactory::new_objArray(klass, count, CHECK_NULL);
-        objArrayHandle h_result (THREAD, r);
-
-        // Fill in results backwards
-        {
-          // First the non-static public methods
-          for (MethodStream st(h_k, false, false); !st.eos(); st.next()) {
-            methodHandle m (THREAD, st.method());
-            if (!m->is_static() && !m->is_initializer() && m->is_public() && !m->is_overridden_in(h_k())) {
-              oop method = new_method(m, false, false, CHECK_NULL);
-              if (method == NULL) {
-                return NULL;
-              } else {
-                h_result->obj_at_put(--count, method);
-              }
-            }
-          }
-        }
-        {
-          // Then the static public methods
-          for (MethodStream st(h_k, false, !is_interface); !st.eos(); st.next()) {
-            methodHandle m (THREAD, st.method());
-            if (m->is_static() && (include_clinit || (!m->is_initializer()) && m->is_public() && !m->is_overridden_in(h_k()))) {
-              oop method = new_method(m, false, false, CHECK_NULL);
-              if (method == NULL) {
-                return NULL;
-              } else {
-                h_result->obj_at_put(--count, method);
-              }
-            }
-          }
-        }
-
-        assert(count == 0, "just checking");
-        return h_result();
-      }
-
-    case MEMBER_DECLARED:
-      {
-        // Count all methods
-        int count = 0;
-        {
-          for (MethodStream st(h_k, true, !is_interface); !st.eos(); st.next()) {
-            methodOop m = st.method();
-            if (!m->is_initializer()) {
-              count++;
-            }
-          }
-        }
-        // Allocate result
-        klassOop klass = SystemDictionary::reflect_Method_klass();
-        objArrayOop r = oopFactory::new_objArray(klass, count, CHECK_NULL);
-        objArrayHandle h_result (THREAD, r);
-
-        // Fill in results backwards
-        {
-          for (MethodStream st(h_k, true, true); !st.eos(); st.next()) {
-            methodHandle m (THREAD, st.method());
-            if (!m->is_initializer()) {
-              oop method = new_method(m, false, false, CHECK_NULL);
-              if (method == NULL) {
-                return NULL;
-              } else {
-                h_result->obj_at_put(--count, method);
-              }
-            }
-          }
-        }
-        assert(count == 0, "just checking");
-        return h_result();
-      }
-  }
-  ShouldNotReachHere();
-  return NULL;
-}
-
-
-oop Reflection::reflect_constructor(oop mirror, objArrayHandle types, jint which, TRAPS) {
-
-  // Exclude primitive, interface and array types
-  bool prim = java_lang_Class::is_primitive(mirror);
-  Klass* klass = prim ? NULL : Klass::cast(java_lang_Class::as_klassOop(mirror));
-  if (prim || klass->is_interface() || klass->oop_is_array()) return NULL;
-
-  // Must be instance klass
-  instanceKlassHandle h_k(THREAD, java_lang_Class::as_klassOop(mirror));
-
-  // Ensure klass is linked (need not be initialized)
-  h_k->link_class(CHECK_NULL);
-
-  bool local_only = (which == MEMBER_DECLARED);
-  for (MethodStream st(h_k, true, true); !st.eos(); st.next()) {
-    methodHandle m(THREAD, st.method());
-    if (m->name() == vmSymbols::object_initializer_name() && (local_only || m->is_public())) {
-      Symbol*  signature = m->signature();
-      bool parameter_match = match_parameter_types(m, types, ArgumentCount(signature).size(), CHECK_NULL);
-      if (parameter_match) {
-        return new_constructor(m, THREAD);
-      }
-    }
-  }
-
-  return NULL;
-}
-
-
-objArrayOop Reflection::reflect_constructors(oop mirror, jint which, TRAPS) {
-  // Exclude primitive, interface and array types
-  bool prim  = java_lang_Class::is_primitive(mirror);
-  Klass* k = prim ? NULL : Klass::cast(java_lang_Class::as_klassOop(mirror));
-  if (prim || k->is_interface() || k->oop_is_array()) {
-    return oopFactory::new_objArray(SystemDictionary::reflect_Constructor_klass(), 0, CHECK_NULL);  // Return empty array
-  }
-
-  // Must be instanceKlass at this point
-  instanceKlassHandle h_k(THREAD, java_lang_Class::as_klassOop(mirror));
-
-  // Ensure klass is linked (need not be initialized)
-  h_k->link_class(CHECK_NULL);
-
-  bool local_only = (which == MEMBER_DECLARED);
-  int count = 0;
-  {
-    for (MethodStream st(h_k, true, true); !st.eos(); st.next()) {
-      methodOop m = st.method();
-      if (m->name() == vmSymbols::object_initializer_name() && (local_only || m->is_public())) {
-        count++;
-      }
-    }
-  }
-
-  // Allocate result
-  Symbol* name = vmSymbols::java_lang_reflect_Constructor();
-  klassOop klass = SystemDictionary::resolve_or_fail(name, true, CHECK_NULL);
-  objArrayOop r = oopFactory::new_objArray(klass, count, CHECK_NULL);
-  objArrayHandle h_result (THREAD, r);
-
-  // Fill in results backwards
-  {
-    for (MethodStream st(h_k, true, true); !st.eos(); st.next()) {
-      methodHandle m (THREAD, st.method());
-      if (m->name() == vmSymbols::object_initializer_name() && (local_only || m->is_public())) {
-        oop constr = new_constructor(m, CHECK_NULL);
-        if (constr == NULL) {
-          return NULL;
-        } else {
-          h_result->obj_at_put(--count, constr);
-        }
-      }
-    }
-    assert(count == 0, "just checking");
-  }
-  return h_result();
-}
-
-
 // This would be nicer if, say, java.lang.reflect.Method was a subclass
 // of java.lang.reflect.Constructor
 
@@ -1647,6 +1124,3 @@
   invoke(klass, method, receiver, override, ptypes, T_VOID, args, false, CHECK_NULL);
   return receiver();
 }
-
-
-#endif /* SUPPORT_OLD_REFLECTION */
--- a/src/share/vm/runtime/reflection.hpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/runtime/reflection.hpp	Wed Sep 07 11:52:00 2011 -0700
@@ -27,7 +27,6 @@
 
 #include "oops/oop.hpp"
 #include "runtime/fieldDescriptor.hpp"
-#include "runtime/reflectionCompat.hpp"
 #include "utilities/accessFlags.hpp"
 #include "utilities/growableArray.hpp"
 
@@ -120,16 +119,6 @@
   // Create a java.lang.reflect.Field object based on a field descriptor
   static oop new_field(fieldDescriptor* fd, bool intern_name, TRAPS);
 
-  //---------------------------------------------------------------------------
-  //
-  // Support for old native code-based reflection (pre-JDK 1.4)
-  //
-  // NOTE: the method and constructor invocation code is still used
-  // for startup time reasons; see reflectionCompat.hpp.
-  //
-  //---------------------------------------------------------------------------
-
-#ifdef SUPPORT_OLD_REFLECTION
 private:
   // method resolution for invoke
   static methodHandle resolve_interface_call(instanceKlassHandle klass, methodHandle method, KlassHandle recv_klass, Handle receiver, TRAPS);
@@ -144,35 +133,11 @@
   // Conversion
   static BasicType basic_type_mirror_to_basic_type(oop basic_type_mirror, TRAPS);
 
-  static bool match_parameter_types(methodHandle method, objArrayHandle types, int parameter_count, TRAPS);
-  // Creating new java.lang.reflect.xxx wrappers
-  static oop new_field(FieldStream* st, TRAPS);
-
 public:
-  // Field lookup and verification.
-  static bool      resolve_field(Handle field_mirror, Handle& receiver, fieldDescriptor* fd, bool check_final, TRAPS);
-
-  // Reflective field access. Returns type code. Throws IllegalArgumentException.
-  static BasicType field_get(jvalue* value, fieldDescriptor* fd, Handle receiver);
-  static void      field_set(jvalue* value, fieldDescriptor* fd, Handle receiver, BasicType value_type, TRAPS);
-
-  // Reflective lookup of fields. Returns java.lang.reflect.Field instances.
-  static oop         reflect_field(oop mirror, Symbol* field_name, jint which, TRAPS);
-  static objArrayOop reflect_fields(oop mirror, jint which, TRAPS);
-
-  // Reflective lookup of methods. Returns java.lang.reflect.Method instances.
-  static oop         reflect_method(oop mirror, Symbol* method_name, objArrayHandle types, jint which, TRAPS);
-  static objArrayOop reflect_methods(oop mirror, jint which, TRAPS);
-
-  // Reflective lookup of constructors. Returns java.lang.reflect.Constructor instances.
-  static oop         reflect_constructor(oop mirror, objArrayHandle types, jint which, TRAPS);
-  static objArrayOop reflect_constructors(oop mirror, jint which, TRAPS);
-
   // Method invokation through java.lang.reflect.Method
   static oop      invoke_method(oop method_mirror, Handle receiver, objArrayHandle args, TRAPS);
   // Method invokation through java.lang.reflect.Constructor
   static oop      invoke_constructor(oop method_mirror, objArrayHandle args, TRAPS);
-#endif /* SUPPORT_OLD_REFLECTION */
 
 };
 
--- a/src/share/vm/runtime/reflectionCompat.hpp	Fri Sep 02 21:33:57 2011 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_VM_RUNTIME_REFLECTIONCOMPAT_HPP
-#define SHARE_VM_RUNTIME_REFLECTIONCOMPAT_HPP
-
-// During the development of the JDK 1.4 reflection implementation
-// based on dynamic bytecode generation, it was hoped that the bulk of
-// the native code for reflection could be removed. Unfortunately
-// there is currently a significant cost associated with loading the
-// stub classes which impacts startup time. Until this cost can be
-// reduced, the JVM entry points JVM_InvokeMethod and
-// JVM_NewInstanceFromConstructor are still needed; these and their
-// dependents currently constitute the bulk of the native code for
-// reflection. If this cost is reduced in the future, the
-// NativeMethodAccessorImpl and NativeConstructorAccessorImpl classes
-// can be removed from sun.reflect and all of the code guarded by this
-// flag removed from the product build. (Non-product builds,
-// specifically the "optimized" target, would retain the code so they
-// could be dropped into earlier JDKs for comparative benchmarking.)
-
-//#ifndef PRODUCT
-# define SUPPORT_OLD_REFLECTION
-//#endif
-
-#endif // SHARE_VM_RUNTIME_REFLECTIONCOMPAT_HPP
--- a/src/share/vm/runtime/sharedRuntime.hpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/runtime/sharedRuntime.hpp	Wed Sep 07 11:52:00 2011 -0700
@@ -45,6 +45,8 @@
 // information, etc.
 
 class SharedRuntime: AllStatic {
+  friend class VMStructs;
+
  private:
   static methodHandle resolve_sub_helper(JavaThread *thread,
                                      bool is_virtual,
--- a/src/share/vm/runtime/stubRoutines.cpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/runtime/stubRoutines.cpp	Wed Sep 07 11:52:00 2011 -0700
@@ -108,6 +108,7 @@
 address StubRoutines::_arrayof_oop_disjoint_arraycopy    = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_oop_copy);
 address StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit  = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_oop_copy_uninit);
 
+address StubRoutines::_zero_aligned_words = CAST_FROM_FN_PTR(address, Copy::zero_to_words);
 
 address StubRoutines::_checkcast_arraycopy               = NULL;
 address StubRoutines::_checkcast_arraycopy_uninit        = NULL;
--- a/src/share/vm/runtime/stubRoutines.hpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/runtime/stubRoutines.hpp	Wed Sep 07 11:52:00 2011 -0700
@@ -199,6 +199,9 @@
   static address _arrayof_jshort_fill;
   static address _arrayof_jint_fill;
 
+  // zero heap space aligned to jlong (8 bytes)
+  static address _zero_aligned_words;
+
   // These are versions of the java.lang.Math methods which perform
   // the same operations as the intrinsic version.  They are used for
   // constant folding in the compiler to ensure equivalence.  If the
@@ -332,6 +335,7 @@
 
   static address select_fill_function(BasicType t, bool aligned, const char* &name);
 
+  static address zero_aligned_words()   { return _zero_aligned_words; }
 
   static double  intrinsic_log(double d) {
     assert(_intrinsic_log != NULL, "must be defined");
--- a/src/share/vm/runtime/thread.cpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/runtime/thread.cpp	Wed Sep 07 11:52:00 2011 -0700
@@ -1272,7 +1272,6 @@
   _exception_oop = NULL;
   _exception_pc  = 0;
   _exception_handler_pc = 0;
-  _exception_stack_size = 0;
   _is_method_handle_return = 0;
   _jvmti_thread_state= NULL;
   _should_post_on_exceptions_flag = JNI_FALSE;
@@ -2860,6 +2859,44 @@
   }
 }
 
+class PrintAndVerifyOopClosure: public OopClosure {
+ protected:
+  template <class T> inline void do_oop_work(T* p) {
+    oop obj = oopDesc::load_decode_heap_oop(p);
+    if (obj == NULL) return;
+    tty->print(INTPTR_FORMAT ": ", p);
+    if (obj->is_oop_or_null()) {
+      if (obj->is_objArray()) {
+        tty->print_cr("valid objArray: " INTPTR_FORMAT, (oopDesc*) obj);
+      } else {
+        obj->print();
+      }
+    } else {
+      tty->print_cr("invalid oop: " INTPTR_FORMAT, (oopDesc*) obj);
+    }
+    tty->cr();
+  }
+ public:
+  virtual void do_oop(oop* p) { do_oop_work(p); }
+  virtual void do_oop(narrowOop* p)  { do_oop_work(p); }
+};
+
+
+static void oops_print(frame* f, const RegisterMap *map) {
+  PrintAndVerifyOopClosure print;
+  f->print_value();
+  f->oops_do(&print, NULL, (RegisterMap*)map);
+}
+
+// Print our all the locations that contain oops and whether they are
+// valid or not.  This useful when trying to find the oldest frame
+// where an oop has gone bad since the frame walk is from youngest to
+// oldest.
+void JavaThread::trace_oops() {
+  tty->print_cr("[Trace oops]");
+  frames_do(oops_print);
+}
+
 
 #ifdef ASSERT
 // Print or validate the layout of stack frames
--- a/src/share/vm/runtime/thread.hpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/runtime/thread.hpp	Wed Sep 07 11:52:00 2011 -0700
@@ -841,7 +841,6 @@
   volatile oop     _exception_oop;               // Exception thrown in compiled code
   volatile address _exception_pc;                // PC where exception happened
   volatile address _exception_handler_pc;        // PC for handler of exception
-  volatile int     _exception_stack_size;        // Size of frame where exception happened
   volatile int     _is_method_handle_return;     // true (== 1) if the current exception PC is a MethodHandle call site.
 
   // support for compilation
@@ -1182,7 +1181,6 @@
 
   // Exception handling for compiled methods
   oop      exception_oop() const                 { return _exception_oop; }
-  int      exception_stack_size() const          { return _exception_stack_size; }
   address  exception_pc() const                  { return _exception_pc; }
   address  exception_handler_pc() const          { return _exception_handler_pc; }
   bool     is_method_handle_return() const       { return _is_method_handle_return == 1; }
@@ -1190,7 +1188,6 @@
   void set_exception_oop(oop o)                  { _exception_oop = o; }
   void set_exception_pc(address a)               { _exception_pc = a; }
   void set_exception_handler_pc(address a)       { _exception_handler_pc = a; }
-  void set_exception_stack_size(int size)        { _exception_stack_size = size; }
   void set_is_method_handle_return(bool value)   { _is_method_handle_return = value ? 1 : 0; }
 
   // Stack overflow support
@@ -1264,7 +1261,6 @@
   static ByteSize exception_oop_offset()         { return byte_offset_of(JavaThread, _exception_oop       ); }
   static ByteSize exception_pc_offset()          { return byte_offset_of(JavaThread, _exception_pc        ); }
   static ByteSize exception_handler_pc_offset()  { return byte_offset_of(JavaThread, _exception_handler_pc); }
-  static ByteSize exception_stack_size_offset()  { return byte_offset_of(JavaThread, _exception_stack_size); }
   static ByteSize is_method_handle_return_offset() { return byte_offset_of(JavaThread, _is_method_handle_return); }
   static ByteSize stack_guard_state_offset()     { return byte_offset_of(JavaThread, _stack_guard_state   ); }
   static ByteSize suspend_flags_offset()         { return byte_offset_of(JavaThread, _suspend_flags       ); }
@@ -1379,6 +1375,7 @@
   void trace_stack()                             PRODUCT_RETURN;
   void trace_stack_from(vframe* start_vf)        PRODUCT_RETURN;
   void trace_frames()                            PRODUCT_RETURN;
+  void trace_oops()                              PRODUCT_RETURN;
 
   // Print an annotated view of the stack frames
   void print_frame_layout(int depth = 0, bool validate_only = false) NOT_DEBUG_RETURN;
--- a/src/share/vm/runtime/vmStructs.cpp	Fri Sep 02 21:33:57 2011 -0700
+++ b/src/share/vm/runtime/vmStructs.cpp	Wed Sep 07 11:52:00 2011 -0700
@@ -652,6 +652,7 @@
       static_field(SystemDictionary,            WK_KLASS(ThreadGroup_klass),                   klassOop)                             \
       static_field(SystemDictionary,            WK_KLASS(Properties_klass),                    klassOop)                             \
       static_field(SystemDictionary,            WK_KLASS(StringBuffer_klass),                  klassOop)                             \
+      static_field(SystemDictionary,            WK_KLASS(MethodHandle_klass),                  klassOop)                             \
       static_field(SystemDictionary,            _box_klasses[0],                               klassOop)                             \
       static_field(SystemDictionary,            _java_system_loader,                           oop)                                  \
                                                                                                                                      \
@@ -757,12 +758,19 @@
   nonstatic_field(PcDesc,                      _pc_offset,                                    int)                                   \
   nonstatic_field(PcDesc,                      _scope_decode_offset,                          int)                                   \
   nonstatic_field(PcDesc,                      _obj_decode_offset,                            int)                                   \
-  nonstatic_field(PcDesc,                      _flags,                        PcDesc::PcDescFlags)                                   \
+  nonstatic_field(PcDesc,                      _flags,                                        int)                                   \
                                                                                                                                      \
   /***************************************************/                                                                              \
   /* CodeBlobs (NOTE: incomplete, but only a little) */                                                                              \
   /***************************************************/                                                                              \
                                                                                                                                      \
+  X86_ONLY(nonstatic_field(MethodHandles::RicochetFrame, _sender_pc,                                     address))                   \
+  X86_ONLY(nonstatic_field(MethodHandles::RicochetFrame, _exact_sender_sp,                              intptr_t*))                  \
+  X86_ONLY(nonstatic_field(MethodHandles::RicochetFrame, _sender_link,                                  intptr_t*))                  \
+  X86_ONLY(nonstatic_field(MethodHandles::RicochetFrame, _saved_args_base,                              intptr_t*))                  \
+                                                                                                                                     \
+     static_field(SharedRuntime,               _ricochet_blob,                                RicochetBlob*)                         \
+                                                                                                                                     \
   nonstatic_field(CodeBlob,                    _name,                                         const char*)                           \
   nonstatic_field(CodeBlob,                    _size,                                         int)                                   \
   nonstatic_field(CodeBlob,                    _header_size,                                  int)                                   \
@@ -774,6 +782,8 @@
   nonstatic_field(CodeBlob,                    _frame_size,                                   int)                                   \
   nonstatic_field(CodeBlob,                    _oop_maps,                                     OopMapSet*)                            \
                                                                                                                                      \
+  nonstatic_field(RuntimeStub,                 _caller_must_gc_arguments,                     bool)                                  \
+                                                                                                                                     \
   /**************************************************/                                                                               \
   /* NMethods (NOTE: incomplete, but only a little) */                                                                               \
   /**************************************************/                                                                               \
@@ -786,6 +796,7 @@
   nonstatic_field(nmethod,             _state,                                        unsigned char)                         \
   nonstatic_field(nmethod,             _exception_offset,                             int)                                   \
   nonstatic_field(nmethod,             _deoptimize_offset,                            int)                                   \
+  nonstatic_field(nmethod,             _deoptimize_mh_offset,                         int)                                   \
   nonstatic_field(nmethod,             _orig_pc_offset,                               int)                                   \
   nonstatic_field(nmethod,             _stub_offset,                                  int)                                   \
   nonstatic_field(nmethod,             _consts_offset,                                int)                                   \
@@ -804,6 +815,9 @@
   nonstatic_field(nmethod,             _compile_id,                                   int)                                   \
   nonstatic_field(nmethod,             _marked_for_deoptimization,                    bool)                                  \
                                                                                                                                      \
+  nonstatic_field(RicochetBlob,        _bounce_offset,                                int)                                           \
+  nonstatic_field(RicochetBlob,        _exception_offset,                             int)                                           \
+                                                                                                                                     \
   /********************************/                                                                                                 \
   /* JavaCalls (NOTE: incomplete) */                                                                                                 \
   /********************************/                                                                                                 \
@@ -1310,24 +1324,27 @@
   /* CodeBlob hierarchy (needed for run-time type information) */         \
   /*************************************************************/         \
                                                                           \
+  declare_toplevel_type(SharedRuntime)                                    \
+  X86_ONLY(declare_toplevel_type(MethodHandles::RicochetFrame))           \
+                                                                          \
   declare_toplevel_type(CodeBlob)                                         \
-  declare_type(BufferBlob,            CodeBlob)                           \
-  declare_type(AdapterBlob,           BufferBlob)                         \
-  declare_type(nmethod,               CodeBlob)                           \
-  declare_type(RuntimeStub,           CodeBlob)                           \
-  declare_type(SingletonBlob,         CodeBlob)                           \
-  declare_type(SafepointBlob,         SingletonBlob)                      \
-  declare_type(DeoptimizationBlob,    SingletonBlob)                      \
-  declare_type(RicochetBlob,          SingletonBlob)                      \
-  declare_c2_type(ExceptionBlob,      SingletonBlob)                      \
-  declare_c2_type(UncommonTrapBlob,   CodeBlob)                           \
+  declare_type(BufferBlob,               CodeBlob)                        \
+  declare_type(AdapterBlob,              BufferBlob)                      \
+  declare_type(MethodHandlesAdapterBlob, BufferBlob)                      \
+  declare_type(nmethod,                  CodeBlob)                        \
+  declare_type(RuntimeStub,              CodeBlob)                        \
+  declare_type(SingletonBlob,            CodeBlob)                        \
+  declare_type(SafepointBlob,            SingletonBlob)                   \
+  declare_type(DeoptimizationBlob,       SingletonBlob)                   \
+  declare_type(RicochetBlob,             SingletonBlob)                   \
+  declare_c2_type(ExceptionBlob,         SingletonBlob)                   \
+  declare_c2_type(UncommonTrapBlob,      CodeBlob)                        \
                                                                           \
   /***************************************/                               \
   /* PcDesc and other compiled code info */                               \
   /***************************************/                               \
                                                                           \
   declare_toplevel_type(PcDesc)                                           \
-  declare_integer_type(PcDesc::PcDescFlags)                               \
                                                                           \
   /************************/                                              \
   /* OopMap and OopMapSet */                                              \
@@ -1796,6 +1813,21 @@
                                                                           \
   declare_constant(ObjectSynchronizer::_BLOCKSIZE)                        \
                                                                           \
+  /**********************/                                                \
+  /* PcDesc             */                                                \
+  /**********************/                                                \
+                                                                          \
+  declare_constant(PcDesc::PCDESC_reexecute)                              \
+  declare_constant(PcDesc::PCDESC_is_method_handle_invoke)                \
+  declare_constant(PcDesc::PCDESC_return_oop)                             \
+                                                                          \
+  /**********************/                                                \
+  /* frame              */                                                \
+  /**********************/                                                \
+                                                                          \
+  X86_ONLY(declare_constant(frame::entry_frame_call_wrapper_offset))      \
+  declare_constant(frame::pc_return_offset)                               \
+                                                                          \
   /********************************/                                      \
   /* Calling convention constants */                                      \
   /********************************/                                      \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/compiler/7082949/Test7082949.java	Wed Sep 07 11:52:00 2011 -0700
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ *
+ */
+
+/**
+ * @test
+ * @bug 7082949
+ * @summary JSR 292: missing ResourceMark in methodOopDesc::make_invoke_method
+ *
+ * @run main Test7082949
+ */
+
+import java.lang.invoke.*;
+import static java.lang.invoke.MethodHandles.*;
+import static java.lang.invoke.MethodType.*;
+
+public class Test7082949 implements Runnable {
+    public static void main(String... args) throws Throwable {
+        new Thread(new Test7082949()).start();
+    }
+
+    public static Test7082949 test() {
+        return null;
+    }
+
+    public void run() {
+        try {
+            MethodHandle m1 = MethodHandles.lookup().findStatic(Test7082949.class, "test",  methodType(Test7082949.class));
+            Test7082949 v = (Test7082949)m1.invokeExact();
+        } catch (Throwable t) {
+            t.printStackTrace();
+        }
+    }
+}