changeset 8948:dedc3f7d3033

Merge
author Andreas Woess <andreas.woess@jku.at>
date Tue, 09 Apr 2013 17:25:02 +0200
parents e7766460ddb3 (current diff) 707b20dd9512 (diff)
children 82d8fac3ad13
files
diffstat 20 files changed, 162 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Assumptions.java	Tue Apr 09 15:26:29 2013 +0200
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Assumptions.java	Tue Apr 09 17:25:02 2013 +0200
@@ -25,6 +25,7 @@
 import static com.oracle.graal.api.meta.MetaUtil.*;
 
 import java.io.*;
+import java.lang.invoke.*;
 import java.util.*;
 
 import com.oracle.graal.api.meta.*;
@@ -182,6 +183,45 @@
     }
 
     /**
+     * Assumption that a call site's method handle did not change.
+     */
+    public static final class CallSiteTargetValue extends Assumption {
+
+        private static final long serialVersionUID = 1732459941784550371L;
+
+        public final CallSite callSite;
+        public final MethodHandle methodHandle;
+
+        public CallSiteTargetValue(CallSite callSite, MethodHandle methodHandle) {
+            this.callSite = callSite;
+            this.methodHandle = methodHandle;
+        }
+
+        @Override
+        public int hashCode() {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + callSite.hashCode();
+            result = prime * result + methodHandle.hashCode();
+            return result;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj instanceof CallSiteTargetValue) {
+                CallSiteTargetValue other = (CallSiteTargetValue) obj;
+                return other.callSite == callSite && other.methodHandle == methodHandle;
+            }
+            return false;
+        }
+
+        @Override
+        public String toString() {
+            return "CallSiteTargetValue[callSite=" + callSite + ", methodHandle=" + methodHandle + "]";
+        }
+    }
+
+    /**
      * Array with the assumptions. This field is directly accessed from C++ code in the
      * Graal/HotSpot implementation.
      */
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ConstantPool.java	Tue Apr 09 15:26:29 2013 +0200
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ConstantPool.java	Tue Apr 09 17:25:02 2013 +0200
@@ -93,4 +93,12 @@
      *         entry
      */
     Object lookupConstant(int cpi);
+
+    /**
+     * Looks up the appendix at the specified index.
+     * 
+     * @param cpi the constant pool index
+     * @return the appendix if resolved or {@code null}.
+     */
+    Object lookupAppendix(int cpi);
 }
--- a/graal/com.oracle.graal.bytecode/src/com/oracle/graal/bytecode/BytecodeStream.java	Tue Apr 09 15:26:29 2013 +0200
+++ b/graal/com.oracle.graal.bytecode/src/com/oracle/graal/bytecode/BytecodeStream.java	Tue Apr 09 17:25:02 2013 +0200
@@ -168,6 +168,16 @@
     }
 
     /**
+     * Reads a constant pool index for an invokedynamic instruction.
+     * 
+     * @return the constant pool index
+     */
+    public int readCPI4() {
+        assert opcode == Bytecodes.INVOKEDYNAMIC;
+        return Bytes.beS4(code, curBCI + 1);
+    }
+
+    /**
      * Reads a signed, 1-byte value for the current instruction (e.g. BIPUSH).
      * 
      * @return the byte
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java	Tue Apr 09 15:26:29 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java	Tue Apr 09 17:25:02 2013 +0200
@@ -221,4 +221,6 @@
      * @param metaspaceMethod the metaspace Method object
      */
     void reprofile(long metaspaceMethod);
+
+    Object lookupAppendixInPool(HotSpotResolvedObjectType pool, int cpi);
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java	Tue Apr 09 15:26:29 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java	Tue Apr 09 17:25:02 2013 +0200
@@ -158,4 +158,7 @@
 
     @Override
     public native void reprofile(long metaspaceMethod);
+
+    @Override
+    public native Object lookupAppendixInPool(HotSpotResolvedObjectType pool, int cpi);
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantPool.java	Tue Apr 09 15:26:29 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantPool.java	Tue Apr 09 17:25:02 2013 +0200
@@ -51,6 +51,13 @@
     }
 
     @Override
+    public Object lookupAppendix(int cpi) {
+        assert cpi != 0;
+        Object constant = HotSpotGraalRuntime.getInstance().getCompilerToVM().lookupAppendixInPool(type, cpi);
+        return constant;
+    }
+
+    @Override
     public JavaMethod lookupMethod(int cpi, int opcode) {
         return HotSpotGraalRuntime.getInstance().getCompilerToVM().lookupMethodInPool(type, cpi, (byte) opcode);
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java	Tue Apr 09 15:26:29 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java	Tue Apr 09 17:25:02 2013 +0200
@@ -24,6 +24,7 @@
 package com.oracle.graal.hotspot.meta;
 
 import java.lang.annotation.*;
+import java.lang.invoke.*;
 import java.lang.reflect.*;
 
 import com.oracle.graal.api.meta.*;
@@ -97,6 +98,8 @@
                 if (assumeNonStaticFinalFieldsAsFinal(receiver.asObject().getClass()) || !value.isDefaultForKind()) {
                     return value;
                 }
+            } else if (receiver.asObject() instanceof ConstantCallSite) {
+                return readValue(receiver);
             }
         }
         return null;
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/BytecodeDisassembler.java	Tue Apr 09 15:26:29 2013 +0200
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/BytecodeDisassembler.java	Tue Apr 09 17:25:02 2013 +0200
@@ -102,6 +102,13 @@
                         buf.append(String.format("#%-10s // %s", cpi + ", " + stream.readUByte(bci + 3), calleeDesc));
                         break;
                     }
+                    case INVOKEDYNAMIC: {
+                        int cpi = stream.readCPI4();
+                        JavaMethod callee = cp.lookupMethod(cpi, opcode);
+                        String calleeDesc = callee.getDeclaringClass().getName().equals(method.getDeclaringClass().getName()) ? MetaUtil.format("%n:(%P)%R", callee) : MetaUtil.format("%H.%n:(%P)%R", callee);
+                        buf.append(String.format("#%-10d // %s", cpi, calleeDesc));
+                        break;
+                    }
                     case LDC            :
                     case LDC_W          :
                     case LDC2_W         : {
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Tue Apr 09 15:26:29 2013 +0200
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Tue Apr 09 17:25:02 2013 +0200
@@ -766,7 +766,8 @@
     }
 
     private void eagerResolvingForSnippets(int cpi, int bytecode) {
-        if (graphBuilderConfig.eagerResolving()) {
+        // (aw) cannot eager-resolve invokedynamic
+        if (graphBuilderConfig.eagerResolving() && bytecode != Bytecodes.INVOKEDYNAMIC) {
             constantPool.loadReferencedType(cpi, bytecode);
         }
     }
@@ -1054,6 +1055,19 @@
         }
     }
 
+    private void genInvokeDynamic(JavaMethod target) {
+        if (target instanceof ResolvedJavaMethod) {
+            Object appendix = constantPool.lookupAppendix(stream.readCPI4());
+            if (appendix != null) {
+                frameState.apush(ConstantNode.forObject(appendix, runtime, currentGraph));
+            }
+            ValueNode[] args = frameState.popArguments(target.getSignature().getParameterSlots(false), target.getSignature().getParameterCount(false));
+            appendInvoke(InvokeKind.Static, (ResolvedJavaMethod) target, args);
+        } else {
+            handleUnresolvedInvoke(target, InvokeKind.Static);
+        }
+    }
+
     private void genInvokeVirtual(JavaMethod target) {
         if (target instanceof ResolvedJavaMethod) {
             ValueNode[] args = frameState.popArguments(target.getSignature().getParameterSlots(true), target.getSignature().getParameterCount(true));
@@ -1937,6 +1951,7 @@
             case INVOKESPECIAL  : cpi = stream.readCPI(); genInvokeSpecial(lookupMethod(cpi, opcode)); break;
             case INVOKESTATIC   : cpi = stream.readCPI(); genInvokeStatic(lookupMethod(cpi, opcode)); break;
             case INVOKEINTERFACE: cpi = stream.readCPI(); genInvokeInterface(lookupMethod(cpi, opcode)); break;
+            case INVOKEDYNAMIC  : cpi = stream.readCPI4(); genInvokeDynamic(lookupMethod(cpi, opcode)); break;
             case NEW            : genNewInstance(stream.readCPI()); break;
             case NEWARRAY       : genNewPrimitiveArray(stream.readLocalIndex()); break;
             case ANEWARRAY      : genNewObjectArray(stream.readCPI()); break;
--- a/src/cpu/x86/vm/templateInterpreter_x86.hpp	Tue Apr 09 15:26:29 2013 +0200
+++ b/src/cpu/x86/vm/templateInterpreter_x86.hpp	Tue Apr 09 17:25:02 2013 +0200
@@ -34,7 +34,7 @@
   // Run with +PrintInterpreter to get the VM to print out the size.
   // Max size with JVMTI
 #ifdef AMD64
-  const static int InterpreterCodeSize = 224 * 1024;
+  const static int InterpreterCodeSize = 240 * 1024;
 #else
   const static int InterpreterCodeSize = 168 * 1024;
 #endif // AMD64
--- a/src/share/vm/classfile/systemDictionary.hpp	Tue Apr 09 15:26:29 2013 +0200
+++ b/src/share/vm/classfile/systemDictionary.hpp	Tue Apr 09 17:25:02 2013 +0200
@@ -201,6 +201,7 @@
   do_klass(Assumptions_ConcreteMethod_klass,      com_oracle_graal_api_code_Assumptions_ConcreteMethod,         Opt) \
   do_klass(Assumptions_ConcreteSubtype_klass,     com_oracle_graal_api_code_Assumptions_ConcreteSubtype,        Opt) \
   do_klass(Assumptions_MethodContents_klass,      com_oracle_graal_api_code_Assumptions_MethodContents,         Opt) \
+  do_klass(Assumptions_CallSiteTargetValue_klass, com_oracle_graal_api_code_Assumptions_CallSiteTargetValue,    Opt) \
   do_klass(BytecodePosition_klass,                com_oracle_graal_api_code_BytecodePosition,                   Opt) \
   do_klass(DebugInfo_klass,                       com_oracle_graal_api_code_DebugInfo,                          Opt) \
   do_klass(BytecodeFrame_klass,                   com_oracle_graal_api_code_BytecodeFrame,                      Opt) \
--- a/src/share/vm/classfile/vmSymbols.hpp	Tue Apr 09 15:26:29 2013 +0200
+++ b/src/share/vm/classfile/vmSymbols.hpp	Tue Apr 09 17:25:02 2013 +0200
@@ -323,6 +323,7 @@
   template(com_oracle_graal_api_code_Assumptions_MethodContents,     "com/oracle/graal/api/code/Assumptions$MethodContents")          \
   template(com_oracle_graal_api_code_Assumptions_ConcreteSubtype,    "com/oracle/graal/api/code/Assumptions$ConcreteSubtype")         \
   template(com_oracle_graal_api_code_Assumptions_ConcreteMethod,     "com/oracle/graal/api/code/Assumptions$ConcreteMethod")          \
+  template(com_oracle_graal_api_code_Assumptions_CallSiteTargetValue,"com/oracle/graal/api/code/Assumptions$CallSiteTargetValue")     \
   template(com_oracle_graal_api_code_CompilationResult,              "com/oracle/graal/api/code/CompilationResult")                   \
   template(com_oracle_graal_api_code_CompilationResult_Call,         "com/oracle/graal/api/code/CompilationResult$Call")              \
   template(com_oracle_graal_api_code_CompilationResult_DataPatch,    "com/oracle/graal/api/code/CompilationResult$DataPatch")         \
--- a/src/share/vm/code/dependencies.cpp	Tue Apr 09 15:26:29 2013 +0200
+++ b/src/share/vm/code/dependencies.cpp	Tue Apr 09 17:25:02 2013 +0200
@@ -170,6 +170,10 @@
   check_ctxk(ctxk);
   assert_common_2(unique_concrete_method, DepValue(_oop_recorder, ctxk), DepValue(_oop_recorder, uniqm));
 }
+
+void Dependencies::assert_call_site_target_value(oop cs, oop mh) {
+  assert_common_2(call_site_target_value, DepValue(_oop_recorder, JNIHandles::make_local(cs)), DepValue(_oop_recorder, JNIHandles::make_local(mh)));
+}
 #endif // GRAAL
 
 
--- a/src/share/vm/code/dependencies.hpp	Tue Apr 09 15:26:29 2013 +0200
+++ b/src/share/vm/code/dependencies.hpp	Tue Apr 09 17:25:02 2013 +0200
@@ -363,6 +363,7 @@
   void assert_leaf_type(Klass* ctxk);
   void assert_unique_concrete_method(Klass* ctxk, Method* uniqm);
   void assert_abstract_with_unique_concrete_subtype(Klass* ctxk, Klass* conck);
+  void assert_call_site_target_value(oop callSite, oop methodHandle);
 #endif // GRAAL
 
   // Define whether a given method or type is concrete.
--- a/src/share/vm/graal/graalCodeInstaller.cpp	Tue Apr 09 15:26:29 2013 +0200
+++ b/src/share/vm/graal/graalCodeInstaller.cpp	Tue Apr 09 17:25:02 2013 +0200
@@ -236,7 +236,7 @@
     for (jint i = 0; i < values->length(); i++) {
       ScopeValue* cur_second = NULL;
       ScopeValue* value = get_hotspot_value(((oop*) values->base(T_OBJECT))[i], total_frame_size, objects, cur_second, oop_recorder);
-      
+
       if (isLongArray && cur_second == NULL) {
         // we're trying to put ints into a long array... this isn't really valid, but it's used for some optimizations.
         // add an int 0 constant
@@ -298,6 +298,8 @@
           assumption_ConcreteSubtype(assumption);
         } else if (assumption->klass() == Assumptions_ConcreteMethod::klass()) {
           assumption_ConcreteMethod(assumption);
+        } else if (assumption->klass() == Assumptions_CallSiteTargetValue::klass()) {
+          assumption_CallSiteTargetValue(assumption);
         } else {
           assumption->print();
           fatal("unexpected Assumption subclass");
@@ -350,7 +352,7 @@
 // constructor used to create a stub
 CodeInstaller::CodeInstaller(Handle& target_method, BufferBlob*& blob, jlong& id) {
   No_Safepoint_Verifier no_safepoint;
-  
+
   _oop_recorder = new OopRecorder(&_arena);
   initialize_fields(target_method(), NULL);
   assert(_name != NULL, "installMethod needs NON-NULL name");
@@ -398,7 +400,7 @@
 
   _debug_recorder = new DebugInformationRecorder(_oop_recorder);
   _debug_recorder->set_oopmaps(new OopMapSet());
-  
+
   buffer.initialize_oop_recorder(_oop_recorder);
 
   _instructions = buffer.insts();
@@ -460,6 +462,13 @@
   _dependencies->assert_unique_concrete_method(context, impl());
 }
 
+void CodeInstaller::assumption_CallSiteTargetValue(Handle assumption) {
+  Handle callSite = Assumptions_CallSiteTargetValue::callSite(assumption());
+  Handle methodHandle = Assumptions_CallSiteTargetValue::methodHandle(assumption());
+
+  _dependencies->assert_call_site_target_value(callSite(), methodHandle());
+}
+
 void CodeInstaller::process_exception_handlers() {
   // allocate some arrays for use by the collection code.
   const int num_handlers = 5;
--- a/src/share/vm/graal/graalCodeInstaller.hpp	Tue Apr 09 15:26:29 2013 +0200
+++ b/src/share/vm/graal/graalCodeInstaller.hpp	Tue Apr 09 17:25:02 2013 +0200
@@ -95,6 +95,7 @@
   void assumption_MethodContents(Handle assumption);
   void assumption_ConcreteSubtype(Handle assumption);
   void assumption_ConcreteMethod(Handle assumption);
+  void assumption_CallSiteTargetValue(Handle assumption);
 
   void site_Safepoint(CodeBuffer& buffer, jint pc_offset, oop site);
   void site_Call(CodeBuffer& buffer, jint pc_offset, oop site);
--- a/src/share/vm/graal/graalCompiler.hpp	Tue Apr 09 15:26:29 2013 +0200
+++ b/src/share/vm/graal/graalCompiler.hpp	Tue Apr 09 17:25:02 2013 +0200
@@ -68,7 +68,7 @@
 
   // Print compilation timers and statistics
   virtual void print_timers();
-  
+
   static Handle get_JavaTypeFromSignature(Symbol* signature, KlassHandle accessor, TRAPS);
   static Handle get_JavaType(constantPoolHandle cp, int index, KlassHandle accessor, TRAPS);
   static Handle get_JavaType(Symbol* klass_name, TRAPS);
@@ -93,6 +93,11 @@
     return ((index & 0xFF) << 8) | (index >> 8);
   }
 
+  static int to_index_u4(int index) {
+    // Swap.
+    return ((index & 0xFF) << 24) | ((index & 0xFF00) << 8) | ((index & 0xFF0000) >> 8) | ((index & 0xFF000000) >> 24);
+  }
+
   static void initialize_buffer_blob();
 };
 
--- a/src/share/vm/graal/graalCompilerToVM.cpp	Tue Apr 09 15:26:29 2013 +0200
+++ b/src/share/vm/graal/graalCompilerToVM.cpp	Tue Apr 09 17:25:02 2013 +0200
@@ -62,7 +62,7 @@
 C2V_ENTRY(jbyteArray, initializeBytecode, (JNIEnv *env, jobject, jlong metaspace_method, jbyteArray result))
   methodHandle method = asMethod(metaspace_method);
   ResourceMark rm;
-  
+
   int code_size = method->code_size();
   jbyte* reconstituted_code = NULL;
 
@@ -416,12 +416,21 @@
   return JNIHandles::make_local(THREAD, result);
 C2V_END
 
+C2V_VMENTRY(jobject, lookupAppendixInPool, (JNIEnv *env, jobject, jobject type, jint index))
+  assert(GraalCompiler::to_index_u4(index) < 0, "not an invokedynamic constant pool index");
+  constantPoolHandle cpool(InstanceKlass::cast(java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(type)))->constants());
+  oop appendix_oop = ConstantPool::appendix_at_if_loaded(cpool, GraalCompiler::to_index_u4(index));
+
+  return JNIHandles::make_local(THREAD, appendix_oop);
+C2V_END
+
 C2V_VMENTRY(jobject, lookupMethodInPool, (JNIEnv *env, jobject, jobject type, jint index, jbyte opcode))
-  index = GraalCompiler::to_cp_index_u2(index);
   constantPoolHandle cp = InstanceKlass::cast(java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(type)))->constants();
   instanceKlassHandle pool_holder(cp->pool_holder());
 
   Bytecodes::Code bc = (Bytecodes::Code) (((int) opcode) & 0xFF);
+  index = (bc == Bytecodes::_invokedynamic) ? GraalCompiler::to_index_u4(index) : GraalCompiler::to_cp_index_u2(index);
+
   methodHandle method = GraalEnv::get_method_by_index(cp, index, bc, pool_holder);
   if (!method.is_null()) {
     Handle holder = GraalCompiler::get_JavaType(method->method_holder(), CHECK_NULL);
@@ -430,8 +439,13 @@
     // Get the method's name and signature.
     Handle name = java_lang_String::create_from_symbol(cp->name_ref_at(index), CHECK_NULL);
     Handle signature  = java_lang_String::create_from_symbol(cp->signature_ref_at(index), CHECK_NULL);
-    int holder_index = cp->klass_ref_index_at(index);
-    Handle type = GraalCompiler::get_JavaType(cp, holder_index, cp->pool_holder(), CHECK_NULL);
+    Handle type;
+    if (bc != Bytecodes::_invokedynamic) {
+      int holder_index = cp->klass_ref_index_at(index);
+      type = GraalCompiler::get_JavaType(cp, holder_index, cp->pool_holder(), CHECK_NULL);
+    } else {
+      type = Handle(SystemDictionary::MethodHandle_klass()->java_mirror());
+    }
     return JNIHandles::make_local(THREAD, VMToCompiler::createUnresolvedJavaMethod(name, signature, type, THREAD));
   }
 C2V_END
@@ -479,7 +493,7 @@
   int holder_index = cp->klass_ref_index_at(index);
   Handle holder = GraalCompiler::get_JavaType(cp, holder_index, cp->pool_holder(), CHECK_NULL);
   instanceKlassHandle holder_klass;
-  
+
   Bytecodes::Code code = (Bytecodes::Code)(((int) opcode) & 0xFF);
   int offset = -1;
   AccessFlags flags;
@@ -499,7 +513,7 @@
       holder = GraalCompiler::get_JavaType(holder_klass, CHECK_NULL);
     }
   }
-  
+
   Handle type = GraalCompiler::get_JavaTypeFromSignature(signature, cp->pool_holder(), CHECK_NULL);
   Handle field_handle = GraalCompiler::get_JavaField(offset, flags.as_int(), name, holder, type, THREAD);
 
@@ -663,7 +677,7 @@
   set_int("arrayKlassLayoutHelperIdentifier", 0x80000000);
   assert((Klass::_lh_array_tag_obj_value & Klass::_lh_array_tag_type_value & 0x80000000) != 0, "obj_array and type_array must have first bit set");
   set_int("arrayKlassComponentMirrorOffset", in_bytes(ArrayKlass::component_mirror_offset()));
-  
+
 
   set_int("pendingDeoptimizationOffset", in_bytes(ThreadShadow::pending_deoptimization_offset()));
 
@@ -1104,6 +1118,7 @@
   {CC"getVtableEntryOffset",          CC"("METASPACE_METHOD")I",                                        FN_PTR(getVtableEntryOffset)},
   {CC"lookupType",                    CC"("STRING HS_RESOLVED_TYPE"Z)"TYPE,                             FN_PTR(lookupType)},
   {CC"lookupConstantInPool",          CC"("HS_RESOLVED_TYPE"I)"OBJECT,                                  FN_PTR(lookupConstantInPool)},
+  {CC"lookupAppendixInPool",          CC"("HS_RESOLVED_TYPE"I)"OBJECT,                                  FN_PTR(lookupAppendixInPool)},
   {CC"lookupMethodInPool",            CC"("HS_RESOLVED_TYPE"IB)"METHOD,                                 FN_PTR(lookupMethodInPool)},
   {CC"lookupTypeInPool",              CC"("HS_RESOLVED_TYPE"I)"TYPE,                                    FN_PTR(lookupTypeInPool)},
   {CC"lookupReferencedTypeInPool",    CC"("HS_RESOLVED_TYPE"IB)V",                                      FN_PTR(lookupReferencedTypeInPool)},
--- a/src/share/vm/graal/graalEnv.cpp	Tue Apr 09 15:26:29 2013 +0200
+++ b/src/share/vm/graal/graalEnv.cpp	Tue Apr 09 17:25:02 2013 +0200
@@ -319,6 +319,19 @@
 methodHandle GraalEnv::get_method_by_index_impl(constantPoolHandle& cpool,
                                           int index, Bytecodes::Code bc,
                                           instanceKlassHandle& accessor) {
+  if (bc == Bytecodes::_invokedynamic) {
+    ConstantPoolCacheEntry* cpce = cpool->invokedynamic_cp_cache_entry_at(index);
+    bool is_resolved = !cpce->is_f1_null();
+    if (is_resolved) {
+      // Get the invoker Method* from the constant pool.
+      // (The appendix argument, if any, will be noted in the method's signature.)
+      Method* adapter = cpce->f1_as_method();
+      return methodHandle(adapter);
+    }
+
+    return NULL;
+  }
+
   int holder_index = cpool->klass_ref_index_at(index);
   bool holder_is_accessible;
   KlassHandle holder = get_klass_by_index_impl(cpool, holder_index, holder_is_accessible, accessor);
@@ -369,7 +382,6 @@
                                      int index, Bytecodes::Code bc,
                                      instanceKlassHandle& accessor) {
   ResourceMark rm;
-  assert(bc != Bytecodes::_invokedynamic, "invokedynamic not yet supported");
   return get_method_by_index_impl(cpool, index, bc, accessor);
 }
 
--- a/src/share/vm/graal/graalJavaAccess.hpp	Tue Apr 09 15:26:29 2013 +0200
+++ b/src/share/vm/graal/graalJavaAccess.hpp	Tue Apr 09 17:25:02 2013 +0200
@@ -119,6 +119,10 @@
     oop_field(Assumptions_ConcreteMethod, context, "Lcom/oracle/graal/api/meta/ResolvedJavaType;")                                                             \
     oop_field(Assumptions_ConcreteMethod, impl, "Lcom/oracle/graal/api/meta/ResolvedJavaMethod;")                                                              \
   end_class                                                                                                                                                    \
+  start_class(Assumptions_CallSiteTargetValue)                                                                                                                 \
+    oop_field(Assumptions_CallSiteTargetValue, callSite, "Ljava/lang/invoke/CallSite;")                                                                        \
+    oop_field(Assumptions_CallSiteTargetValue, methodHandle, "Ljava/lang/invoke/MethodHandle;")                                                                \
+  end_class                                                                                                                                                    \
   start_class(CompilationResult_Site)                                                                                                                          \
     int_field(CompilationResult_Site, pcOffset)                                                                                                                \
   end_class                                                                                                                                                    \