6829187: compiler optimizations required for JSR 292
authortwisti
Tue, 05 Jan 2010 13:05:58 +0100
changeset 4566 b363f6ef4068
parent 4565 cbb3fed38514
child 4567 7fc02fbe5c7a
6829187: compiler optimizations required for JSR 292 Summary: C2 implementation for invokedynamic support. Reviewed-by: kvn, never
hotspot/src/cpu/sparc/vm/sparc.ad
hotspot/src/cpu/x86/vm/frame_x86.inline.hpp
hotspot/src/cpu/x86/vm/x86_32.ad
hotspot/src/cpu/x86/vm/x86_64.ad
hotspot/src/share/vm/ci/ciCPCache.cpp
hotspot/src/share/vm/ci/ciCPCache.hpp
hotspot/src/share/vm/ci/ciClassList.hpp
hotspot/src/share/vm/ci/ciEnv.cpp
hotspot/src/share/vm/ci/ciEnv.hpp
hotspot/src/share/vm/ci/ciMethod.cpp
hotspot/src/share/vm/ci/ciMethod.hpp
hotspot/src/share/vm/ci/ciObject.hpp
hotspot/src/share/vm/ci/ciObjectFactory.cpp
hotspot/src/share/vm/ci/ciStreams.cpp
hotspot/src/share/vm/ci/ciStreams.hpp
hotspot/src/share/vm/ci/ciTypeFlow.cpp
hotspot/src/share/vm/includeDB_compiler2
hotspot/src/share/vm/includeDB_core
hotspot/src/share/vm/opto/bytecodeInfo.cpp
hotspot/src/share/vm/opto/callGenerator.cpp
hotspot/src/share/vm/opto/callGenerator.hpp
hotspot/src/share/vm/opto/callnode.hpp
hotspot/src/share/vm/opto/doCall.cpp
hotspot/src/share/vm/opto/graphKit.cpp
hotspot/src/share/vm/opto/lcm.cpp
hotspot/src/share/vm/opto/machnode.cpp
hotspot/src/share/vm/opto/machnode.hpp
hotspot/src/share/vm/opto/matcher.cpp
hotspot/src/share/vm/opto/matcher.hpp
hotspot/src/share/vm/opto/output.cpp
hotspot/src/share/vm/opto/type.cpp
--- a/hotspot/src/cpu/sparc/vm/sparc.ad	Mon Jan 04 15:21:09 2010 -0800
+++ b/hotspot/src/cpu/sparc/vm/sparc.ad	Tue Jan 05 13:05:58 2010 +0100
@@ -1885,6 +1885,10 @@
   return RegMask();
 }
 
+const RegMask Matcher::method_handle_invoke_SP_save_mask() {
+  return RegMask();
+}
+
 %}
 
 
--- a/hotspot/src/cpu/x86/vm/frame_x86.inline.hpp	Mon Jan 04 15:21:09 2010 -0800
+++ b/hotspot/src/cpu/x86/vm/frame_x86.inline.hpp	Tue Jan 05 13:05:58 2010 +0100
@@ -225,11 +225,12 @@
 // top of expression stack
 inline intptr_t* frame::interpreter_frame_tos_address() const {
   intptr_t* last_sp = interpreter_frame_last_sp();
-  if (last_sp == NULL ) {
+  if (last_sp == NULL) {
     return sp();
   } else {
-    // sp() may have been extended by an adapter
-    assert(last_sp < fp() && last_sp >= sp(), "bad tos");
+    // sp() may have been extended or shrunk by an adapter.  At least
+    // check that we don't fall behind the legal region.
+    assert(last_sp < (intptr_t*) interpreter_frame_monitor_begin(), "bad tos");
     return last_sp;
   }
 }
--- a/hotspot/src/cpu/x86/vm/x86_32.ad	Mon Jan 04 15:21:09 2010 -0800
+++ b/hotspot/src/cpu/x86/vm/x86_32.ad	Tue Jan 05 13:05:58 2010 +0100
@@ -268,22 +268,36 @@
 static jlong *float_signflip_pool  = double_quadword(&fp_signmask_pool[3*2], CONST64(0x8000000080000000), CONST64(0x8000000080000000));
 static jlong *double_signflip_pool = double_quadword(&fp_signmask_pool[4*2], CONST64(0x8000000000000000), CONST64(0x8000000000000000));
 
+// Offset hacking within calls.
+static int pre_call_FPU_size() {
+  if (Compile::current()->in_24_bit_fp_mode())
+    return 6; // fldcw
+  return 0;
+}
+
+static int preserve_SP_size() {
+  return LP64_ONLY(1 +) 2;  // [rex,] op, rm(reg/reg)
+}
+
 // !!!!! Special hack to get all type of calls to specify the byte offset
 //       from the start of the call to the point where the return address
 //       will point.
 int MachCallStaticJavaNode::ret_addr_offset() {
-  return 5 + (Compile::current()->in_24_bit_fp_mode() ? 6 : 0);  // 5 bytes from start of call to where return address points
+  int offset = 5 + pre_call_FPU_size();  // 5 bytes from start of call to where return address points
+  if (_method_handle_invoke)
+    offset += preserve_SP_size();
+  return offset;
 }
 
 int MachCallDynamicJavaNode::ret_addr_offset() {
-  return 10 + (Compile::current()->in_24_bit_fp_mode() ? 6 : 0);  // 10 bytes from start of call to where return address points
+  return 10 + pre_call_FPU_size();  // 10 bytes from start of call to where return address points
 }
 
 static int sizeof_FFree_Float_Stack_All = -1;
 
 int MachCallRuntimeNode::ret_addr_offset() {
   assert(sizeof_FFree_Float_Stack_All != -1, "must have been emitted already");
-  return sizeof_FFree_Float_Stack_All + 5 + (Compile::current()->in_24_bit_fp_mode() ? 6 : 0);
+  return sizeof_FFree_Float_Stack_All + 5 + pre_call_FPU_size();
 }
 
 // Indicate if the safepoint node needs the polling page as an input.
@@ -299,8 +313,16 @@
 // The address of the call instruction needs to be 4-byte aligned to
 // ensure that it does not span a cache line so that it can be patched.
 int CallStaticJavaDirectNode::compute_padding(int current_offset) const {
-  if (Compile::current()->in_24_bit_fp_mode())
-    current_offset += 6;    // skip fldcw in pre_call_FPU, if any
+  current_offset += pre_call_FPU_size();  // skip fldcw, if any
+  current_offset += 1;      // skip call opcode byte
+  return round_to(current_offset, alignment_required()) - current_offset;
+}
+
+// The address of the call instruction needs to be 4-byte aligned to
+// ensure that it does not span a cache line so that it can be patched.
+int CallStaticJavaHandleNode::compute_padding(int current_offset) const {
+  current_offset += pre_call_FPU_size();  // skip fldcw, if any
+  current_offset += preserve_SP_size();   // skip mov rbp, rsp
   current_offset += 1;      // skip call opcode byte
   return round_to(current_offset, alignment_required()) - current_offset;
 }
@@ -308,8 +330,7 @@
 // The address of the call instruction needs to be 4-byte aligned to
 // ensure that it does not span a cache line so that it can be patched.
 int CallDynamicJavaDirectNode::compute_padding(int current_offset) const {
-  if (Compile::current()->in_24_bit_fp_mode())
-    current_offset += 6;    // skip fldcw in pre_call_FPU, if any
+  current_offset += pre_call_FPU_size();  // skip fldcw, if any
   current_offset += 5;      // skip MOV instruction
   current_offset += 1;      // skip call opcode byte
   return round_to(current_offset, alignment_required()) - current_offset;
@@ -1460,6 +1481,10 @@
   return RegMask();
 }
 
+const RegMask Matcher::method_handle_invoke_SP_save_mask() {
+  return EBP_REG_mask;
+}
+
 %}
 
 //----------ENCODING BLOCK-----------------------------------------------------
@@ -1772,10 +1797,13 @@
 
   enc_class pre_call_FPU %{
     // If method sets FPU control word restore it here
+    debug_only(int off0 = cbuf.code_size());
     if( Compile::current()->in_24_bit_fp_mode() ) {
       MacroAssembler masm(&cbuf);
       masm.fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_std()));
     }
+    debug_only(int off1 = cbuf.code_size());
+    assert(off1 - off0 == pre_call_FPU_size(), "correct size prediction");
   %}
 
   enc_class post_call_FPU %{
@@ -1786,6 +1814,21 @@
     }
   %}
 
+  enc_class preserve_SP %{
+    debug_only(int off0 = cbuf.code_size());
+    MacroAssembler _masm(&cbuf);
+    // RBP is preserved across all calls, even compiled calls.
+    // Use it to preserve RSP in places where the callee might change the SP.
+    __ movptr(rbp, rsp);
+    debug_only(int off1 = cbuf.code_size());
+    assert(off1 - off0 == preserve_SP_size(), "correct size prediction");
+  %}
+
+  enc_class restore_SP %{
+    MacroAssembler _masm(&cbuf);
+    __ movptr(rsp, rbp);
+  %}
+
   enc_class Java_Static_Call (method meth) %{    // JAVA STATIC CALL
     // CALL to fixup routine.  Fixup routine uses ScopeDesc info to determine
     // who we intended to call.
@@ -13406,6 +13449,7 @@
 //       compute_padding() functions will have to be adjusted.
 instruct CallStaticJavaDirect(method meth) %{
   match(CallStaticJava);
+  predicate(! ((CallStaticJavaNode*)n)->is_method_handle_invoke());
   effect(USE meth);
 
   ins_cost(300);
@@ -13420,6 +13464,30 @@
   ins_alignment(4);
 %}
 
+// Call Java Static Instruction (method handle version)
+// Note: If this code changes, the corresponding ret_addr_offset() and
+//       compute_padding() functions will have to be adjusted.
+instruct CallStaticJavaHandle(method meth, eBPRegP ebp) %{
+  match(CallStaticJava);
+  predicate(((CallStaticJavaNode*)n)->is_method_handle_invoke());
+  effect(USE meth);
+  // EBP is saved by all callees (for interpreter stack correction).
+  // We use it here for a similar purpose, in {preserve,restore}_SP.
+
+  ins_cost(300);
+  format %{ "CALL,static/MethodHandle " %}
+  opcode(0xE8); /* E8 cd */
+  ins_encode( pre_call_FPU,
+              preserve_SP,
+              Java_Static_Call( meth ),
+              restore_SP,
+              call_epilog,
+              post_call_FPU );
+  ins_pipe( pipe_slow );
+  ins_pc_relative(1);
+  ins_alignment(4);
+%}
+
 // Call Java Dynamic Instruction
 // Note: If this code changes, the corresponding ret_addr_offset() and
 //       compute_padding() functions will have to be adjusted.
--- a/hotspot/src/cpu/x86/vm/x86_64.ad	Mon Jan 04 15:21:09 2010 -0800
+++ b/hotspot/src/cpu/x86/vm/x86_64.ad	Tue Jan 05 13:05:58 2010 +0100
@@ -551,12 +551,19 @@
 
 #define __ _masm.
 
+static int preserve_SP_size() {
+  return LP64_ONLY(1 +) 2;  // [rex,] op, rm(reg/reg)
+}
+
 // !!!!! Special hack to get all types of calls to specify the byte offset
 //       from the start of the call to the point where the return address
 //       will point.
 int MachCallStaticJavaNode::ret_addr_offset()
 {
-  return 5; // 5 bytes from start of call to where return address points
+  int offset = 5; // 5 bytes from start of call to where return address points
+  if (_method_handle_invoke)
+    offset += preserve_SP_size();
+  return offset;
 }
 
 int MachCallDynamicJavaNode::ret_addr_offset()
@@ -589,6 +596,15 @@
 
 // The address of the call instruction needs to be 4-byte aligned to
 // ensure that it does not span a cache line so that it can be patched.
+int CallStaticJavaHandleNode::compute_padding(int current_offset) const
+{
+  current_offset += preserve_SP_size();   // skip mov rbp, rsp
+  current_offset += 1; // skip call opcode byte
+  return round_to(current_offset, alignment_required()) - current_offset;
+}
+
+// The address of the call instruction needs to be 4-byte aligned to
+// ensure that it does not span a cache line so that it can be patched.
 int CallDynamicJavaDirectNode::compute_padding(int current_offset) const
 {
   current_offset += 11; // skip movq instruction + call opcode byte
@@ -2113,6 +2129,10 @@
   return LONG_RDX_REG_mask;
 }
 
+const RegMask Matcher::method_handle_invoke_SP_save_mask() {
+  return PTR_RBP_REG_mask;
+}
+
 static Address build_address(int b, int i, int s, int d) {
   Register index = as_Register(i);
   Address::ScaleFactor scale = (Address::ScaleFactor)s;
@@ -2608,6 +2628,21 @@
                    RELOC_DISP32);
   %}
 
+  enc_class preserve_SP %{
+    debug_only(int off0 = cbuf.code_size());
+    MacroAssembler _masm(&cbuf);
+    // RBP is preserved across all calls, even compiled calls.
+    // Use it to preserve RSP in places where the callee might change the SP.
+    __ movptr(rbp, rsp);
+    debug_only(int off1 = cbuf.code_size());
+    assert(off1 - off0 == preserve_SP_size(), "correct size prediction");
+  %}
+
+  enc_class restore_SP %{
+    MacroAssembler _masm(&cbuf);
+    __ movptr(rsp, rbp);
+  %}
+
   enc_class Java_Static_Call(method meth)
   %{
     // JAVA STATIC CALL
@@ -12526,9 +12561,9 @@
 // Call Java Static Instruction
 // Note: If this code changes, the corresponding ret_addr_offset() and
 //       compute_padding() functions will have to be adjusted.
-instruct CallStaticJavaDirect(method meth)
-%{
+instruct CallStaticJavaDirect(method meth) %{
   match(CallStaticJava);
+  predicate(!((CallStaticJavaNode*) n)->is_method_handle_invoke());
   effect(USE meth);
 
   ins_cost(300);
@@ -12540,6 +12575,28 @@
   ins_alignment(4);
 %}
 
+// Call Java Static Instruction (method handle version)
+// Note: If this code changes, the corresponding ret_addr_offset() and
+//       compute_padding() functions will have to be adjusted.
+instruct CallStaticJavaHandle(method meth, rbp_RegP rbp) %{
+  match(CallStaticJava);
+  predicate(((CallStaticJavaNode*) n)->is_method_handle_invoke());
+  effect(USE meth);
+  // RBP is saved by all callees (for interpreter stack correction).
+  // We use it here for a similar purpose, in {preserve,restore}_SP.
+
+  ins_cost(300);
+  format %{ "call,static/MethodHandle " %}
+  opcode(0xE8); /* E8 cd */
+  ins_encode(preserve_SP,
+             Java_Static_Call(meth),
+             restore_SP,
+             call_epilog);
+  ins_pipe(pipe_slow);
+  ins_pc_relative(1);
+  ins_alignment(4);
+%}
+
 // Call Java Dynamic Instruction
 // Note: If this code changes, the corresponding ret_addr_offset() and
 //       compute_padding() functions will have to be adjusted.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/ci/ciCPCache.cpp	Tue Jan 05 13:05:58 2010 +0100
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_ciCPCache.cpp.incl"
+
+// ciCPCache
+
+// ------------------------------------------------------------------
+// ciCPCache::get_f1_offset
+size_t ciCPCache::get_f1_offset(int index) {
+  // Calculate the offset from the constantPoolCacheOop to the f1
+  // field.
+  ByteSize f1_offset =
+    constantPoolCacheOopDesc::entry_offset(index) +
+    ConstantPoolCacheEntry::f1_offset();
+
+  return in_bytes(f1_offset);
+}
+
+// ------------------------------------------------------------------
+// ciCPCache::print
+//
+// Print debugging information about the cache.
+void ciCPCache::print() {
+  Unimplemented();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/ci/ciCPCache.hpp	Tue Jan 05 13:05:58 2010 +0100
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+// ciCPCache
+//
+// This class represents a constant pool cache.
+//
+// Note: This class is called ciCPCache as ciConstantPoolCache is used
+// for something different.
+class ciCPCache : public ciObject {
+public:
+  ciCPCache(constantPoolCacheHandle cpcache) : ciObject(cpcache) {}
+
+  // What kind of ciObject is this?
+  bool is_cpcache() const { return true; }
+
+  // Get the offset in bytes from the oop to the f1 field of the
+  // requested entry.
+  size_t get_f1_offset(int index);
+
+  void print();
+};
--- a/hotspot/src/share/vm/ci/ciClassList.hpp	Mon Jan 04 15:21:09 2010 -0800
+++ b/hotspot/src/share/vm/ci/ciClassList.hpp	Tue Jan 05 13:05:58 2010 +0100
@@ -25,6 +25,7 @@
 class ciEnv;
 class ciObjectFactory;
 class ciConstantPoolCache;
+class ciCPCache;
 
 class ciField;
 class ciConstant;
--- a/hotspot/src/share/vm/ci/ciEnv.cpp	Mon Jan 04 15:21:09 2010 -0800
+++ b/hotspot/src/share/vm/ci/ciEnv.cpp	Tue Jan 05 13:05:58 2010 +0100
@@ -41,6 +41,7 @@
 ciInstanceKlass* ciEnv::_ArrayStoreException;
 ciInstanceKlass* ciEnv::_Class;
 ciInstanceKlass* ciEnv::_ClassCastException;
+ciInstanceKlass* ciEnv::_InvokeDynamic;
 ciInstanceKlass* ciEnv::_Object;
 ciInstanceKlass* ciEnv::_Throwable;
 ciInstanceKlass* ciEnv::_Thread;
@@ -736,6 +737,35 @@
 
 
 // ------------------------------------------------------------------
+// ciEnv::get_fake_invokedynamic_method_impl
+ciMethod* ciEnv::get_fake_invokedynamic_method_impl(ciInstanceKlass* accessor,
+                                                    int index, Bytecodes::Code bc) {
+  assert(bc == Bytecodes::_invokedynamic, "must be invokedynamic");
+  assert(accessor->get_instanceKlass()->is_linked(), "must be linked before accessing constant pool");
+  constantPoolHandle cpool = accessor->get_instanceKlass()->constants();
+
+  // Get the CallSite from the constant pool cache.
+  ConstantPoolCacheEntry* cpc_entry = cpool->cache()->secondary_entry_at(index);
+  assert(cpc_entry != NULL && cpc_entry->is_secondary_entry(), "sanity");
+  Handle call_site = cpc_entry->f1();
+
+  // Call site might not be linked yet.
+  if (call_site.is_null()) {
+    ciInstanceKlass* mh_klass = get_object(SystemDictionary::MethodHandle_klass())->as_instance_klass();
+    ciSymbol*       sig_sym   = get_object(cpool->signature_ref_at(index))->as_symbol();
+    return get_unloaded_method(mh_klass, ciSymbol::invoke_name(), sig_sym);
+  }
+
+  // Get the methodOop from the CallSite.
+  methodOop method_oop = (methodOop) java_dyn_CallSite::vmmethod(call_site());
+  assert(method_oop != NULL, "sanity");
+  assert(method_oop->is_method_handle_invoke(), "consistent");
+
+  return get_object(method_oop)->as_method();
+}
+
+
+// ------------------------------------------------------------------
 // ciEnv::get_instance_klass_for_declared_method_holder
 ciInstanceKlass* ciEnv::get_instance_klass_for_declared_method_holder(ciKlass* method_holder) {
   // For the case of <array>.clone(), the method holder can be a ciArrayKlass
@@ -757,15 +787,18 @@
 }
 
 
-
-
 // ------------------------------------------------------------------
 // ciEnv::get_method_by_index
 ciMethod* ciEnv::get_method_by_index(ciInstanceKlass* accessor,
                                      int index, Bytecodes::Code bc) {
-  GUARDED_VM_ENTRY(return get_method_by_index_impl(accessor, index, bc);)
+  if (bc == Bytecodes::_invokedynamic) {
+    GUARDED_VM_ENTRY(return get_fake_invokedynamic_method_impl(accessor, index, bc);)
+  } else {
+    GUARDED_VM_ENTRY(return get_method_by_index_impl(accessor, index, bc);)
+  }
 }
 
+
 // ------------------------------------------------------------------
 // ciEnv::name_buffer
 char *ciEnv::name_buffer(int req_len) {
--- a/hotspot/src/share/vm/ci/ciEnv.hpp	Mon Jan 04 15:21:09 2010 -0800
+++ b/hotspot/src/share/vm/ci/ciEnv.hpp	Tue Jan 05 13:05:58 2010 +0100
@@ -77,6 +77,7 @@
   static ciInstanceKlass* _ArrayStoreException;
   static ciInstanceKlass* _Class;
   static ciInstanceKlass* _ClassCastException;
+  static ciInstanceKlass* _InvokeDynamic;
   static ciInstanceKlass* _Object;
   static ciInstanceKlass* _Throwable;
   static ciInstanceKlass* _Thread;
@@ -151,6 +152,8 @@
                                      int field_index);
   ciMethod*  get_method_by_index_impl(ciInstanceKlass* loading_klass,
                                       int method_index, Bytecodes::Code bc);
+  ciMethod*  get_fake_invokedynamic_method_impl(ciInstanceKlass* accessor,
+                                                int index, Bytecodes::Code bc);
 
   // Helper methods
   bool       check_klass_accessibility(ciKlass* accessing_klass,
@@ -301,6 +304,9 @@
   ciInstanceKlass* ClassCastException_klass() {
     return _ClassCastException;
   }
+  ciInstanceKlass* InvokeDynamic_klass() {
+    return _InvokeDynamic;
+  }
   ciInstanceKlass* Object_klass() {
     return _Object;
   }
--- a/hotspot/src/share/vm/ci/ciMethod.cpp	Mon Jan 04 15:21:09 2010 -0800
+++ b/hotspot/src/share/vm/ci/ciMethod.cpp	Tue Jan 05 13:05:58 2010 +0100
@@ -687,7 +687,7 @@
 // ------------------------------------------------------------------
 // invokedynamic support
 //
-bool ciMethod::is_method_handle_invoke() {
+bool ciMethod::is_method_handle_invoke() const {
   check_is_loaded();
   bool flag = ((flags().as_int() & JVM_MH_INVOKE_BITS) == JVM_MH_INVOKE_BITS);
 #ifdef ASSERT
--- a/hotspot/src/share/vm/ci/ciMethod.hpp	Mon Jan 04 15:21:09 2010 -0800
+++ b/hotspot/src/share/vm/ci/ciMethod.hpp	Tue Jan 05 13:05:58 2010 +0100
@@ -213,7 +213,7 @@
   bool check_call(int refinfo_index, bool is_static) const;
   void build_method_data();  // make sure it exists in the VM also
   int scale_count(int count, float prof_factor = 1.);  // make MDO count commensurate with IIC
-  bool is_method_handle_invoke();
+  bool is_method_handle_invoke() const;
   ciInstance* method_handle_type();
 
   // What kind of ciObject is this?
--- a/hotspot/src/share/vm/ci/ciObject.hpp	Mon Jan 04 15:21:09 2010 -0800
+++ b/hotspot/src/share/vm/ci/ciObject.hpp	Tue Jan 05 13:05:58 2010 +0100
@@ -131,6 +131,7 @@
 
   // What kind of ciObject is this?
   virtual bool is_null_object() const       { return false; }
+  virtual bool is_cpcache() const           { return false; }
   virtual bool is_instance()                { return false; }
   virtual bool is_method()                  { return false; }
   virtual bool is_method_data()             { return false; }
@@ -185,6 +186,10 @@
     assert(is_null_object(), "bad cast");
     return (ciNullObject*)this;
   }
+  ciCPCache*               as_cpcache() {
+    assert(is_cpcache(), "bad cast");
+    return (ciCPCache*) this;
+  }
   ciInstance*              as_instance() {
     assert(is_instance(), "bad cast");
     return (ciInstance*)this;
--- a/hotspot/src/share/vm/ci/ciObjectFactory.cpp	Mon Jan 04 15:21:09 2010 -0800
+++ b/hotspot/src/share/vm/ci/ciObjectFactory.cpp	Tue Jan 05 13:05:58 2010 +0100
@@ -153,6 +153,10 @@
   ciEnv::_ClassCastException =
     get(SystemDictionary::ClassCastException_klass())
       ->as_instance_klass();
+  if (EnableInvokeDynamic) {
+    ciEnv::_InvokeDynamic =
+      get(SystemDictionary::InvokeDynamic_klass())->as_instance_klass();
+  }
   ciEnv::_Object =
     get(SystemDictionary::object_klass())
       ->as_instance_klass();
@@ -340,6 +344,9 @@
   } else if (o->is_typeArray()) {
     typeArrayHandle h_ta(THREAD, (typeArrayOop)o);
     return new (arena()) ciTypeArray(h_ta);
+  } else if (o->is_constantPoolCache()) {
+    constantPoolCacheHandle h_cpc(THREAD, (constantPoolCacheOop) o);
+    return new (arena()) ciCPCache(h_cpc);
   }
 
   // The oop is of some type not supported by the compiler interface.
--- a/hotspot/src/share/vm/ci/ciStreams.cpp	Mon Jan 04 15:21:09 2010 -0800
+++ b/hotspot/src/share/vm/ci/ciStreams.cpp	Tue Jan 05 13:05:58 2010 +0100
@@ -321,7 +321,7 @@
 //
 // If this is a method invocation bytecode, get the invoked method.
 ciMethod* ciBytecodeStream::get_method(bool& will_link) {
-  ciMethod* m = CURRENT_ENV->get_method_by_index(_holder, get_method_index(),cur_bc());
+  ciMethod* m = CURRENT_ENV->get_method_by_index(_holder, get_method_index(), cur_bc());
   will_link = m->is_loaded();
   return m;
 }
@@ -370,3 +370,14 @@
   int name_and_type_index = cpool->name_and_type_ref_index_at(method_index);
   return cpool->signature_ref_index_at(name_and_type_index);
 }
+
+// ------------------------------------------------------------------
+// ciBytecodeStream::get_cpcache
+ciCPCache* ciBytecodeStream::get_cpcache() {
+  VM_ENTRY_MARK;
+  // Get the constant pool.
+  constantPoolOop      cpool   = _holder->get_instanceKlass()->constants();
+  constantPoolCacheOop cpcache = cpool->cache();
+
+  return CURRENT_ENV->get_object(cpcache)->as_cpcache();
+}
--- a/hotspot/src/share/vm/ci/ciStreams.hpp	Mon Jan 04 15:21:09 2010 -0800
+++ b/hotspot/src/share/vm/ci/ciStreams.hpp	Tue Jan 05 13:05:58 2010 +0100
@@ -232,6 +232,8 @@
   int       get_method_holder_index();
   int       get_method_signature_index();
 
+  ciCPCache* get_cpcache();
+
  private:
   void assert_index_size(int required_size) const {
 #ifdef ASSERT
--- a/hotspot/src/share/vm/ci/ciTypeFlow.cpp	Mon Jan 04 15:21:09 2010 -0800
+++ b/hotspot/src/share/vm/ci/ciTypeFlow.cpp	Tue Jan 05 13:05:58 2010 +0100
@@ -635,8 +635,15 @@
   ciMethod* method = str->get_method(will_link);
   if (!will_link) {
     // We weren't able to find the method.
-    ciKlass* unloaded_holder = method->holder();
-    trap(str, unloaded_holder, str->get_method_holder_index());
+    if (str->cur_bc() == Bytecodes::_invokedynamic) {
+      trap(str, NULL,
+           Deoptimization::make_trap_request
+           (Deoptimization::Reason_uninitialized,
+            Deoptimization::Action_reinterpret));
+    } else {
+      ciKlass* unloaded_holder = method->holder();
+      trap(str, unloaded_holder, str->get_method_holder_index());
+    }
   } else {
     ciSignature* signature = method->signature();
     ciSignatureStream sigstr(signature);
@@ -1292,8 +1299,8 @@
   case Bytecodes::_invokeinterface: do_invoke(str, true);           break;
   case Bytecodes::_invokespecial:   do_invoke(str, true);           break;
   case Bytecodes::_invokestatic:    do_invoke(str, false);          break;
-
   case Bytecodes::_invokevirtual:   do_invoke(str, true);           break;
+  case Bytecodes::_invokedynamic:   do_invoke(str, false);          break;
 
   case Bytecodes::_istore:   store_local_int(str->get_index());     break;
   case Bytecodes::_istore_0: store_local_int(0);                    break;
--- a/hotspot/src/share/vm/includeDB_compiler2	Mon Jan 04 15:21:09 2010 -0800
+++ b/hotspot/src/share/vm/includeDB_compiler2	Tue Jan 05 13:05:58 2010 +0100
@@ -155,6 +155,7 @@
 callGenerator.cpp                       cfgnode.hpp
 callGenerator.cpp                       compileLog.hpp
 callGenerator.cpp                       connode.hpp
+callGenerator.cpp                       ciCPCache.hpp
 callGenerator.cpp                       parse.hpp
 callGenerator.cpp                       rootnode.hpp
 callGenerator.cpp                       runtime.hpp
--- a/hotspot/src/share/vm/includeDB_core	Mon Jan 04 15:21:09 2010 -0800
+++ b/hotspot/src/share/vm/includeDB_core	Tue Jan 05 13:05:58 2010 +0100
@@ -532,6 +532,12 @@
 ciConstantPoolCache.hpp                 growableArray.hpp
 ciConstantPoolCache.hpp                 resourceArea.hpp
 
+ciCPCache.cpp                           cpCacheOop.hpp
+ciCPCache.cpp                           ciCPCache.hpp
+
+ciCPCache.hpp                           ciClassList.hpp
+ciCPCache.hpp                           ciObject.hpp
+
 ciEnv.cpp                               allocation.inline.hpp
 ciEnv.cpp                               ciConstant.hpp
 ciEnv.cpp                               ciEnv.hpp
@@ -755,6 +761,7 @@
 ciObject.hpp                            jniHandles.hpp
 
 ciObjectFactory.cpp                     allocation.inline.hpp
+ciObjectFactory.cpp                     ciCPCache.hpp
 ciObjectFactory.cpp                     ciInstance.hpp
 ciObjectFactory.cpp                     ciInstanceKlass.hpp
 ciObjectFactory.cpp                     ciInstanceKlassKlass.hpp
--- a/hotspot/src/share/vm/opto/bytecodeInfo.cpp	Mon Jan 04 15:21:09 2010 -0800
+++ b/hotspot/src/share/vm/opto/bytecodeInfo.cpp	Tue Jan 05 13:05:58 2010 +0100
@@ -322,14 +322,17 @@
     // stricter than callee_holder->is_initialized()
     ciBytecodeStream iter(caller_method);
     iter.force_bci(caller_bci);
-    int index = iter.get_index_int();
-    if( !caller_method->is_klass_loaded(index, true) ) {
-      return false;
-    }
-    // Try to do constant pool resolution if running Xcomp
     Bytecodes::Code call_bc = iter.cur_bc();
-    if( !caller_method->check_call(index, call_bc == Bytecodes::_invokestatic) ) {
-      return false;
+    // An invokedynamic instruction does not have a klass.
+    if (call_bc != Bytecodes::_invokedynamic) {
+      int index = iter.get_index_int();
+      if (!caller_method->is_klass_loaded(index, true)) {
+        return false;
+      }
+      // Try to do constant pool resolution if running Xcomp
+      if( !caller_method->check_call(index, call_bc == Bytecodes::_invokestatic) ) {
+        return false;
+      }
     }
   }
   // We will attempt to see if a class/field/etc got properly loaded.  If it
--- a/hotspot/src/share/vm/opto/callGenerator.cpp	Mon Jan 04 15:21:09 2010 -0800
+++ b/hotspot/src/share/vm/opto/callGenerator.cpp	Tue Jan 05 13:05:58 2010 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2000-2009 Sun Microsystems, Inc.  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
@@ -136,6 +136,8 @@
     }
     // Mark the call node as virtual, sort of:
     call->set_optimized_virtual(true);
+    if (method()->is_method_handle_invoke())
+      call->set_method_handle_invoke(true);
   }
   kit.set_arguments_for_java_call(call);
   kit.set_edges_for_java_call(call, false, _separate_io_proj);
@@ -145,6 +147,71 @@
   return kit.transfer_exceptions_into_jvms();
 }
 
+//---------------------------DynamicCallGenerator-----------------------------
+// Internal class which handles all out-of-line dynamic calls.
+class DynamicCallGenerator : public CallGenerator {
+public:
+  DynamicCallGenerator(ciMethod* method)
+    : CallGenerator(method)
+  {
+  }
+  virtual JVMState* generate(JVMState* jvms);
+};
+
+JVMState* DynamicCallGenerator::generate(JVMState* jvms) {
+  GraphKit kit(jvms);
+
+  if (kit.C->log() != NULL) {
+    kit.C->log()->elem("dynamic_call bci='%d'", jvms->bci());
+  }
+
+  // Get the constant pool cache from the caller class.
+  ciMethod* caller_method = jvms->method();
+  ciBytecodeStream str(caller_method);
+  str.force_bci(jvms->bci());  // Set the stream to the invokedynamic bci.
+  assert(str.cur_bc() == Bytecodes::_invokedynamic, "wrong place to issue a dynamic call!");
+  ciCPCache* cpcache = str.get_cpcache();
+
+  // Get the offset of the CallSite from the constant pool cache
+  // pointer.
+  int index = str.get_method_index();
+  size_t call_site_offset = cpcache->get_f1_offset(index);
+
+  // Load the CallSite object from the constant pool cache.
+  const TypeOopPtr* cpcache_ptr = TypeOopPtr::make_from_constant(cpcache);
+  Node* cpc = kit.makecon(cpcache_ptr);
+  Node* adr = kit.basic_plus_adr(cpc, cpc, call_site_offset);
+  Node* call_site = kit.make_load(kit.control(), adr, TypeInstPtr::BOTTOM, T_OBJECT, Compile::AliasIdxRaw);
+
+  // Load the MethodHandle (target) from the CallSite object.
+  Node* mh_adr = kit.basic_plus_adr(call_site, call_site, java_dyn_CallSite::target_offset_in_bytes());
+  Node* mh = kit.make_load(kit.control(), mh_adr, TypeInstPtr::BOTTOM, T_OBJECT);
+
+  address stub = SharedRuntime::get_resolve_opt_virtual_call_stub();
+
+  CallStaticJavaNode *call = new (kit.C, tf()->domain()->cnt()) CallStaticJavaNode(tf(), stub, method(), kit.bci());
+  // invokedynamic is treated as an optimized invokevirtual.
+  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);
+
+  // Pass the MethodHandle as first argument and shift the other
+  // arguments.
+  call->init_req(0 + TypeFunc::Parms, mh);
+  uint nargs = call->method()->arg_size();
+  for (uint i = 1; i < nargs; i++) {
+    Node* arg = kit.argument(i - 1);
+    call->init_req(i + TypeFunc::Parms, arg);
+  }
+
+  kit.set_edges_for_java_call(call);
+  Node* ret = kit.set_results_for_java_call(call);
+  kit.push_node(method()->return_type()->basic_type(), ret);
+  return kit.transfer_exceptions_into_jvms();
+}
+
+//--------------------------VirtualCallGenerator------------------------------
+// Internal class which handles all out-of-line calls checking receiver type.
 class VirtualCallGenerator : public CallGenerator {
 private:
   int _vtable_index;
@@ -159,8 +226,6 @@
   virtual JVMState* generate(JVMState* jvms);
 };
 
-//--------------------------VirtualCallGenerator------------------------------
-// Internal class which handles all out-of-line calls checking receiver type.
 JVMState* VirtualCallGenerator::generate(JVMState* jvms) {
   GraphKit kit(jvms);
   Node* receiver = kit.argument(0);
@@ -253,8 +318,14 @@
   return new DirectCallGenerator(m, separate_io_proj);
 }
 
+CallGenerator* CallGenerator::for_dynamic_call(ciMethod* m) {
+  assert(m->is_method_handle_invoke(), "for_dynamic_call mismatch");
+  return new DynamicCallGenerator(m);
+}
+
 CallGenerator* CallGenerator::for_virtual_call(ciMethod* m, int vtable_index) {
   assert(!m->is_static(), "for_virtual_call mismatch");
+  assert(!m->is_method_handle_invoke(), "should be a direct call");
   return new VirtualCallGenerator(m, vtable_index);
 }
 
--- a/hotspot/src/share/vm/opto/callGenerator.hpp	Mon Jan 04 15:21:09 2010 -0800
+++ b/hotspot/src/share/vm/opto/callGenerator.hpp	Tue Jan 05 13:05:58 2010 +0100
@@ -100,6 +100,7 @@
 
   // How to generate vanilla out-of-line call sites:
   static CallGenerator* for_direct_call(ciMethod* m, bool separate_io_projs = false);   // static, special
+  static CallGenerator* for_dynamic_call(ciMethod* m);   // invokedynamic
   static CallGenerator* for_virtual_call(ciMethod* m, int vtable_index);  // virtual, interface
 
   // How to generate a replace a direct call with an inline version
--- a/hotspot/src/share/vm/opto/callnode.hpp	Mon Jan 04 15:21:09 2010 -0800
+++ b/hotspot/src/share/vm/opto/callnode.hpp	Tue Jan 05 13:05:58 2010 +0100
@@ -562,12 +562,15 @@
   virtual uint size_of() const; // Size is bigger
 
   bool    _optimized_virtual;
+  bool    _method_handle_invoke;
   ciMethod* _method;            // Method being direct called
 public:
   const int       _bci;         // Byte Code Index of call byte code
   CallJavaNode(const TypeFunc* tf , address addr, ciMethod* method, int bci)
     : CallNode(tf, addr, TypePtr::BOTTOM),
-      _method(method), _bci(bci), _optimized_virtual(false)
+      _method(method), _bci(bci),
+      _optimized_virtual(false),
+      _method_handle_invoke(false)
   {
     init_class_id(Class_CallJava);
   }
@@ -577,6 +580,8 @@
   void  set_method(ciMethod *m)           { _method = m; }
   void  set_optimized_virtual(bool f)     { _optimized_virtual = f; }
   bool  is_optimized_virtual() const      { return _optimized_virtual; }
+  void  set_method_handle_invoke(bool f)  { _method_handle_invoke = f; }
+  bool  is_method_handle_invoke() const   { return _method_handle_invoke; }
 
 #ifndef PRODUCT
   virtual void  dump_spec(outputStream *st) const;
--- a/hotspot/src/share/vm/opto/doCall.cpp	Mon Jan 04 15:21:09 2010 -0800
+++ b/hotspot/src/share/vm/opto/doCall.cpp	Tue Jan 05 13:05:58 2010 +0100
@@ -228,6 +228,12 @@
   // Use a more generic tactic, like a simple call.
   if (call_is_virtual) {
     return CallGenerator::for_virtual_call(call_method, vtable_index);
+  } else if (call_method->is_method_handle_invoke()) {
+    if (jvms->method()->java_code_at_bci(jvms->bci()) == Bytecodes::_invokedynamic)
+      return CallGenerator::for_dynamic_call(call_method);
+    else
+      // %%% if the target MH is a compile-time constant, we should try to inline it
+      return CallGenerator::for_direct_call(call_method);
   } else {
     // Class Hierarchy Analysis or Type Profile reveals a unique target,
     // or it is a static or special call.
@@ -299,7 +305,7 @@
   // Interface classes can be loaded & linked and never get around to
   // being initialized.  Uncommon-trap for not-initialized static or
   // v-calls.  Let interface calls happen.
-  ciInstanceKlass* holder_klass  = dest_method->holder();
+  ciInstanceKlass* holder_klass = dest_method->holder();
   if (!holder_klass->is_initialized() &&
       !holder_klass->is_interface()) {
     uncommon_trap(Deoptimization::Reason_uninitialized,
@@ -307,14 +313,6 @@
                   holder_klass);
     return true;
   }
-  if (dest_method->is_method_handle_invoke()
-      && holder_klass->name() == ciSymbol::java_dyn_InvokeDynamic()) {
-    // FIXME: NYI
-    uncommon_trap(Deoptimization::Reason_unhandled,
-                  Deoptimization::Action_none,
-                  holder_klass);
-    return true;
-  }
 
   assert(dest_method->will_link(method()->holder(), klass, bc()), "dest_method: typeflow responsibility");
   return false;
@@ -333,6 +331,7 @@
   bool is_virtual = bc() == Bytecodes::_invokevirtual;
   bool is_virtual_or_interface = is_virtual || bc() == Bytecodes::_invokeinterface;
   bool has_receiver = is_virtual_or_interface || bc() == Bytecodes::_invokespecial;
+  bool is_invokedynamic = bc() == Bytecodes::_invokedynamic;
 
   // Find target being called
   bool             will_link;
@@ -341,7 +340,8 @@
   ciKlass* holder = iter().get_declared_method_holder();
   ciInstanceKlass* klass = ciEnv::get_instance_klass_for_declared_method_holder(holder);
 
-  int   nargs    = dest_method->arg_size();
+  int nargs = dest_method->arg_size();
+  if (is_invokedynamic)  nargs -= 1;
 
   // uncommon-trap when callee is unloaded, uninitialized or will not link
   // bailout when too many arguments for register representation
@@ -355,7 +355,7 @@
     return;
   }
   assert(holder_klass->is_loaded(), "");
-  assert(dest_method->is_static() == !has_receiver, "must match bc");
+  assert((dest_method->is_static() || is_invokedynamic) == !has_receiver , "must match bc");
   // Note: this takes into account invokeinterface of methods declared in java/lang/Object,
   // which should be invokevirtuals but according to the VM spec may be invokeinterfaces
   assert(holder_klass->is_interface() || holder_klass->super() == NULL || (bc() != Bytecodes::_invokeinterface), "must match bc");
--- a/hotspot/src/share/vm/opto/graphKit.cpp	Mon Jan 04 15:21:09 2010 -0800
+++ b/hotspot/src/share/vm/opto/graphKit.cpp	Tue Jan 05 13:05:58 2010 +0100
@@ -981,14 +981,19 @@
   case Bytecodes::_invokedynamic:
   case Bytecodes::_invokeinterface:
     {
-      bool is_static = (depth == 0);
       bool ignore;
       ciBytecodeStream iter(method());
       iter.reset_to_bci(bci());
       iter.next();
       ciMethod* method = iter.get_method(ignore);
       inputs = method->arg_size_no_receiver();
-      if (!is_static)  inputs += 1;
+      // Add a receiver argument, maybe:
+      if (code != Bytecodes::_invokestatic &&
+          code != Bytecodes::_invokedynamic)
+        inputs += 1;
+      // (Do not use ciMethod::arg_size(), because
+      // it might be an unloaded method, which doesn't
+      // know whether it is static or not.)
       int size = method->return_type()->size();
       depth = size - inputs;
     }
--- a/hotspot/src/share/vm/opto/lcm.cpp	Mon Jan 04 15:21:09 2010 -0800
+++ b/hotspot/src/share/vm/opto/lcm.cpp	Tue Jan 05 13:05:58 2010 +0100
@@ -542,6 +542,16 @@
   // pointers as far as the kill mask goes.
   bool exclude_soe = op == Op_CallRuntime;
 
+  // If the call is a MethodHandle invoke, we need to exclude the
+  // register which is used to save the SP value over MH invokes from
+  // the mask.  Otherwise this register could be used for
+  // deoptimization information.
+  if (op == Op_CallStaticJava) {
+    MachCallStaticJavaNode* mcallstaticjava = (MachCallStaticJavaNode*) mcall;
+    if (mcallstaticjava->_method_handle_invoke)
+      proj->_rout.OR(Matcher::method_handle_invoke_SP_save_mask());
+  }
+
   // Fill in the kill mask for the call
   for( OptoReg::Name r = OptoReg::Name(0); r < _last_Mach_Reg; r=OptoReg::add(r,1) ) {
     if( !regs.Member(r) ) {     // Not already defined by the call
--- a/hotspot/src/share/vm/opto/machnode.cpp	Mon Jan 04 15:21:09 2010 -0800
+++ b/hotspot/src/share/vm/opto/machnode.cpp	Tue Jan 05 13:05:58 2010 +0100
@@ -636,7 +636,9 @@
 }
 #ifndef PRODUCT
 void MachCallJavaNode::dump_spec(outputStream *st) const {
-  if( _method ) {
+  if (_method_handle_invoke)
+    st->print("MethodHandle ");
+  if (_method) {
     _method->print_short_name(st);
     st->print(" ");
   }
@@ -644,6 +646,20 @@
 }
 #endif
 
+//------------------------------Registers--------------------------------------
+const RegMask &MachCallJavaNode::in_RegMask(uint idx) const {
+  // Values in the domain use the users calling convention, embodied in the
+  // _in_rms array of RegMasks.
+  if (idx < tf()->domain()->cnt())  return _in_rms[idx];
+  // Values outside the domain represent debug info
+  Matcher* m = Compile::current()->matcher();
+  // If this call is a MethodHandle invoke we have to use a different
+  // debugmask which does not include the register we use to save the
+  // SP over MH invokes.
+  RegMask** debugmask = _method_handle_invoke ? m->idealreg2mhdebugmask : m->idealreg2debugmask;
+  return *debugmask[in(idx)->ideal_reg()];
+}
+
 //=============================================================================
 uint MachCallStaticJavaNode::size_of() const { return sizeof(*this); }
 uint MachCallStaticJavaNode::cmp( const Node &n ) const {
--- a/hotspot/src/share/vm/opto/machnode.hpp	Mon Jan 04 15:21:09 2010 -0800
+++ b/hotspot/src/share/vm/opto/machnode.hpp	Tue Jan 05 13:05:58 2010 +0100
@@ -662,9 +662,13 @@
   ciMethod* _method;             // Method being direct called
   int        _bci;               // Byte Code index of call byte code
   bool       _optimized_virtual; // Tells if node is a static call or an optimized virtual
+  bool       _method_handle_invoke;   // Tells if the call has to preserve SP
   MachCallJavaNode() : MachCallNode() {
     init_class_id(Class_MachCallJava);
   }
+
+  virtual const RegMask &in_RegMask(uint) const;
+
 #ifndef PRODUCT
   virtual void dump_spec(outputStream *st) const;
 #endif
--- a/hotspot/src/share/vm/opto/matcher.cpp	Mon Jan 04 15:21:09 2010 -0800
+++ b/hotspot/src/share/vm/opto/matcher.cpp	Tue Jan 05 13:05:58 2010 +0100
@@ -70,19 +70,27 @@
   _dontcare(&_states_arena) {
   C->set_matcher(this);
 
-  idealreg2spillmask[Op_RegI] = NULL;
-  idealreg2spillmask[Op_RegN] = NULL;
-  idealreg2spillmask[Op_RegL] = NULL;
-  idealreg2spillmask[Op_RegF] = NULL;
-  idealreg2spillmask[Op_RegD] = NULL;
-  idealreg2spillmask[Op_RegP] = NULL;
+  idealreg2spillmask  [Op_RegI] = NULL;
+  idealreg2spillmask  [Op_RegN] = NULL;
+  idealreg2spillmask  [Op_RegL] = NULL;
+  idealreg2spillmask  [Op_RegF] = NULL;
+  idealreg2spillmask  [Op_RegD] = NULL;
+  idealreg2spillmask  [Op_RegP] = NULL;
 
-  idealreg2debugmask[Op_RegI] = NULL;
-  idealreg2debugmask[Op_RegN] = NULL;
-  idealreg2debugmask[Op_RegL] = NULL;
-  idealreg2debugmask[Op_RegF] = NULL;
-  idealreg2debugmask[Op_RegD] = NULL;
-  idealreg2debugmask[Op_RegP] = NULL;
+  idealreg2debugmask  [Op_RegI] = NULL;
+  idealreg2debugmask  [Op_RegN] = NULL;
+  idealreg2debugmask  [Op_RegL] = NULL;
+  idealreg2debugmask  [Op_RegF] = NULL;
+  idealreg2debugmask  [Op_RegD] = NULL;
+  idealreg2debugmask  [Op_RegP] = NULL;
+
+  idealreg2mhdebugmask[Op_RegI] = NULL;
+  idealreg2mhdebugmask[Op_RegN] = NULL;
+  idealreg2mhdebugmask[Op_RegL] = NULL;
+  idealreg2mhdebugmask[Op_RegF] = NULL;
+  idealreg2mhdebugmask[Op_RegD] = NULL;
+  idealreg2mhdebugmask[Op_RegP] = NULL;
+
   debug_only(_mem_node = NULL;)   // Ideal memory node consumed by mach node
 }
 
@@ -389,19 +397,28 @@
 void Matcher::init_first_stack_mask() {
 
   // Allocate storage for spill masks as masks for the appropriate load type.
-  RegMask *rms = (RegMask*)C->comp_arena()->Amalloc_D(sizeof(RegMask)*12);
-  idealreg2spillmask[Op_RegN] = &rms[0];
-  idealreg2spillmask[Op_RegI] = &rms[1];
-  idealreg2spillmask[Op_RegL] = &rms[2];
-  idealreg2spillmask[Op_RegF] = &rms[3];
-  idealreg2spillmask[Op_RegD] = &rms[4];
-  idealreg2spillmask[Op_RegP] = &rms[5];
-  idealreg2debugmask[Op_RegN] = &rms[6];
-  idealreg2debugmask[Op_RegI] = &rms[7];
-  idealreg2debugmask[Op_RegL] = &rms[8];
-  idealreg2debugmask[Op_RegF] = &rms[9];
-  idealreg2debugmask[Op_RegD] = &rms[10];
-  idealreg2debugmask[Op_RegP] = &rms[11];
+  RegMask *rms = (RegMask*)C->comp_arena()->Amalloc_D(sizeof(RegMask) * 3*6);
+
+  idealreg2spillmask  [Op_RegN] = &rms[0];
+  idealreg2spillmask  [Op_RegI] = &rms[1];
+  idealreg2spillmask  [Op_RegL] = &rms[2];
+  idealreg2spillmask  [Op_RegF] = &rms[3];
+  idealreg2spillmask  [Op_RegD] = &rms[4];
+  idealreg2spillmask  [Op_RegP] = &rms[5];
+
+  idealreg2debugmask  [Op_RegN] = &rms[6];
+  idealreg2debugmask  [Op_RegI] = &rms[7];
+  idealreg2debugmask  [Op_RegL] = &rms[8];
+  idealreg2debugmask  [Op_RegF] = &rms[9];
+  idealreg2debugmask  [Op_RegD] = &rms[10];
+  idealreg2debugmask  [Op_RegP] = &rms[11];
+
+  idealreg2mhdebugmask[Op_RegN] = &rms[12];
+  idealreg2mhdebugmask[Op_RegI] = &rms[13];
+  idealreg2mhdebugmask[Op_RegL] = &rms[14];
+  idealreg2mhdebugmask[Op_RegF] = &rms[15];
+  idealreg2mhdebugmask[Op_RegD] = &rms[16];
+  idealreg2mhdebugmask[Op_RegP] = &rms[17];
 
   OptoReg::Name i;
 
@@ -442,12 +459,19 @@
   // Make up debug masks.  Any spill slot plus callee-save registers.
   // Caller-save registers are assumed to be trashable by the various
   // inline-cache fixup routines.
-  *idealreg2debugmask[Op_RegN]= *idealreg2spillmask[Op_RegN];
-  *idealreg2debugmask[Op_RegI]= *idealreg2spillmask[Op_RegI];
-  *idealreg2debugmask[Op_RegL]= *idealreg2spillmask[Op_RegL];
-  *idealreg2debugmask[Op_RegF]= *idealreg2spillmask[Op_RegF];
-  *idealreg2debugmask[Op_RegD]= *idealreg2spillmask[Op_RegD];
-  *idealreg2debugmask[Op_RegP]= *idealreg2spillmask[Op_RegP];
+  *idealreg2debugmask  [Op_RegN]= *idealreg2spillmask[Op_RegN];
+  *idealreg2debugmask  [Op_RegI]= *idealreg2spillmask[Op_RegI];
+  *idealreg2debugmask  [Op_RegL]= *idealreg2spillmask[Op_RegL];
+  *idealreg2debugmask  [Op_RegF]= *idealreg2spillmask[Op_RegF];
+  *idealreg2debugmask  [Op_RegD]= *idealreg2spillmask[Op_RegD];
+  *idealreg2debugmask  [Op_RegP]= *idealreg2spillmask[Op_RegP];
+
+  *idealreg2mhdebugmask[Op_RegN]= *idealreg2spillmask[Op_RegN];
+  *idealreg2mhdebugmask[Op_RegI]= *idealreg2spillmask[Op_RegI];
+  *idealreg2mhdebugmask[Op_RegL]= *idealreg2spillmask[Op_RegL];
+  *idealreg2mhdebugmask[Op_RegF]= *idealreg2spillmask[Op_RegF];
+  *idealreg2mhdebugmask[Op_RegD]= *idealreg2spillmask[Op_RegD];
+  *idealreg2mhdebugmask[Op_RegP]= *idealreg2spillmask[Op_RegP];
 
   // Prevent stub compilations from attempting to reference
   // callee-saved registers from debug info
@@ -458,14 +482,31 @@
     if( _register_save_policy[i] == 'C' ||
         _register_save_policy[i] == 'A' ||
         (_register_save_policy[i] == 'E' && exclude_soe) ) {
-      idealreg2debugmask[Op_RegN]->Remove(i);
-      idealreg2debugmask[Op_RegI]->Remove(i); // Exclude save-on-call
-      idealreg2debugmask[Op_RegL]->Remove(i); // registers from debug
-      idealreg2debugmask[Op_RegF]->Remove(i); // masks
-      idealreg2debugmask[Op_RegD]->Remove(i);
-      idealreg2debugmask[Op_RegP]->Remove(i);
+      idealreg2debugmask  [Op_RegN]->Remove(i);
+      idealreg2debugmask  [Op_RegI]->Remove(i); // Exclude save-on-call
+      idealreg2debugmask  [Op_RegL]->Remove(i); // registers from debug
+      idealreg2debugmask  [Op_RegF]->Remove(i); // masks
+      idealreg2debugmask  [Op_RegD]->Remove(i);
+      idealreg2debugmask  [Op_RegP]->Remove(i);
+
+      idealreg2mhdebugmask[Op_RegN]->Remove(i);
+      idealreg2mhdebugmask[Op_RegI]->Remove(i);
+      idealreg2mhdebugmask[Op_RegL]->Remove(i);
+      idealreg2mhdebugmask[Op_RegF]->Remove(i);
+      idealreg2mhdebugmask[Op_RegD]->Remove(i);
+      idealreg2mhdebugmask[Op_RegP]->Remove(i);
     }
   }
+
+  // Subtract the register we use to save the SP for MethodHandle
+  // invokes to from the debug mask.
+  const RegMask save_mask = method_handle_invoke_SP_save_mask();
+  idealreg2mhdebugmask[Op_RegN]->SUBTRACT(save_mask);
+  idealreg2mhdebugmask[Op_RegI]->SUBTRACT(save_mask);
+  idealreg2mhdebugmask[Op_RegL]->SUBTRACT(save_mask);
+  idealreg2mhdebugmask[Op_RegF]->SUBTRACT(save_mask);
+  idealreg2mhdebugmask[Op_RegD]->SUBTRACT(save_mask);
+  idealreg2mhdebugmask[Op_RegP]->SUBTRACT(save_mask);
 }
 
 //---------------------------is_save_on_entry----------------------------------
@@ -989,6 +1030,7 @@
   CallNode *call;
   const TypeTuple *domain;
   ciMethod*        method = NULL;
+  bool             is_method_handle_invoke = false;  // for special kill effects
   if( sfpt->is_Call() ) {
     call = sfpt->as_Call();
     domain = call->tf()->domain();
@@ -1013,6 +1055,8 @@
       mcall_java->_method = method;
       mcall_java->_bci = call_java->_bci;
       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( mcall_java->is_MachCallStaticJava() )
         mcall_java->as_MachCallStaticJava()->_name =
          call_java->as_CallStaticJava()->_name;
@@ -1126,6 +1170,15 @@
     mcall->_argsize = out_arg_limit_per_call - begin_out_arg_area;
   }
 
+  if (is_method_handle_invoke) {
+    // Kill some extra stack space in case method handles want to do
+    // a little in-place argument insertion.
+    int regs_per_word  = NOT_LP64(1) LP64_ONLY(2); // %%% make a global const!
+    out_arg_limit_per_call += MethodHandlePushLimit * regs_per_word;
+    // Do not update mcall->_argsize because (a) the extra space is not
+    // pushed as arguments and (b) _argsize is dead (not used anywhere).
+  }
+
   // Compute the max stack slot killed by any call.  These will not be
   // available for debug info, and will be used to adjust FIRST_STACK_mask
   // after all call sites have been visited.
--- a/hotspot/src/share/vm/opto/matcher.hpp	Mon Jan 04 15:21:09 2010 -0800
+++ b/hotspot/src/share/vm/opto/matcher.hpp	Tue Jan 05 13:05:58 2010 +0100
@@ -117,8 +117,9 @@
   static const int base2reg[];        // Map Types to machine register types
   // Convert ideal machine register to a register mask for spill-loads
   static const RegMask *idealreg2regmask[];
-  RegMask *idealreg2spillmask[_last_machine_leaf];
-  RegMask *idealreg2debugmask[_last_machine_leaf];
+  RegMask *idealreg2spillmask  [_last_machine_leaf];
+  RegMask *idealreg2debugmask  [_last_machine_leaf];
+  RegMask *idealreg2mhdebugmask[_last_machine_leaf];
   void init_spill_mask( Node *ret );
   // Convert machine register number to register mask
   static uint mreg2regmask_max;
@@ -297,6 +298,8 @@
   // Register for MODL projection of divmodL
   static RegMask modL_proj_mask();
 
+  static const RegMask method_handle_invoke_SP_save_mask();
+
   // Java-Interpreter calling convention
   // (what you use when calling between compiled-Java and Interpreted-Java
 
--- a/hotspot/src/share/vm/opto/output.cpp	Mon Jan 04 15:21:09 2010 -0800
+++ b/hotspot/src/share/vm/opto/output.cpp	Tue Jan 05 13:05:58 2010 +0100
@@ -794,6 +794,7 @@
 #endif
 
   int safepoint_pc_offset = current_offset;
+  bool is_method_handle_invoke = false;
 
   // Add the safepoint in the DebugInfoRecorder
   if( !mach->is_MachCall() ) {
@@ -801,6 +802,11 @@
     debug_info()->add_safepoint(safepoint_pc_offset, sfn->_oop_map);
   } else {
     mcall = mach->as_MachCall();
+
+    // Is the call a MethodHandle call?
+    if (mcall->is_MachCallJava())
+      is_method_handle_invoke = mcall->as_MachCallJava()->_method_handle_invoke;
+
     safepoint_pc_offset += mcall->ret_addr_offset();
     debug_info()->add_safepoint(safepoint_pc_offset, mcall->_oop_map);
   }
@@ -913,7 +919,6 @@
     assert(jvms->bci() >= InvocationEntryBci && jvms->bci() <= 0x10000, "must be a valid or entry BCI");
     assert(!jvms->should_reexecute() || depth == max_depth, "reexecute allowed only for the youngest");
     // Now we can describe the scope.
-    bool is_method_handle_invoke = false;
     debug_info()->describe_scope(safepoint_pc_offset, scope_method, jvms->bci(), jvms->should_reexecute(), is_method_handle_invoke, locvals, expvals, monvals);
   } // End jvms loop
 
--- a/hotspot/src/share/vm/opto/type.cpp	Mon Jan 04 15:21:09 2010 -0800
+++ b/hotspot/src/share/vm/opto/type.cpp	Tue Jan 05 13:05:58 2010 +0100
@@ -2431,7 +2431,7 @@
 //------------------------------make_from_constant-----------------------------
 // Make a java pointer from an oop constant
 const TypeOopPtr* TypeOopPtr::make_from_constant(ciObject* o, bool require_constant) {
-  if (o->is_method_data() || o->is_method()) {
+  if (o->is_method_data() || o->is_method() || o->is_cpcache()) {
     // Treat much like a typeArray of bytes, like below, but fake the type...
     const Type* etype = (Type*)get_const_basic_type(T_BYTE);
     const TypeAry* arr0 = TypeAry::make(etype, TypeInt::POS);
@@ -3966,7 +3966,7 @@
   const TypeFunc* tf = C->last_tf(method); // check cache
   if (tf != NULL)  return tf;  // The hit rate here is almost 50%.
   const TypeTuple *domain;
-  if (method->flags().is_static()) {
+  if (method->is_static()) {
     domain = TypeTuple::make_domain(NULL, method->signature());
   } else {
     domain = TypeTuple::make_domain(method->holder(), method->signature());