changeset 9023:f94bb5d20e5d

Rename MethodInvalidatedException to InvalidInstalledCodeException (and make it a checked exception). Make sure that a compiled code object can always be directly called without first doing a check on the native method pointer.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Thu, 11 Apr 2013 17:36:46 +0200
parents 7844a36d0216
children 2b840ae76df1
files graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/InstalledCode.java graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/InvalidInstalledCodeException.java graal/com.oracle.graal.asm.test/src/com/oracle/graal/asm/test/AssemblerTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/deopt/CompiledMethodTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/deopt/SynchronizedMethodDeoptimizationTest.java graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotInstalledCodeTest.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotInstalledCode.java src/share/vm/classfile/vmSymbols.hpp src/share/vm/code/nmethod.cpp src/share/vm/graal/graalCompilerToVM.cpp src/share/vm/runtime/javaCalls.cpp src/share/vm/runtime/sharedRuntime.cpp src/share/vm/runtime/sharedRuntime.hpp
diffstat 15 files changed, 160 insertions(+), 134 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/InstalledCode.java	Thu Apr 11 13:03:20 2013 +0200
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/InstalledCode.java	Thu Apr 11 17:36:46 2013 +0200
@@ -31,14 +31,6 @@
 public interface InstalledCode {
 
     /**
-     * Exception thrown by the runtime in case an invalidated machine code is called.
-     */
-    public abstract class MethodInvalidatedException extends RuntimeException {
-
-        private static final long serialVersionUID = -3540232440794244844L;
-    }
-
-    /**
      * Returns the method (if any) to which the installed code belongs.
      */
     ResolvedJavaMethod getMethod();
@@ -61,6 +53,12 @@
     boolean isValid();
 
     /**
+     * Invalidates this installed code such that any subsequent invocation will throw an
+     * {@link InvalidInstalledCodeException}.
+     */
+    void invalidate();
+
+    /**
      * Executes the installed code with three object arguments.
      * 
      * @param arg1 the first argument
@@ -68,7 +66,7 @@
      * @param arg3 the third argument
      * @return the value returned by the executed code
      */
-    Object execute(Object arg1, Object arg2, Object arg3);
+    Object execute(Object arg1, Object arg2, Object arg3) throws InvalidInstalledCodeException;
 
     /**
      * Executes the installed code with a variable number of arguments.
@@ -76,5 +74,5 @@
      * @param args the array of object arguments
      * @return the value returned by the executed code
      */
-    Object executeVarargs(Object... args);
+    Object executeVarargs(Object... args) throws InvalidInstalledCodeException;
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/InvalidInstalledCodeException.java	Thu Apr 11 17:36:46 2013 +0200
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2013, 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.api.code;
+
+/**
+ * Exception thrown by the runtime in case an invalidated machine code is called.
+ */
+public final class InvalidInstalledCodeException extends Exception {
+
+    private static final long serialVersionUID = -3540232440794244844L;
+}
--- a/graal/com.oracle.graal.asm.test/src/com/oracle/graal/asm/test/AssemblerTest.java	Thu Apr 11 13:03:20 2013 +0200
+++ b/graal/com.oracle.graal.asm.test/src/com/oracle/graal/asm/test/AssemblerTest.java	Thu Apr 11 17:36:46 2013 +0200
@@ -67,7 +67,11 @@
     protected Object runTest(String methodName, CodeGenTest test, Object... args) {
         Method method = getMethod(methodName);
         InstalledCode code = assembleMethod(method, test);
-        return code.executeVarargs(args);
+        try {
+            return code.executeVarargs(args);
+        } catch (InvalidInstalledCodeException e) {
+            throw new RuntimeException(e);
+        }
     }
 
     protected void assertReturn(String methodName, CodeGenTest test, Object expected, Object... args) {
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/deopt/CompiledMethodTest.java	Thu Apr 11 13:03:20 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/deopt/CompiledMethodTest.java	Thu Apr 11 17:36:46 2013 +0200
@@ -75,7 +75,7 @@
         try {
             Object result = compiledMethod.execute("1", "2", "3");
             Assert.assertEquals("1-2-3", result);
-        } catch (MethodInvalidatedException t) {
+        } catch (InvalidInstalledCodeException t) {
             Assert.fail("method invalidated");
         }
     }
@@ -89,7 +89,7 @@
         try {
             Object result = compiledMethod.executeVarargs("1", "2", "3");
             Assert.assertEquals("1 2 3", result);
-        } catch (MethodInvalidatedException t) {
+        } catch (InvalidInstalledCodeException t) {
             Assert.fail("method invalidated");
         }
     }
@@ -104,98 +104,8 @@
             f1 = "0";
             Object result = compiledMethod.executeVarargs(this, "1", "2", "3");
             Assert.assertEquals("0 1 2 3", result);
-        } catch (MethodInvalidatedException t) {
+        } catch (InvalidInstalledCodeException t) {
             Assert.fail("method invalidated");
         }
     }
-
-    @LongTest
-    public void test2() throws NoSuchMethodException, SecurityException {
-        Method method = CompilableObjectImpl.class.getDeclaredMethod("executeHelper", ObjectCompiler.class, String.class);
-        ResolvedJavaMethod javaMethod = runtime.lookupJavaMethod(method);
-        StructuredGraph graph = new StructuredGraph(javaMethod);
-        new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.NONE).apply(graph);
-        new CanonicalizerPhase(runtime, new Assumptions(false)).apply(graph);
-        new DeadCodeEliminationPhase().apply(graph);
-
-        for (Node node : graph.getNodes()) {
-            if (node instanceof ConstantNode) {
-                ConstantNode constant = (ConstantNode) node;
-                if (constant.kind() == Kind.Object && "1 ".equals(constant.value.asObject())) {
-                    graph.replaceFloating(constant, ConstantNode.forObject("1-", runtime, graph));
-                }
-            }
-        }
-
-        InstalledCode compiledMethod = getCode(javaMethod, graph);
-        final CompilableObject compilableObject = new CompilableObjectImpl(0);
-
-        Object result;
-        result = compilableObject.execute(new ObjectCompilerImpl(compiledMethod), "3");
-        Assert.assertEquals("1-3", result);
-    }
-
-    public abstract class CompilableObject {
-
-        private CompiledObject compiledObject;
-        private final int compileThreshold;
-        private int counter;
-
-        public CompilableObject(int compileThreshold) {
-            this.compileThreshold = compileThreshold;
-        }
-
-        public final Object execute(ObjectCompiler compiler, String args) {
-            if (counter++ < compileThreshold || compiler == null) {
-                return executeHelper(compiler, args);
-            } else {
-                compiledObject = compiler.compile(this);
-                return compiledObject.execute(compiler, args);
-            }
-        }
-
-        protected abstract Object executeHelper(ObjectCompiler context, String args);
-    }
-
-    private final class CompilableObjectImpl extends CompilableObject {
-
-        private CompilableObjectImpl(int compileThreshold) {
-            super(compileThreshold);
-        }
-
-        @Override
-        protected Object executeHelper(ObjectCompiler compiler, String args) {
-            return "1 " + args;
-        }
-    }
-
-    public interface CompiledObject {
-
-        Object execute(ObjectCompiler context, String args);
-    }
-
-    public interface ObjectCompiler {
-
-        CompiledObject compile(CompilableObject node);
-    }
-
-    private final class ObjectCompilerImpl implements ObjectCompiler {
-
-        private final InstalledCode compiledMethod;
-
-        private ObjectCompilerImpl(InstalledCode compiledMethod) {
-            this.compiledMethod = compiledMethod;
-        }
-
-        @Override
-        public CompiledObject compile(final CompilableObject node) {
-            return new CompiledObject() {
-
-                @Override
-                public Object execute(ObjectCompiler compiler, String args) {
-                    return compiledMethod.execute(node, compiler, args);
-                }
-            };
-        }
-    }
 }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/deopt/SynchronizedMethodDeoptimizationTest.java	Thu Apr 11 13:03:20 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/deopt/SynchronizedMethodDeoptimizationTest.java	Thu Apr 11 17:36:46 2013 +0200
@@ -27,7 +27,6 @@
 import org.junit.*;
 
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.code.InstalledCode.MethodInvalidatedException;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.test.*;
 import com.oracle.graal.nodes.*;
@@ -59,7 +58,7 @@
         try {
             Object result = compiledMethod.executeVarargs(testString);
             Assert.assertEquals(testString, result);
-        } catch (MethodInvalidatedException t) {
+        } catch (InvalidInstalledCodeException t) {
             Assert.fail("method invalidated");
         }
 
@@ -67,7 +66,7 @@
             Object result = compiledMethod.executeVarargs(new Object[]{null});
             Assert.assertEquals(null, result);
             Assert.assertFalse(compiledMethod.isValid());
-        } catch (MethodInvalidatedException t) {
+        } catch (InvalidInstalledCodeException t) {
             Assert.fail("method invalidated");
         }
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotInstalledCodeTest.java	Thu Apr 11 17:36:46 2013 +0200
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2013, 2013, 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.test;
+
+import org.junit.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.test.*;
+import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.nodes.*;
+
+public class HotSpotInstalledCodeTest extends GraalCompilerTest {
+
+    @Test
+    public void testInstallCode() {
+        final ResolvedJavaMethod testJavaMethod = runtime.lookupJavaMethod(getMethod("foo"));
+        final StructuredGraph graph = parse("otherFoo");
+        final HotSpotInstalledCode installedCode = (HotSpotInstalledCode) getCode(testJavaMethod, graph);
+        Object result = installedCode.execute(null, null, null);
+        assertEquals(43, result);
+        installedCode.invalidate();
+        result = installedCode.execute(null, null, null);
+        System.out.println(result);
+    }
+
+    @SuppressWarnings("unused")
+    public static Object foo(Object a1, Object a2, Object a3) {
+        return 42;
+    }
+
+    @SuppressWarnings("unused")
+    public static Object otherFoo(Object a1, Object a2, Object a3) {
+        return 43;
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java	Thu Apr 11 13:03:20 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java	Thu Apr 11 17:36:46 2013 +0200
@@ -223,4 +223,8 @@
     void reprofile(long metaspaceMethod);
 
     Object lookupAppendixInPool(HotSpotResolvedObjectType pool, int cpi);
+
+    void invalidateInstalledCode(long nativeMethod);
+
+    boolean isInstalledCodeValid(long nativeMethod);
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java	Thu Apr 11 13:03:20 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java	Thu Apr 11 17:36:46 2013 +0200
@@ -161,4 +161,10 @@
 
     @Override
     public native Object lookupAppendixInPool(HotSpotResolvedObjectType pool, int cpi);
+
+    @Override
+    public native void invalidateInstalledCode(long nativeMethod);
+
+    @Override
+    public native boolean isInstalledCodeValid(long nativeMethod);
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotInstalledCode.java	Thu Apr 11 13:03:20 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotInstalledCode.java	Thu Apr 11 17:36:46 2013 +0200
@@ -62,7 +62,12 @@
 
     @Override
     public boolean isValid() {
-        return nmethod != 0;
+        return HotSpotGraalRuntime.getInstance().getCompilerToVM().isInstalledCodeValid(nmethod);
+    }
+
+    @Override
+    public void invalidate() {
+        HotSpotGraalRuntime.getInstance().getCompilerToVM().invalidateInstalledCode(nmethod);
     }
 
     @Override
--- a/src/share/vm/classfile/vmSymbols.hpp	Thu Apr 11 13:03:20 2013 +0200
+++ b/src/share/vm/classfile/vmSymbols.hpp	Thu Apr 11 17:36:46 2013 +0200
@@ -338,6 +338,7 @@
   template(com_oracle_graal_api_code_RegisterValue,                  "com/oracle/graal/api/code/RegisterValue")                       \
   template(com_oracle_graal_api_code_StackSlot,                      "com/oracle/graal/api/code/StackSlot")                           \
   template(com_oracle_graal_api_code_VirtualObject,                  "com/oracle/graal/api/code/VirtualObject")                       \
+  template(com_oracle_graal_api_code_InvalidInstalledCodeException,  "com/oracle/graal/api/code/InvalidInstalledCodeException")       \
   template(startCompiler_name,                    "startCompiler")                                                                    \
   template(bootstrap_name,                        "bootstrap")                                                                        \
   template(shutdownCompiler_name,                 "shutdownCompiler")                                                                 \
@@ -378,7 +379,6 @@
   template(forObject_name,                        "forObject")                                                                        \
   template(callbackInternal_name,                 "callbackInternal")                                                                 \
   template(callback_signature,                    "(Ljava/lang/Object;)Ljava/lang/Object;")                                           \
-  template(MethodInvalidatedException,            "com/oracle/graal/api/code/InstalledCode$MethodInvalidatedException")               \
   /* graal.api.interpreter */                                                                                                         \
   template(com_oracle_graal_api_interpreter_Interpreter,             "com/oracle/graal/api/interpreter/Interpreter")                  \
   template(interpreter_execute_name,              "execute")                                                                          \
--- a/src/share/vm/code/nmethod.cpp	Thu Apr 11 13:03:20 2013 +0200
+++ b/src/share/vm/code/nmethod.cpp	Thu Apr 11 17:36:46 2013 +0200
@@ -1306,13 +1306,6 @@
     _method = NULL;            // Clear the method of this dead nmethod
   }
 
-#ifdef GRAAL
-    if (_graal_installed_code != NULL) {
-      HotSpotInstalledCode::set_nmethod(_graal_installed_code, 0);
-      _graal_installed_code = NULL;
-    }
-#endif
-
   // Make the class unloaded - i.e., change state and notify sweeper
   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
   if (is_in_use()) {
@@ -1394,18 +1387,17 @@
       return false;
     }
 
-#ifdef GRAAL
-    if (_graal_installed_code != NULL) {
-      HotSpotInstalledCode::set_nmethod(_graal_installed_code, 0);
-      _graal_installed_code = NULL;
-    }
-#endif
-
     // The caller can be calling the method statically or through an inline
     // cache call.
     if (!is_osr_method() && !is_not_entrant()) {
-      NativeJump::patch_verified_entry(entry_point(), verified_entry_point(),
-                  SharedRuntime::get_handle_wrong_method_stub());
+      if (_graal_installed_code != NULL && !HotSpotInstalledCode::isDefault(_graal_installed_code)) {
+        // This was manually installed machine code. Patch entry with stub that throws an exception.
+        NativeJump::patch_verified_entry(entry_point(), verified_entry_point(),
+                    SharedRuntime::get_deoptimized_installed_code_stub());
+      } else {
+        NativeJump::patch_verified_entry(entry_point(), verified_entry_point(),
+                    SharedRuntime::get_handle_wrong_method_stub());
+      }
     }
 
     if (is_in_use()) {
--- a/src/share/vm/graal/graalCompilerToVM.cpp	Thu Apr 11 13:03:20 2013 +0200
+++ b/src/share/vm/graal/graalCompilerToVM.cpp	Thu Apr 11 17:36:46 2013 +0200
@@ -911,10 +911,6 @@
   JavaValue result(jap.get_ret_type());
 
   nmethod* nm = (nmethod*) (address) metaspace_nmethod;
-  if (nm == NULL || !nm->is_alive()) {
-    THROW_0(vmSymbols::MethodInvalidatedException());
-  }
-
   jca.set_alternative_target(nm);
   JavaCalls::call(&result, mh, &jca, CHECK_NULL);
 
@@ -941,10 +937,6 @@
   args.push_oop(JNIHandles::resolve(arg3));
 
   nmethod* nm = (nmethod*) (address) metaspace_nmethod;
-  if (nm == NULL || !nm->is_alive()) {
-    THROW_0(vmSymbols::MethodInvalidatedException());
-  }
-
   args.set_alternative_target(nm);
   JavaCalls::call(&result, method, &args, CHECK_NULL);
 
@@ -1069,6 +1061,18 @@
 C2V_END
 
 
+C2V_VMENTRY(void, invalidateInstalledCode, (JNIEnv *env, jobject, jlong nativeMethod))
+  nmethod* m = (nmethod*)nativeMethod;
+  m->mark_for_deoptimization();
+  VM_Deoptimize op;
+  VMThread::execute(&op);
+C2V_END
+
+
+C2V_VMENTRY(jboolean, isInstalledCodeValid, (JNIEnv *env, jobject, jlong nativeMethod))
+  nmethod* m = (nmethod*)nativeMethod;
+  return m->is_alive();
+C2V_END
 
 #define CC (char*)  /*cast a literal from (const char*)*/
 #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &(c2v_ ## f))
@@ -1146,6 +1150,8 @@
   {CC"getFileName",                   CC"("HS_RESOLVED_JAVA_TYPE")"STRING,                              FN_PTR(getFileName)},
   {CC"clearQueuedForCompilation",     CC"("HS_RESOLVED_METHOD")V",                                      FN_PTR(clearQueuedForCompilation)},
   {CC"reprofile",                     CC"("METASPACE_METHOD")V",                                        FN_PTR(reprofile)},
+  {CC"invalidateInstalledCode",       CC"(J)V",                                                         FN_PTR(invalidateInstalledCode)},
+  {CC"isInstalledCodeValid",          CC"(J)Z",                                                         FN_PTR(isInstalledCodeValid)},
 };
 
 int CompilerToVM_methods_count() {
--- a/src/share/vm/runtime/javaCalls.cpp	Thu Apr 11 13:03:20 2013 +0200
+++ b/src/share/vm/runtime/javaCalls.cpp	Thu Apr 11 17:36:46 2013 +0200
@@ -412,7 +412,7 @@
       ((JavaThread*) THREAD)->set_graal_alternate_call_target(nm->verified_entry_point());
       entry_point = method->adapter()->get_i2c_entry();
     } else {
-      THROW(vmSymbols::MethodInvalidatedException());
+      THROW(vmSymbols::com_oracle_graal_api_code_InvalidInstalledCodeException());
     }
   }
 #endif
--- a/src/share/vm/runtime/sharedRuntime.cpp	Thu Apr 11 13:03:20 2013 +0200
+++ b/src/share/vm/runtime/sharedRuntime.cpp	Thu Apr 11 17:36:46 2013 +0200
@@ -83,6 +83,7 @@
 #endif
 
 // Shared stub locations
+RuntimeStub*        SharedRuntime::_deoptimized_installed_code_blob;
 RuntimeStub*        SharedRuntime::_wrong_method_blob;
 RuntimeStub*        SharedRuntime::_ic_miss_blob;
 RuntimeStub*        SharedRuntime::_resolve_opt_virtual_call_blob;
@@ -101,6 +102,7 @@
 
 //----------------------------generate_stubs-----------------------------------
 void SharedRuntime::generate_stubs() {
+  _deoptimized_installed_code_blob     = generate_resolve_blob(CAST_FROM_FN_PTR(address, SharedRuntime::handle_deoptimized_installed_code), "deoptimized_installed_code");
   _wrong_method_blob                   = generate_resolve_blob(CAST_FROM_FN_PTR(address, SharedRuntime::handle_wrong_method),         "wrong_method_stub");
   _ic_miss_blob                        = generate_resolve_blob(CAST_FROM_FN_PTR(address, SharedRuntime::handle_wrong_method_ic_miss), "ic_miss_stub");
   _resolve_opt_virtual_call_blob       = generate_resolve_blob(CAST_FROM_FN_PTR(address, SharedRuntime::resolve_opt_virtual_call_C),  "resolve_opt_virtual_call");
@@ -1350,6 +1352,11 @@
   return callee_method->verified_code_entry();
 JRT_END
 
+// Installed code has been deoptimized
+JRT_BLOCK_ENTRY(address, SharedRuntime::handle_deoptimized_installed_code(JavaThread* thread))
+  JavaThread* THREAD = thread;
+  THROW_(vmSymbols::java_lang_NullPointerException(), NULL);
+JRT_END
 
 // Handle call site that has been made non-entrant
 JRT_BLOCK_ENTRY(address, SharedRuntime::handle_wrong_method(JavaThread* thread))
--- a/src/share/vm/runtime/sharedRuntime.hpp	Thu Apr 11 13:03:20 2013 +0200
+++ b/src/share/vm/runtime/sharedRuntime.hpp	Thu Apr 11 17:36:46 2013 +0200
@@ -55,6 +55,7 @@
 
   // Shared stub locations
 
+  static RuntimeStub*        _deoptimized_installed_code_blob;
   static RuntimeStub*        _wrong_method_blob;
   static RuntimeStub*        _ic_miss_blob;
   static RuntimeStub*        _resolve_opt_virtual_call_blob;
@@ -209,6 +210,11 @@
     return _wrong_method_blob->entry_point();
   }
 
+  static address get_deoptimized_installed_code_stub() {
+    assert(_deoptimized_installed_code_blob!= NULL, "oops");
+    return _deoptimized_installed_code_blob->entry_point();
+  }
+
 #ifdef COMPILER2
   static void generate_uncommon_trap_blob(void);
   static UncommonTrapBlob* uncommon_trap_blob()                  { return _uncommon_trap_blob; }
@@ -486,6 +492,9 @@
   static address handle_wrong_method(JavaThread* thread);
   static address handle_wrong_method_ic_miss(JavaThread* thread);
 
+  // handle deoptimized installed code
+  static address handle_deoptimized_installed_code(JavaThread* thread);
+
 #ifndef PRODUCT
 
   // Collect and print inline cache miss statistics