changeset 8136:c66aa27ef4da

Reenable patching of optimized and static calls but without out-of-line stubs.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Wed, 06 Mar 2013 21:58:58 +0100
parents 25ec01061adf
children ae629e3671a0
files graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64DirectCallOp.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotspotDirectStaticCallOp.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotspotDirectVirtualCallOp.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/Marks.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Arithmetic.java graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstructionClass.java src/share/vm/code/compiledIC.cpp src/share/vm/graal/graalCodeInstaller.cpp src/share/vm/graal/graalCodeInstaller.hpp
diffstat 12 files changed, 203 insertions(+), 90 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64DirectCallOp.java	Wed Mar 06 16:39:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2012, 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 com.oracle.graal.hotspot.amd64;
-
-import static com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind.*;
-
-import com.oracle.graal.amd64.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.asm.amd64.*;
-import com.oracle.graal.hotspot.bridge.*;
-import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.LIRInstruction.Opcode;
-import com.oracle.graal.lir.amd64.*;
-import com.oracle.graal.lir.amd64.AMD64Call.DirectCallOp;
-import com.oracle.graal.lir.asm.*;
-import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind;
-
-/**
- * A direct call that complies with the conventions for such calls in HotSpot. In particular, for
- * calls using an inline cache, a MOVE instruction is emitted just prior to the aligned direct call.
- * This instruction (which moves 0L in RAX) is patched by the C++ Graal code to replace the 0L
- * constant with Universe::non_oop_word(), a special sentinel used for the initial value of the
- * Klass in an inline cache.
- */
-@Opcode("CALL_DIRECT")
-final class AMD64DirectCallOp extends DirectCallOp {
-
-    private final InvokeKind invokeKind;
-
-    AMD64DirectCallOp(InvokeTarget target, Value result, Value[] parameters, Value[] temps, LIRFrameState state, InvokeKind invokeKind) {
-        super(target, result, parameters, temps, state);
-        this.invokeKind = invokeKind;
-        assert invokeKind == InvokeKind.Interface || invokeKind == InvokeKind.Virtual;
-    }
-
-    @Override
-    public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-        // The mark for an invocation that uses an inline cache must be placed at the
-        // instruction
-        // that loads the Klass from the inline cache so that the C++ code can find it
-        // and replace the inline 0L value with Universe::non_oop_word()
-        tasm.recordMark(invokeKind == Virtual ? Marks.MARK_INVOKEVIRTUAL : Marks.MARK_INVOKEINTERFACE);
-        AMD64Move.move(tasm, masm, AMD64.rax.asValue(Kind.Long), Constant.LONG_0);
-        emitAlignmentForDirectCall(tasm, masm);
-        AMD64Call.directCall(tasm, masm, callTarget, state);
-    }
-}
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java	Wed Mar 06 16:39:01 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java	Wed Mar 06 21:58:58 2013 +0100
@@ -50,6 +50,7 @@
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.java.*;
+import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind;
 import com.oracle.graal.phases.*;
 
 /**
@@ -154,7 +155,15 @@
 
         @Override
         protected void emitDirectCall(DirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) {
-            append(new AMD64DirectCallOp(callTarget.target(), result, parameters, temps, callState, ((HotSpotDirectCallTargetNode) callTarget).invokeKind()));
+            InvokeKind invokeKind = ((HotSpotDirectCallTargetNode) callTarget).invokeKind();
+            if (invokeKind == InvokeKind.Interface || invokeKind == InvokeKind.Virtual) {
+                append(new AMD64HotspotDirectVirtualCallOp(callTarget.target(), result, parameters, temps, callState, invokeKind));
+            } else {
+                assert invokeKind == InvokeKind.Static || invokeKind == InvokeKind.Special;
+                HotSpotResolvedJavaMethod resolvedMethod = (HotSpotResolvedJavaMethod) callTarget.target();
+                Constant metaspaceMethod = resolvedMethod.getMetaspaceMethodConstant();
+                append(new AMD64HotspotDirectStaticCallOp(callTarget.target(), result, parameters, temps, callState, invokeKind, metaspaceMethod));
+            }
         }
 
         @Override
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotspotDirectStaticCallOp.java	Wed Mar 06 21:58:58 2013 +0100
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2012, 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 com.oracle.graal.hotspot.amd64;
+
+import com.oracle.graal.amd64.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.asm.amd64.*;
+import com.oracle.graal.hotspot.bridge.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.LIRInstruction.Opcode;
+import com.oracle.graal.lir.amd64.*;
+import com.oracle.graal.lir.amd64.AMD64Call.DirectCallOp;
+import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind;
+
+/**
+ * A direct call that complies with the conventions for such calls in HotSpot. In particular, for
+ * calls using an inline cache, a MOVE instruction is emitted just prior to the aligned direct call.
+ * This instruction (which moves 0L in RAX) is patched by the C++ Graal code to replace the 0L
+ * constant with Universe::non_oop_word(), a special sentinel used for the initial value of the
+ * Klass in an inline cache. It puts the called method into rbx before calling.
+ */
+@Opcode("CALL_DIRECT")
+final class AMD64HotspotDirectStaticCallOp extends DirectCallOp {
+
+    private final Constant metaspaceMethod;
+    private final InvokeKind invokeKind;
+
+    AMD64HotspotDirectStaticCallOp(InvokeTarget target, Value result, Value[] parameters, Value[] temps, LIRFrameState state, InvokeKind invokeKind, Constant metaspaceMethod) {
+        super(target, result, parameters, temps, state);
+        assert invokeKind == InvokeKind.Static || invokeKind == InvokeKind.Special;
+        this.metaspaceMethod = metaspaceMethod;
+        this.invokeKind = invokeKind;
+    }
+
+    @Override
+    public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+        // The mark for an invocation that uses an inline cache must be placed at the
+        // instruction
+        // that loads the Klass from the inline cache so that the C++ code can find it
+        // and replace the inline 0L value with Universe::non_oop_word()
+        AMD64Move.move(tasm, masm, AMD64.rbx.asValue(Kind.Long), metaspaceMethod);
+        tasm.recordMark(invokeKind == InvokeKind.Static ? Marks.MARK_INVOKESTATIC : Marks.MARK_INVOKESPECIAL);
+        AMD64Move.move(tasm, masm, AMD64.rax.asValue(Kind.Long), Constant.LONG_0);
+        super.emitCode(tasm, masm);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotspotDirectVirtualCallOp.java	Wed Mar 06 21:58:58 2013 +0100
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2012, 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 com.oracle.graal.hotspot.amd64;
+
+import static com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind.*;
+
+import com.oracle.graal.amd64.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.asm.amd64.*;
+import com.oracle.graal.hotspot.bridge.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.LIRInstruction.Opcode;
+import com.oracle.graal.lir.amd64.*;
+import com.oracle.graal.lir.amd64.AMD64Call.DirectCallOp;
+import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind;
+
+/**
+ * A direct call that complies with the conventions for such calls in HotSpot. In particular, for
+ * calls using an inline cache, a MOVE instruction is emitted just prior to the aligned direct call.
+ * This instruction (which moves 0L in RAX) is patched by the C++ Graal code to replace the 0L
+ * constant with Universe::non_oop_word(), a special sentinel used for the initial value of the
+ * Klass in an inline cache.
+ */
+@Opcode("CALL_DIRECT")
+final class AMD64HotspotDirectVirtualCallOp extends DirectCallOp {
+
+    private final InvokeKind invokeKind;
+
+    AMD64HotspotDirectVirtualCallOp(InvokeTarget target, Value result, Value[] parameters, Value[] temps, LIRFrameState state, InvokeKind invokeKind) {
+        super(target, result, parameters, temps, state);
+        this.invokeKind = invokeKind;
+        assert invokeKind == InvokeKind.Interface || invokeKind == InvokeKind.Virtual;
+    }
+
+    @Override
+    public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+        // The mark for an invocation that uses an inline cache must be placed at the
+        // instruction
+        // that loads the Klass from the inline cache so that the C++ code can find it
+        // and replace the inline 0L value with Universe::non_oop_word()
+        tasm.recordMark(invokeKind == Virtual ? Marks.MARK_INVOKEVIRTUAL : Marks.MARK_INVOKEINTERFACE);
+        AMD64Move.move(tasm, masm, AMD64.rax.asValue(Kind.Long), Constant.LONG_0);
+        super.emitCode(tasm, masm);
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/Marks.java	Wed Mar 06 16:39:01 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/Marks.java	Wed Mar 06 21:58:58 2013 +0100
@@ -36,9 +36,11 @@
     int MARK_DEOPT_HANDLER_ENTRY = 5;
     int MARK_INVOKEINTERFACE = 6;
     int MARK_INVOKEVIRTUAL = 7;
-    int MARK_INLINE_INVOKE = 8;
-    int MARK_POLL_NEAR = 9;
-    int MARK_POLL_RETURN_NEAR = 10;
-    int MARK_POLL_FAR = 11;
-    int MARK_POLL_RETURN_FAR = 12;
+    int MARK_INVOKESTATIC = 8;
+    int MARK_INVOKESPECIAL = 9;
+    int MARK_INLINE_INVOKE = 10;
+    int MARK_POLL_NEAR = 11;
+    int MARK_POLL_RETURN_NEAR = 12;
+    int MARK_POLL_FAR = 13;
+    int MARK_POLL_RETURN_FAR = 14;
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Wed Mar 06 16:39:01 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Wed Mar 06 21:58:58 2013 +0100
@@ -565,13 +565,8 @@
                         }
                     }
                 } else if (callTarget.invokeKind() == InvokeKind.Special || callTarget.invokeKind() == InvokeKind.Static) {
-                    HotSpotResolvedJavaMethod hsMethod = (HotSpotResolvedJavaMethod) callTarget.targetMethod();
-                    ConstantNode metaspaceMethod = ConstantNode.forConstant(hsMethod.getMetaspaceMethodConstant(), this, graph);
-                    ReadNode compiledEntry = graph.add(new ReadNode(metaspaceMethod, LocationNode.create(LocationNode.ANY_LOCATION, wordKind, config.methodCompiledEntryOffset, graph),
-                                    StampFactory.forKind(wordKind())));
-                    loweredCallTarget = graph.add(new HotSpotIndirectCallTargetNode(metaspaceMethod, compiledEntry, parameters, invoke.node().stamp(), signature, callTarget.targetMethod(),
-                                    CallingConvention.Type.JavaCall));
-                    graph.addBeforeFixed(invoke.node(), compiledEntry);
+                    loweredCallTarget = graph.add(new HotSpotDirectCallTargetNode(parameters, invoke.node().stamp(), signature, callTarget.targetMethod(), CallingConvention.Type.JavaCall,
+                                    callTarget.invokeKind()));
                 }
 
                 if (loweredCallTarget == null) {
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Arithmetic.java	Wed Mar 06 16:39:01 2013 +0100
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Arithmetic.java	Wed Mar 06 21:58:58 2013 +0100
@@ -159,7 +159,7 @@
         @Opcode private final AMD64Arithmetic opcode;
         @Def({REG, HINT}) protected AllocatableValue result;
         @Use({REG, STACK}) protected AllocatableValue x;
-        @Use({CONST}) protected Constant y;
+        protected Constant y;
 
         public BinaryRegConst(AMD64Arithmetic opcode, AllocatableValue result, AllocatableValue x, Constant y) {
             this.opcode = opcode;
@@ -221,7 +221,7 @@
         @Opcode private final AMD64Arithmetic opcode;
         @Def({REG}) protected AllocatableValue result;
         @Use({REG, STACK}) protected AllocatableValue x;
-        @Use({CONST}) protected Constant y;
+        protected Constant y;
 
         public BinaryRegStackConst(AMD64Arithmetic opcode, AllocatableValue result, AllocatableValue x, Constant y) {
             this.opcode = opcode;
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java	Wed Mar 06 16:39:01 2013 +0100
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java	Wed Mar 06 21:58:58 2013 +0100
@@ -230,7 +230,7 @@
 
     public static class StoreConstantOp extends MemOp {
 
-        @Use({CONST}) protected Constant input;
+        protected final Constant input;
 
         public StoreConstantOp(AMD64Address address, Constant input, LIRFrameState state) {
             super(address, state);
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstructionClass.java	Wed Mar 06 16:39:01 2013 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstructionClass.java	Wed Mar 06 21:58:58 2013 +0100
@@ -58,6 +58,7 @@
 
     private static final Class<?> INSTRUCTION_CLASS = LIRInstruction.class;
     private static final Class<?> VALUE_CLASS = Value.class;
+    private static final Class<?> CONSTANT_CLASS = Constant.class;
     private static final Class<?> VALUE_ARRAY_CLASS = Value[].class;
     private static final Class<?> STATE_CLASS = LIRFrameState.class;
 
@@ -219,7 +220,7 @@
 
         @Override
         protected void scanField(Field field, Class<?> type, long offset) {
-            if (VALUE_CLASS.isAssignableFrom(type)) {
+            if (VALUE_CLASS.isAssignableFrom(type) && type != CONSTANT_CLASS) {
                 assert !Modifier.isFinal(field.getModifiers()) : "Value field must not be declared final because it is modified by register allocator: " + field;
                 OperandModeAnnotation annotation = getOperandModeAnnotation(field);
                 assert annotation != null : "Field must have operand mode annotation: " + field;
--- a/src/share/vm/code/compiledIC.cpp	Wed Mar 06 16:39:01 2013 +0100
+++ b/src/share/vm/code/compiledIC.cpp	Wed Mar 06 21:58:58 2013 +0100
@@ -95,7 +95,7 @@
   // Don't use ic_destination for this test since that forwards
   // through ICBuffer instead of returning the actual current state of
   // the CompiledIC.
-  if (is_icholder_entry(_ic_call->destination())) {
+  if (is_icholder_entry(_ic_call->destination()) && !_is_optimized) {
     // When patching for the ICStub case the cached value isn't
     // overwritten until the ICStub copied into the CompiledIC during
     // the next safepoint.  Make sure that the CompiledICHolder* is
@@ -126,6 +126,13 @@
   _ic_call->set_destination_mt_safe(entry_point);
 }
 
+#ifdef GRAAL
+  if (_value == NULL) {
+    // Can happen when Graal converted a virtual call into an invoke special based on static analysis.
+    return;
+  }
+#endif
+
   if (is_optimized() || is_icstub) {
     // Optimized call sites don't have a cache value and ICStub call
     // sites only change the entry point.  Changing the value in that
@@ -265,12 +272,14 @@
     // Check if we are calling into our own codeblob (i.e., to a stub)
     CodeBlob* cb = CodeCache::find_blob(_ic_call->instruction_address());
     address dest = ic_destination();
+#ifndef GRAAL
 #ifdef ASSERT
     {
       CodeBlob* db = CodeCache::find_blob_unsafe(dest);
       assert(!db->is_adapter_blob(), "must use stub!");
     }
 #endif /* ASSERT */
+#endif
     is_call_to_interpreted = cb->contains(dest);
   }
   return is_call_to_interpreted;
@@ -551,7 +560,13 @@
 
 
 void CompiledStaticCall::set_to_interpreted(methodHandle callee, address entry) {
+  set_destination_mt_safe(entry);
   address stub=find_stub();
+#ifdef GRAAL
+  if (stub == NULL) {
+    return;
+  }
+#endif
   assert(stub!=NULL, "stub not found");
 
   if (TraceICs) {
@@ -646,7 +661,11 @@
         case relocInfo::poll_type:
         case relocInfo::poll_return_type: // A safepoint can't overlap a call.
         default:
+#ifdef GRAAL
+          return NULL;
+#else
           ShouldNotReachHere();
+#endif
       }
     }
   }
@@ -702,9 +721,11 @@
 
   // Verify stub
   address stub = find_stub();
+#ifndef GRAAL
   assert(stub != NULL, "no stub found for static call");
   NativeMovConstReg* method_holder = nativeMovConstReg_at(stub);   // creation also verifies the object
   NativeJump*        jump          = nativeJump_at(method_holder->next_instruction_address());
+#endif
 
   // Verify state
   assert(is_clean() || is_call_to_compiled() || is_call_to_interpreted(), "sanity check");
--- a/src/share/vm/graal/graalCodeInstaller.cpp	Wed Mar 06 16:39:01 2013 +0100
+++ b/src/share/vm/graal/graalCodeInstaller.cpp	Wed Mar 06 21:58:58 2013 +0100
@@ -699,6 +699,21 @@
         _instructions->relocate(call->instruction_address(), virtual_call_Relocation::spec(_invoke_mark_pc), Assembler::call32_operand);
         break;
       }
+      case MARK_INVOKESTATIC: {
+        assert(method == NULL || method->is_static(), "cannot call non-static method with invokestatic");
+
+        NativeCall* call = nativeCall_at(_instructions->start() + pc_offset);
+        call->set_destination(SharedRuntime::get_resolve_static_call_stub());
+        _instructions->relocate(call->instruction_address(), relocInfo::static_call_type, Assembler::call32_operand);
+        break;
+      }
+      case MARK_INVOKESPECIAL: {
+        assert(method == NULL || !method->is_static(), "cannot call static method with invokespecial");
+        NativeCall* call = nativeCall_at(_instructions->start() + pc_offset);
+        call->set_destination(SharedRuntime::get_resolve_opt_virtual_call_stub());
+        _instructions->relocate(call->instruction_address(), relocInfo::opt_virtual_call_type, Assembler::call32_operand);
+        break;
+      }
       default:
         fatal("invalid _next_call_type value");
         break;
@@ -807,6 +822,8 @@
         n_copy->set_data((intptr_t)Universe::non_oop_word());
       }
       case MARK_INLINE_INVOKE:
+      case MARK_INVOKESTATIC:
+      case MARK_INVOKESPECIAL:
         _next_call_type = (MarkId) id;
         _invoke_mark_pc = instruction;
         break;
--- a/src/share/vm/graal/graalCodeInstaller.hpp	Wed Mar 06 16:39:01 2013 +0100
+++ b/src/share/vm/graal/graalCodeInstaller.hpp	Wed Mar 06 21:58:58 2013 +0100
@@ -38,11 +38,13 @@
     MARK_DEOPT_HANDLER_ENTRY        = 5,
     MARK_INVOKEINTERFACE            = 6,
     MARK_INVOKEVIRTUAL              = 7,
-    MARK_INLINE_INVOKE              = 8,
-    MARK_POLL_NEAR                  = 9,
-    MARK_POLL_RETURN_NEAR           = 10,
-    MARK_POLL_FAR                   = 11,
-    MARK_POLL_RETURN_FAR            = 12,
+    MARK_INVOKESTATIC               = 8,
+    MARK_INVOKESPECIAL              = 9,
+    MARK_INLINE_INVOKE              = 10,
+    MARK_POLL_NEAR                  = 11,
+    MARK_POLL_RETURN_NEAR           = 12,
+    MARK_POLL_FAR                   = 13,
+    MARK_POLL_RETURN_FAR            = 14,
     MARK_INVOKE_INVALID             = -1
   };