# HG changeset patch # User Lukas Stadler # Date 1330448435 -3600 # Node ID 897b7d18bebc2b72c56d45a867825574efabaafe # Parent f86ddbd42a7bb461725f92cecbd86f6c5783dacb added RiCompiledMethod.execute and the required VM infrastructure diff -r f86ddbd42a7b -r 897b7d18bebc graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiCompiledMethod.java --- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiCompiledMethod.java Tue Feb 28 17:53:07 2012 +0100 +++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiCompiledMethod.java Tue Feb 28 18:00:35 2012 +0100 @@ -27,6 +27,11 @@ */ public interface RiCompiledMethod { + public abstract class MethodInvalidatedException extends RuntimeException { + + private static final long serialVersionUID = -3540232440794244844L; + } + /** * Returns the method to which the compiled code belongs. * @return the method to which the compiled code belongs. @@ -37,4 +42,6 @@ * @return true if the code represented by this object is still valid, false otherwise (may happen due to deopt, etc.) */ boolean isValid(); + + Object execute(Object arg1, Object arg2, Object arg3); } diff -r f86ddbd42a7b -r 897b7d18bebc graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java Tue Feb 28 17:53:07 2012 +0100 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java Tue Feb 28 18:00:35 2012 +0100 @@ -156,6 +156,7 @@ if (plan != null) { plan.runPhases(PhasePosition.AFTER_PARSING, newGraph); } + assert newGraph.start().next() != null : "graph needs to be populated during PhasePosition.AFTER_PARSING"; if (GraalOptions.ProbabilityAnalysis) { new DeadCodeEliminationPhase().apply(newGraph); diff -r f86ddbd42a7b -r 897b7d18bebc graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/bridge/CompilerToVM.java --- a/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/bridge/CompilerToVM.java Tue Feb 28 17:53:07 2012 +0100 +++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/bridge/CompilerToVM.java Tue Feb 28 18:00:35 2012 +0100 @@ -109,5 +109,7 @@ String disassembleJava(HotSpotMethodResolved method); + Object executeCompiledMethod(HotSpotCompiledMethod method, Object arg1, Object arg2, Object arg3); + // Checkstyle: resume } diff -r f86ddbd42a7b -r 897b7d18bebc graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/bridge/CompilerToVMImpl.java --- a/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/bridge/CompilerToVMImpl.java Tue Feb 28 17:53:07 2012 +0100 +++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/bridge/CompilerToVMImpl.java Tue Feb 28 18:00:35 2012 +0100 @@ -156,5 +156,8 @@ @Override public native String disassembleJava(HotSpotMethodResolved method); + @Override + public native Object executeCompiledMethod(HotSpotCompiledMethod method, Object arg1, Object arg2, Object arg3); + // Checkstyle: resume } diff -r f86ddbd42a7b -r 897b7d18bebc graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotCompiledMethod.java --- a/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotCompiledMethod.java Tue Feb 28 17:53:07 2012 +0100 +++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotCompiledMethod.java Tue Feb 28 18:00:35 2012 +0100 @@ -22,17 +22,25 @@ */ package com.oracle.max.graal.hotspot.ri; +import java.lang.reflect.*; + +import com.oracle.max.cri.ci.*; import com.oracle.max.cri.ri.*; +import com.oracle.max.graal.hotspot.*; +import com.oracle.max.graal.hotspot.Compiler; /** * Implementation of RiCompiledMethod for HotSpot. Stores a reference to the nmethod which contains the compiled code. */ -public class HotSpotCompiledMethod implements RiCompiledMethod { +public class HotSpotCompiledMethod extends CompilerObject implements RiCompiledMethod { + + private static final long serialVersionUID = 156632908220561612L; private final RiResolvedMethod method; private long nmethod; - public HotSpotCompiledMethod(RiResolvedMethod method) { + public HotSpotCompiledMethod(Compiler compiler, RiResolvedMethod method) { + super(compiler); this.method = method; } @@ -50,4 +58,13 @@ public String toString() { return "compiled method " + method + " @" + nmethod; } + + @Override + public Object execute(Object arg1, Object arg2, Object arg3) { + assert method.signature().argumentCount(!Modifier.isStatic(method.accessFlags())) == 3; + assert method.signature().argumentKindAt(0, false) == CiKind.Object; + assert method.signature().argumentKindAt(1, false) == CiKind.Object; + assert !Modifier.isStatic(method.accessFlags()) || method.signature().argumentKindAt(2, false) == CiKind.Object; + return compiler.getVMEntries().executeCompiledMethod(this, arg1, arg2, arg3); + } } diff -r f86ddbd42a7b -r 897b7d18bebc graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotRuntime.java --- a/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotRuntime.java Tue Feb 28 17:53:07 2012 +0100 +++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotRuntime.java Tue Feb 28 18:00:35 2012 +0100 @@ -35,6 +35,7 @@ import com.oracle.max.criutils.*; import com.oracle.max.graal.compiler.*; import com.oracle.max.graal.compiler.phases.*; +import com.oracle.max.graal.compiler.phases.PhasePlan.*; import com.oracle.max.graal.cri.*; import com.oracle.max.graal.graph.*; import com.oracle.max.graal.hotspot.*; @@ -448,7 +449,7 @@ runtimeCall.setStateAfter(initialFrameState.duplicateModified(0, false, CiKind.Void, runtimeCall)); @SuppressWarnings("unused") - HotSpotCompiledMethod hotSpotCompiledMethod = new HotSpotCompiledMethod(null); // initialize class... + HotSpotCompiledMethod hotSpotCompiledMethod = new HotSpotCompiledMethod(null, null); // initialize class... RiResolvedType compiledMethodClass = getType(HotSpotCompiledMethod.class); RiResolvedField nmethodField = null; for (RiResolvedField field : compiledMethodClass.declaredFields()) { @@ -483,4 +484,12 @@ CiTargetMethod result = compiler.getCompiler().compileMethod(method, graph, -1, PhasePlan.DEFAULT); return result; } + + @Override + public CiTargetMethod compile(RiResolvedMethod method, StructuredGraph graph) { + final PhasePlan plan = new PhasePlan(); + GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(compiler.getRuntime()); + plan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase); + return compiler.getCompiler().compileMethod(method, graph, -1, plan); + } } diff -r f86ddbd42a7b -r 897b7d18bebc graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/cri/GraalRuntime.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/cri/GraalRuntime.java Tue Feb 28 17:53:07 2012 +0100 +++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/cri/GraalRuntime.java Tue Feb 28 18:00:35 2012 +0100 @@ -24,6 +24,7 @@ import java.util.*; +import com.oracle.max.cri.ci.*; import com.oracle.max.cri.ri.*; import com.oracle.max.graal.graph.*; import com.oracle.max.graal.nodes.*; @@ -36,4 +37,6 @@ void lower(Node n, CiLoweringTool tool); StructuredGraph intrinsicGraph(RiResolvedMethod caller, int bci, RiResolvedMethod method, List parameters); + + CiTargetMethod compile(RiResolvedMethod method, StructuredGraph graph); } diff -r f86ddbd42a7b -r 897b7d18bebc graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/CompiledMethodTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/CompiledMethodTest.java Tue Feb 28 18:00:35 2012 +0100 @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.max.graal.compiler.tests; + +import java.lang.reflect.*; + +import org.junit.*; + +import com.oracle.max.cri.ci.*; +import com.oracle.max.cri.ri.*; +import com.oracle.max.cri.ri.RiCompiledMethod.MethodInvalidatedException; +import com.oracle.max.graal.compiler.phases.*; +import com.oracle.max.graal.graph.*; +import com.oracle.max.graal.nodes.*; + +/** + * In the following tests, the usages of local variable "a" are replaced with the integer constant 0. Then + * canonicalization is applied and it is verified that the resulting graph is equal to the graph of the method that just + * has a "return 1" statement in it. + */ +public class CompiledMethodTest extends GraphTest { + + public static Object testMethod(Object arg1, Object arg2, Object arg3) { + return arg1 + " " + arg2 + " " + arg3; + } + + @Test + public void test1() { + Method method = getMethod("testMethod"); + final StructuredGraph graph = parse(method); + new CanonicalizerPhase(null, runtime(), null).apply(graph); + new DeadCodeEliminationPhase().apply(graph); + + for (Node node : graph.getNodes()) { + if (node instanceof ConstantNode) { + ConstantNode constant = (ConstantNode) node; + if (constant.kind() == CiKind.Object && " ".equals(constant.value.asObject())) { + graph.replaceFloating(constant, ConstantNode.forObject("-", runtime, graph)); + } + } + } + + final RiResolvedMethod riMethod = runtime.getRiMethod(method); + CiTargetMethod targetMethod = runtime.compile(riMethod, graph); + RiCompiledMethod compiledMethod = runtime.addMethod(riMethod, targetMethod); + try { + Object result = compiledMethod.execute("1", "2", "3"); + Assert.assertEquals("1-2-3", result); + } catch (MethodInvalidatedException t) { + Assert.fail("method invalidated"); + } + + } +} diff -r f86ddbd42a7b -r 897b7d18bebc graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/GraphTest.java --- a/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/GraphTest.java Tue Feb 28 17:53:07 2012 +0100 +++ b/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/GraphTest.java Tue Feb 28 18:00:35 2012 +0100 @@ -76,6 +76,10 @@ * @param methodName the name of the method in {@code this.getClass()} to be parsed */ protected StructuredGraph parse(String methodName) { + return parse(getMethod(methodName)); + } + + protected Method getMethod(String methodName) { Method found = null; for (Method m : this.getClass().getMethods()) { if (m.getName().equals(methodName)) { @@ -84,7 +88,7 @@ } } if (found != null) { - return parse(found); + return found; } else { throw new RuntimeException("method not found: " + methodName); } @@ -96,18 +100,7 @@ * @param methodName the name of the method in {@code this.getClass()} to be parsed */ protected StructuredGraph parseProfiled(String methodName) { - Method found = null; - for (Method m : this.getClass().getMethods()) { - if (m.getName().equals(methodName)) { - Assert.assertNull(found); - found = m; - } - } - if (found != null) { - return parseProfiled(found); - } else { - throw new RuntimeException("method not found: " + methodName); - } + return parseProfiled(getMethod(methodName)); } /** diff -r f86ddbd42a7b -r 897b7d18bebc src/cpu/x86/vm/sharedRuntime_x86_64.cpp --- a/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Tue Feb 28 17:53:07 2012 +0100 +++ b/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Tue Feb 28 18:00:35 2012 +0100 @@ -644,6 +644,16 @@ // Pre-load the register-jump target early, to schedule it better. __ movptr(r11, Address(rbx, in_bytes(methodOopDesc::from_compiled_offset()))); +#ifdef GRAAL + // check if this call should be routed towards a specific entry point + __ cmpptr(Address(r15_thread, in_bytes(JavaThread::graal_alternate_call_target_offset())), 0); + Label no_alternative_target; + __ jcc(Assembler::equal, no_alternative_target); + __ movptr(r11, Address(r15_thread, in_bytes(JavaThread::graal_alternate_call_target_offset()))); + __ movptr(Address(r15_thread, in_bytes(JavaThread::graal_alternate_call_target_offset())), 0); + __ bind(no_alternative_target); +#endif + // Now generate the shuffle code. Pick up all register args and move the // rest through the floating point stack top. for (int i = 0; i < total_args_passed; i++) { diff -r f86ddbd42a7b -r 897b7d18bebc src/os/bsd/vm/os_bsd.cpp --- a/src/os/bsd/vm/os_bsd.cpp Tue Feb 28 17:53:07 2012 +0100 +++ b/src/os/bsd/vm/os_bsd.cpp Tue Feb 28 18:00:35 2012 +0100 @@ -4847,9 +4847,9 @@ // able to use structured exception handling (thread-local exception filters) // on, e.g., Win32. void -os::os_exception_wrapper(java_call_t f, JavaValue* value, methodHandle* method, +os::os_exception_wrapper(java_call_t f, JavaValue* value, methodHandle* method, nmethod* nm, JavaCallArguments* args, Thread* thread) { - f(value, method, args, thread); + f(value, method, nm, args, thread); } void os::print_statistics() { diff -r f86ddbd42a7b -r 897b7d18bebc src/os/linux/vm/os_linux.cpp --- a/src/os/linux/vm/os_linux.cpp Tue Feb 28 17:53:07 2012 +0100 +++ b/src/os/linux/vm/os_linux.cpp Tue Feb 28 18:00:35 2012 +0100 @@ -4486,9 +4486,9 @@ // able to use structured exception handling (thread-local exception filters) // on, e.g., Win32. void -os::os_exception_wrapper(java_call_t f, JavaValue* value, methodHandle* method, +os::os_exception_wrapper(java_call_t f, JavaValue* value, methodHandle* method, nmethod* nm, JavaCallArguments* args, Thread* thread) { - f(value, method, args, thread); + f(value, method, nm, args, thread); } void os::print_statistics() { diff -r f86ddbd42a7b -r 897b7d18bebc src/os/solaris/vm/os_solaris.cpp --- a/src/os/solaris/vm/os_solaris.cpp Tue Feb 28 17:53:07 2012 +0100 +++ b/src/os/solaris/vm/os_solaris.cpp Tue Feb 28 18:00:35 2012 +0100 @@ -4316,8 +4316,8 @@ // This does not do anything on Solaris. This is basically a hook for being // able to use structured exception handling (thread-local exception filters) on, e.g., Win32. -void os::os_exception_wrapper(java_call_t f, JavaValue* value, methodHandle* method, JavaCallArguments* args, Thread* thread) { - f(value, method, args, thread); +void os::os_exception_wrapper(java_call_t f, JavaValue* value, methodHandle* method, nmethod* nm, JavaCallArguments* args, Thread* thread) { + f(value, method, nm, args, thread); } // This routine may be used by user applications as a "hook" to catch signals. diff -r f86ddbd42a7b -r 897b7d18bebc src/os_cpu/windows_x86/vm/os_windows_x86.cpp --- a/src/os_cpu/windows_x86/vm/os_windows_x86.cpp Tue Feb 28 17:53:07 2012 +0100 +++ b/src/os_cpu/windows_x86/vm/os_windows_x86.cpp Tue Feb 28 18:00:35 2012 +0100 @@ -76,7 +76,7 @@ extern LONG WINAPI topLevelExceptionFilter(_EXCEPTION_POINTERS* ); // Install a win32 structured exception handler around thread. -void os::os_exception_wrapper(java_call_t f, JavaValue* value, methodHandle* method, JavaCallArguments* args, Thread* thread) { +void os::os_exception_wrapper(java_call_t f, JavaValue* value, methodHandle* method, nmethod* nm, JavaCallArguments* args, Thread* thread) { __try { #ifndef AMD64 @@ -116,7 +116,7 @@ #endif // ASSERT #endif // !AMD64 - f(value, method, args, thread); + f(value, method, nm, args, thread); } __except(topLevelExceptionFilter((_EXCEPTION_POINTERS*)_exception_info())) { // Nothing to do. } diff -r f86ddbd42a7b -r 897b7d18bebc src/share/vm/classfile/vmSymbols.hpp --- a/src/share/vm/classfile/vmSymbols.hpp Tue Feb 28 17:53:07 2012 +0100 +++ b/src/share/vm/classfile/vmSymbols.hpp Tue Feb 28 18:00:35 2012 +0100 @@ -351,6 +351,7 @@ template(forObject_name, "forObject") \ template(callbackInternal_name, "callbackInternal") \ template(callback_signature, "(Ljava/lang/Object;)Ljava/lang/Object;") \ + template(MethodInvalidatedException, "com/oracle/max/cri/ri/RiCompiledMethod$MethodInvalidatedException") \ \ \ /* common method and field names */ \ diff -r f86ddbd42a7b -r 897b7d18bebc src/share/vm/graal/graalCompilerToVM.cpp --- a/src/share/vm/graal/graalCompilerToVM.cpp Tue Feb 28 17:53:07 2012 +0100 +++ b/src/share/vm/graal/graalCompilerToVM.cpp Tue Feb 28 18:00:35 2012 +0100 @@ -864,6 +864,7 @@ instanceKlass::cast(HotSpotCompiledMethod::klass())->initialize(CHECK_NULL); Handle obj = instanceKlass::cast(HotSpotCompiledMethod::klass())->allocate_permanent_instance(CHECK_NULL); assert(obj() != NULL, "must succeed in allocating instance"); + HotSpotCompiledMethod::set_compiler(obj, VMToCompiler::compilerInstance()()); HotSpotCompiledMethod::set_nmethod(obj, (jlong) nm); HotSpotCompiledMethod::set_method(obj, HotSpotTargetMethod::method(targetMethod)); nm->set_graal_compiled_method(obj()); @@ -923,6 +924,32 @@ return JNIHandles::make_local(result()); } +// public Object executeCompiledMethod(HotSpotCompiledMethod method, Object arg1, Object arg2, Object arg3); +JNIEXPORT jobject JNICALL Java_com_oracle_max_graal_hotspot_bridge_CompilerToVMImpl_executeCompiledMethod(JNIEnv *env, jobject, jobject method, jobject arg1, jobject arg2, jobject arg3) { + TRACE_graal_3("CompilerToVM::executeCompiledMethod"); + + VM_ENTRY_MARK; + ResourceMark rm; + HandleMark hm; + + methodHandle actualMethod = getMethodFromHotSpotMethod(HotSpotCompiledMethod::method(method)); + assert(method != NULL, "just checking"); + JavaValue result(T_OBJECT); + JavaCallArguments args; + args.push_oop(JNIHandles::resolve(arg1)); + args.push_oop(JNIHandles::resolve(arg2)); + args.push_oop(JNIHandles::resolve(arg3)); + + nmethod* nm = (nmethod*) HotSpotCompiledMethod::nmethod(method); + if (nm == NULL || !nm->is_alive()) { + THROW_0(vmSymbols::MethodInvalidatedException()); + } + + JavaCalls::call(&result, actualMethod, nm, &args, CHECK_NULL); + + return JNIHandles::make_local((oop) result.get_jobject()); +} + #define CC (char*) /*cast a literal from (const char*)*/ #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &(Java_com_oracle_max_graal_hotspot_bridge_CompilerToVMImpl_##f)) @@ -984,6 +1011,7 @@ {CC"installStub", CC"("TARGET_METHOD")"PROXY, FN_PTR(installStub)}, {CC"disassembleNative", CC"([BJ)"STRING, FN_PTR(disassembleNative)}, {CC"disassembleJava", CC"("RESOLVED_METHOD")"STRING, FN_PTR(disassembleJava)}, + {CC"executeCompiledMethod", CC"("HS_COMP_METHOD OBJECT OBJECT OBJECT")"OBJECT, FN_PTR(executeCompiledMethod)}, }; int CompilerToVM_methods_count() { diff -r f86ddbd42a7b -r 897b7d18bebc src/share/vm/graal/graalJavaAccess.hpp --- a/src/share/vm/graal/graalJavaAccess.hpp Tue Feb 28 17:53:07 2012 +0100 +++ b/src/share/vm/graal/graalJavaAccess.hpp Tue Feb 28 18:00:35 2012 +0100 @@ -85,6 +85,7 @@ int_field(HotSpotField, accessFlags) \ end_class \ start_class(HotSpotCompiledMethod) \ + oop_field(HotSpotCompiledMethod, compiler, "Lcom/oracle/max/graal/hotspot/Compiler;") \ long_field(HotSpotCompiledMethod, nmethod) \ oop_field(HotSpotCompiledMethod, method, "Lcom/oracle/max/cri/ri/RiResolvedMethod;") \ end_class \ diff -r f86ddbd42a7b -r 897b7d18bebc src/share/vm/runtime/javaCalls.cpp --- a/src/share/vm/runtime/javaCalls.cpp Tue Feb 28 17:53:07 2012 +0100 +++ b/src/share/vm/runtime/javaCalls.cpp Tue Feb 28 18:00:35 2012 +0100 @@ -334,10 +334,19 @@ assert(THREAD->is_Java_thread(), "only JavaThreads can make JavaCalls"); // Need to wrap each and everytime, since there might be native code down the // stack that has installed its own exception handlers - os::os_exception_wrapper(call_helper, result, &method, args, THREAD); + os::os_exception_wrapper(call_helper, result, &method, NULL, args, THREAD); } -void JavaCalls::call_helper(JavaValue* result, methodHandle* m, JavaCallArguments* args, TRAPS) { +void JavaCalls::call(JavaValue* result, methodHandle method, nmethod* nm, JavaCallArguments* args, TRAPS) { + // Check if we need to wrap a potential OS exception handler around thread + // This is used for e.g. Win32 structured exception handlers + assert(THREAD->is_Java_thread(), "only JavaThreads can make JavaCalls"); + // Need to wrap each and everytime, since there might be native code down the + // stack that has installed its own exception handlers + os::os_exception_wrapper(call_helper, result, &method, nm, args, THREAD); +} + +void JavaCalls::call_helper(JavaValue* result, methodHandle* m, nmethod* nm, JavaCallArguments* args, TRAPS) { methodHandle method = *m; JavaThread* thread = (JavaThread*)THREAD; assert(thread->is_Java_thread(), "must be called by a java thread"); @@ -416,6 +425,19 @@ os::bang_stack_shadow_pages(); } + if (nm != NULL) { +#ifdef GRAAL + if (nm->is_alive()) { + ((JavaThread*) THREAD)->set_graal_alternate_call_target(nm->entry_point()); + entry_point = method->adapter()->get_i2c_entry(); + } else { + THROW(vmSymbols::MethodInvalidatedException()); + } +#else + ShouldNotReachHere(); +#endif + } + // do call { JavaCallWrapper link(method, receiver, result, CHECK); { HandleMark hm(thread); // HandleMark used by HandleMarkCleaner diff -r f86ddbd42a7b -r 897b7d18bebc src/share/vm/runtime/javaCalls.hpp --- a/src/share/vm/runtime/javaCalls.hpp Tue Feb 28 17:53:07 2012 +0100 +++ b/src/share/vm/runtime/javaCalls.hpp Tue Feb 28 18:00:35 2012 +0100 @@ -190,7 +190,7 @@ // class JavaCalls: AllStatic { - static void call_helper(JavaValue* result, methodHandle* method, JavaCallArguments* args, TRAPS); + static void call_helper(JavaValue* result, methodHandle* method, nmethod* nm, JavaCallArguments* args, TRAPS); public: // Optimized Constuctor call static void call_default_constructor(JavaThread* thread, methodHandle method, Handle receiver, TRAPS); @@ -230,6 +230,7 @@ // Low-level interface static void call(JavaValue* result, methodHandle method, JavaCallArguments* args, TRAPS); + static void call(JavaValue* result, methodHandle method, nmethod* nm, JavaCallArguments* args, TRAPS); }; #endif // SHARE_VM_RUNTIME_JAVACALLS_HPP diff -r f86ddbd42a7b -r 897b7d18bebc src/share/vm/runtime/os.hpp --- a/src/share/vm/runtime/os.hpp Tue Feb 28 17:53:07 2012 +0100 +++ b/src/share/vm/runtime/os.hpp Tue Feb 28 18:00:35 2012 +0100 @@ -79,7 +79,7 @@ }; // Typedef for structured exception handling support -typedef void (*java_call_t)(JavaValue* value, methodHandle* method, JavaCallArguments* args, Thread* thread); +typedef void (*java_call_t)(JavaValue* value, methodHandle* method, nmethod* nm, JavaCallArguments* args, Thread* thread); class os: AllStatic { public: @@ -632,7 +632,7 @@ static void init_random(long initval); // initialize random sequence // Structured OS Exception support - static void os_exception_wrapper(java_call_t f, JavaValue* value, methodHandle* method, JavaCallArguments* args, Thread* thread); + static void os_exception_wrapper(java_call_t f, JavaValue* value, methodHandle* method, nmethod* nm, JavaCallArguments* args, Thread* thread); // On Windows this will create an actual minidump, on Linux/Solaris it will simply check core dump limits static void check_or_create_dump(void* exceptionRecord, void* contextRecord, char* buffer, size_t bufferSize); diff -r f86ddbd42a7b -r 897b7d18bebc src/share/vm/runtime/thread.cpp --- a/src/share/vm/runtime/thread.cpp Tue Feb 28 17:53:07 2012 +0100 +++ b/src/share/vm/runtime/thread.cpp Tue Feb 28 18:00:35 2012 +0100 @@ -1304,6 +1304,7 @@ _doing_unsafe_access = false; _stack_guard_state = stack_guard_unused; _graal_deopt_info = NULL; + _graal_alternate_call_target = NULL; _exception_oop = NULL; _exception_pc = 0; _exception_handler_pc = 0; diff -r f86ddbd42a7b -r 897b7d18bebc src/share/vm/runtime/thread.hpp --- a/src/share/vm/runtime/thread.hpp Tue Feb 28 17:53:07 2012 +0100 +++ b/src/share/vm/runtime/thread.hpp Tue Feb 28 18:00:35 2012 +0100 @@ -870,6 +870,7 @@ jint graal_multinewarray_storage[256]; volatile oop _graal_deopt_info; + address _graal_alternate_call_target; StackGuardState _stack_guard_state; @@ -1236,6 +1237,8 @@ oop graal_deopt_info() const { return _graal_deopt_info; } void set_graal_deopt_info(oop o) { _graal_deopt_info = o; } + void set_graal_alternate_call_target(address a) { _graal_alternate_call_target = a; } + // Exception handling for compiled methods oop exception_oop() const { return _exception_oop; } address exception_pc() const { return _exception_pc; } @@ -1316,6 +1319,7 @@ static ByteSize saved_exception_pc_offset() { return byte_offset_of(JavaThread, _saved_exception_pc ); } static ByteSize osthread_offset() { return byte_offset_of(JavaThread, _osthread ); } static ByteSize graal_deopt_info_offset() { return byte_offset_of(JavaThread, _graal_deopt_info ); } + static ByteSize graal_alternate_call_target_offset() { return byte_offset_of(JavaThread, _graal_alternate_call_target); } static ByteSize exception_oop_offset() { return byte_offset_of(JavaThread, _exception_oop ); } static ByteSize exception_pc_offset() { return byte_offset_of(JavaThread, _exception_pc ); } static ByteSize exception_handler_pc_offset() { return byte_offset_of(JavaThread, _exception_handler_pc); }