Mercurial > hg > graal-jvmci-8
changeset 9027:e0e85d78843b
Merge.
author | Thomas Wuerthinger <thomas.wuerthinger@oracle.com> |
---|---|
date | Fri, 12 Apr 2013 04:51:28 +0200 |
parents | 22851e342f0e (diff) 80aee92588cd (current diff) |
children | 5450f281602b |
files | 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/HotSpotRuntime.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/BoxingSnippets.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/BoxingSubstitutions.java src/share/vm/classfile/vmSymbols.hpp src/share/vm/graal/graalCompilerToVM.cpp |
diffstat | 27 files changed, 275 insertions(+), 182 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/InstalledCode.java Thu Apr 11 15:41:48 2013 -0700 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/InstalledCode.java Fri Apr 12 04:51:28 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 Fri Apr 12 04:51:28 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 15:41:48 2013 -0700 +++ b/graal/com.oracle.graal.asm.test/src/com/oracle/graal/asm/test/AssemblerTest.java Fri Apr 12 04:51:28 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 15:41:48 2013 -0700 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/deopt/CompiledMethodTest.java Fri Apr 12 04:51:28 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 15:41:48 2013 -0700 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/deopt/SynchronizedMethodDeoptimizationTest.java Fri Apr 12 04:51:28 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 Fri Apr 12 04:51:28 2013 +0200 @@ -0,0 +1,85 @@ +/* + * 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.code.*; +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 { + + private static final int ITERATION_COUNT = 100000; + + @Test + public void testInstallCodeInvalidation() { + final ResolvedJavaMethod testJavaMethod = runtime.lookupJavaMethod(getMethod("foo")); + final StructuredGraph graph = parse("otherFoo"); + final HotSpotInstalledCode installedCode = (HotSpotInstalledCode) getCode(testJavaMethod, graph); + Assert.assertTrue(installedCode.isValid()); + Object result; + try { + result = installedCode.execute("a", "b", "c"); + assertEquals(43, result); + } catch (InvalidInstalledCodeException e) { + Assert.fail("Code was invalidated"); + } + Assert.assertTrue(installedCode.isValid()); + installedCode.invalidate(); + Assert.assertFalse(installedCode.isValid()); + try { + result = installedCode.execute(null, null, null); + Assert.fail("Code was not invalidated"); + } catch (InvalidInstalledCodeException e) { + } + Assert.assertFalse(installedCode.isValid()); + } + + @Test + public void testInstalledCodeCalledFromCompiledCode() { + final ResolvedJavaMethod testJavaMethod = runtime.lookupJavaMethod(getMethod("foo")); + final StructuredGraph graph = parse("otherFoo"); + final HotSpotInstalledCode installedCode = (HotSpotInstalledCode) getCode(testJavaMethod, graph); + Assert.assertTrue(installedCode.isValid()); + try { + for (int i = 0; i < ITERATION_COUNT; ++i) { + installedCode.execute("a", "b", "c"); + } + } catch (InvalidInstalledCodeException e) { + Assert.fail("Code was invalidated"); + } + } + + @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.test/src/com/oracle/graal/hotspot/test/InstalledCodeExecuteHelperTest.java Thu Apr 11 15:41:48 2013 -0700 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/InstalledCodeExecuteHelperTest.java Fri Apr 12 04:51:28 2013 +0200 @@ -24,6 +24,7 @@ import java.lang.reflect.*; +import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.api.runtime.*; import com.oracle.graal.compiler.test.*; @@ -36,7 +37,7 @@ // TODO this is not a test, move it somewhere else // CheckStyle: stop system..print check - public void test1() throws NoSuchMethodException, SecurityException { + public void test1() throws NoSuchMethodException, SecurityException, InvalidInstalledCodeException { final Method benchrMethod = InstalledCodeExecuteHelperTest.class.getMethod("bench", long.class, long.class); final ResolvedJavaMethod benchJavaMethod = Graal.getRequiredCapability(GraalCodeCacheProvider.class).lookupJavaMethod(benchrMethod); @@ -63,7 +64,7 @@ // CheckStyle: resume system..print check - public static Long bench(long nmethod, long metaspacemethod) { + public static Long bench(long nmethod, long metaspacemethod) throws InvalidInstalledCodeException { long start = System.currentTimeMillis(); for (int i = 0; i < ITERATIONS; i++) { @@ -78,7 +79,7 @@ return 42; } - public static Object executeWrapper(long nmethod, long metaspaceMethod, Object arg1, Object arg2, Object arg3) { + public static Object executeWrapper(long nmethod, long metaspaceMethod, Object arg1, Object arg2, Object arg3) throws InvalidInstalledCodeException { return HotSpotInstalledCode.executeHelper(nmethod, metaspaceMethod, arg1, arg2, arg3); }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java Thu Apr 11 15:41:48 2013 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java Fri Apr 12 04:51:28 2013 +0200 @@ -201,9 +201,9 @@ StackTraceElement getStackTraceElement(long metaspaceMethod, int bci); - Object executeCompiledMethod(long metaspaceMethod, long nmethod, Object arg1, Object arg2, Object arg3); + Object executeCompiledMethod(Object arg1, Object arg2, Object arg3, long nativeMethod) throws InvalidInstalledCodeException; - Object executeCompiledMethodVarargs(long metaspaceMethod, long nmethod, Object... args); + Object executeCompiledMethodVarargs(Object[] args, long nativeMethod) throws InvalidInstalledCodeException; int getVtableEntryOffset(long metaspaceMethod); @@ -223,4 +223,10 @@ * @param metaspaceMethod the metaspace Method object */ 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 15:41:48 2013 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java Fri Apr 12 04:51:28 2013 +0200 @@ -133,10 +133,7 @@ public native StackTraceElement getStackTraceElement(long metaspaceMethod, int bci); @Override - public native Object executeCompiledMethod(long metaspaceMethod, long nmethod, Object arg1, Object arg2, Object arg3); - - @Override - public native Object executeCompiledMethodVarargs(long metaspaceMethod, long nmethod, Object... args); + public native Object executeCompiledMethodVarargs(Object[] args, long nativeMethod); @Override public native int getVtableEntryOffset(long metaspaceMethod); @@ -161,4 +158,17 @@ @Override public native Object lookupAppendixInPool(HotSpotResolvedObjectType pool, int cpi, byte opcode); + + @Override + public native void invalidateInstalledCode(long nativeMethod); + + @Override + public native boolean isInstalledCodeValid(long nativeMethod); + + @Override + public Object executeCompiledMethod(Object arg1, Object arg2, Object arg3, long nativeMethod) throws InvalidInstalledCodeException { + return executeCompiledMethodIntrinsic(arg1, arg2, arg3, nativeMethod); + } + + private static native Object executeCompiledMethodIntrinsic(Object arg1, Object arg2, Object arg3, long nativeMethod); }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotInstalledCode.java Thu Apr 11 15:41:48 2013 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotInstalledCode.java Fri Apr 12 04:51:28 2013 +0200 @@ -39,10 +39,11 @@ private final HotSpotResolvedJavaMethod method; private final boolean isDefault; - long nmethod; + private final long nmethod; // This field is set by the runtime upon code installation. long start; public HotSpotInstalledCode(HotSpotResolvedJavaMethod method, boolean isDefault) { + this.nmethod = 0; this.method = method; this.isDefault = isDefault; } @@ -62,7 +63,12 @@ @Override public boolean isValid() { - return nmethod != 0; + return HotSpotGraalRuntime.getInstance().getCompilerToVM().isInstalledCodeValid(nmethod); + } + + @Override + public void invalidate() { + HotSpotGraalRuntime.getInstance().getCompilerToVM().invalidateInstalledCode(nmethod); } @Override @@ -71,12 +77,12 @@ } @Override - public Object execute(Object arg1, Object arg2, Object arg3) { + public Object execute(Object arg1, Object arg2, Object arg3) throws InvalidInstalledCodeException { assert method.getSignature().getParameterCount(!Modifier.isStatic(method.getModifiers())) == 3; assert method.getSignature().getParameterKind(0) == Kind.Object; assert method.getSignature().getParameterKind(1) == Kind.Object; assert !Modifier.isStatic(method.getModifiers()) || method.getSignature().getParameterKind(2) == Kind.Object; - return HotSpotGraalRuntime.getInstance().getCompilerToVM().executeCompiledMethod(method.metaspaceMethod, nmethod, arg1, arg2, arg3); + return HotSpotGraalRuntime.getInstance().getCompilerToVM().executeCompiledMethod(arg1, arg2, arg3, nmethod); } private boolean checkArgs(Object... args) { @@ -94,9 +100,9 @@ } @Override - public Object executeVarargs(Object... args) { + public Object executeVarargs(Object... args) throws InvalidInstalledCodeException { assert checkArgs(args); - return HotSpotGraalRuntime.getInstance().getCompilerToVM().executeCompiledMethodVarargs(method.metaspaceMethod, nmethod, args); + return HotSpotGraalRuntime.getInstance().getCompilerToVM().executeCompiledMethodVarargs(args, nmethod); } @Override @@ -109,7 +115,8 @@ return HotSpotGraalRuntime.getInstance().getCompilerToVM().getCode(nmethod); } - public static Object executeHelper(long nmethod, long metaspaceMethod, Object arg1, Object arg2, Object arg3) { - return HotSpotGraalRuntime.getInstance().getCompilerToVM().executeCompiledMethod(metaspaceMethod, nmethod, arg1, arg2, arg3); + @SuppressWarnings("unused") + public static Object executeHelper(long nmethod, long metaspaceMethod, Object arg1, Object arg2, Object arg3) throws InvalidInstalledCodeException { + return HotSpotGraalRuntime.getInstance().getCompilerToVM().executeCompiledMethod(arg1, arg2, arg3, nmethod); } }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Thu Apr 11 15:41:48 2013 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Fri Apr 12 04:51:28 2013 +0200 @@ -894,7 +894,7 @@ public String disassemble(InstalledCode code) { if (code.isValid()) { - long nmethod = ((HotSpotInstalledCode) code).nmethod; + long nmethod = ((HotSpotInstalledCode) code).getnmethod(); return graalRuntime.getCompilerToVM().disassembleNMethod(nmethod); } return null;
--- a/src/cpu/sparc/vm/interpreter_sparc.cpp Thu Apr 11 15:41:48 2013 -0700 +++ b/src/cpu/sparc/vm/interpreter_sparc.cpp Fri Apr 12 04:51:28 2013 +0200 @@ -381,6 +381,7 @@ case Interpreter::zerolocals_synchronized: synchronized = true; break; case Interpreter::native : entry_point = ((InterpreterGenerator*)this)->generate_native_entry(false); break; case Interpreter::native_synchronized : entry_point = ((InterpreterGenerator*)this)->generate_native_entry(true); break; + case Interpreter::execute_compiled_method: entry_point = ((InterpreterGenerator*)this)->generate_execute_compiled_method_entry(); break; case Interpreter::empty : entry_point = ((InterpreterGenerator*)this)->generate_empty_entry(); break; case Interpreter::accessor : entry_point = ((InterpreterGenerator*)this)->generate_accessor_entry(); break; case Interpreter::abstract : entry_point = ((InterpreterGenerator*)this)->generate_abstract_entry(); break;
--- a/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Thu Apr 11 15:41:48 2013 -0700 +++ b/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Fri Apr 12 04:51:28 2013 +0200 @@ -1917,6 +1917,7 @@ BasicType* in_sig_bt, VMRegPair* in_regs, BasicType ret_type) { + assert (method->intrinsic_id() != vmIntrinsics::_CompilerToVMImpl_executeCompiledMethod, "not yet ported"); if (method->is_method_handle_intrinsic()) { vmIntrinsics::ID iid = method->intrinsic_id(); intptr_t start = (intptr_t)__ pc();
--- a/src/cpu/x86/vm/interpreterGenerator_x86.hpp Thu Apr 11 15:41:48 2013 -0700 +++ b/src/cpu/x86/vm/interpreterGenerator_x86.hpp Fri Apr 12 04:51:28 2013 +0200 @@ -36,6 +36,7 @@ address generate_normal_entry(bool synchronized); address generate_native_entry(bool synchronized); + address generate_execute_compiled_method_entry(); address generate_abstract_entry(void); address generate_math_entry(AbstractInterpreter::MethodKind kind); address generate_empty_entry(void);
--- a/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Thu Apr 11 15:41:48 2013 -0700 +++ b/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Fri Apr 12 04:51:28 2013 +0200 @@ -1670,6 +1670,11 @@ verify_oop_args(masm, method, sig_bt, regs); vmIntrinsics::ID iid = method->intrinsic_id(); + if (iid == vmIntrinsics::_CompilerToVMImpl_executeCompiledMethod) { + __ jmp(Address(j_rarg3, nmethod::verified_entry_point_offset())); + return; + } + // Now write the args into the outgoing interpreter space bool has_receiver = false; Register receiver_reg = noreg;
--- a/src/cpu/x86/vm/templateInterpreter_x86_64.cpp Thu Apr 11 15:41:48 2013 -0700 +++ b/src/cpu/x86/vm/templateInterpreter_x86_64.cpp Fri Apr 12 04:51:28 2013 +0200 @@ -873,6 +873,31 @@ return generate_accessor_entry(); } +// Interpreter stub for calling a compiled method with 3 object arguments +address InterpreterGenerator::generate_execute_compiled_method_entry() { + address entry_point = __ pc(); + + // Pick up the return address + __ movptr(rax, Address(rsp, 0)); + + // Must preserve original SP for loading incoming arguments because + // we need to align the outgoing SP for compiled code. + __ movptr(r11, rsp); + + // Ensure compiled code always sees stack at proper alignment + __ andptr(rsp, -16); + + // push the return address and misalign the stack that youngest frame always sees + // as far as the placement of the call instruction + __ push(rax); + + __ movq(j_rarg0, Address(r11, Interpreter::stackElementSize*5)); + __ movq(j_rarg1, Address(r11, Interpreter::stackElementSize*4)); + __ movq(j_rarg2, Address(r11, Interpreter::stackElementSize*3)); + __ movq(j_rarg3, Address(r11, Interpreter::stackElementSize)); + __ jmp(Address(j_rarg3, nmethod::verified_entry_point_offset())); + return entry_point; +} // Interpreter stub for calling a native method. (asm interpreter) // This sets up a somewhat different looking stack for calling the @@ -1561,6 +1586,7 @@ switch (kind) { case Interpreter::zerolocals : break; case Interpreter::zerolocals_synchronized: synchronized = true; break; + case Interpreter::execute_compiled_method: entry_point = ((InterpreterGenerator*)this)->generate_execute_compiled_method_entry(); break; case Interpreter::native : entry_point = ((InterpreterGenerator*)this)->generate_native_entry(false); break; case Interpreter::native_synchronized : entry_point = ((InterpreterGenerator*)this)->generate_native_entry(true); break; case Interpreter::empty : entry_point = ((InterpreterGenerator*)this)->generate_empty_entry(); break;
--- a/src/share/vm/classfile/vmSymbols.hpp Thu Apr 11 15:41:48 2013 -0700 +++ b/src/share/vm/classfile/vmSymbols.hpp Fri Apr 12 04:51:28 2013 +0200 @@ -299,6 +299,7 @@ template(com_oracle_graal_hotspot_HotSpotCompilationResult, "com/oracle/graal/hotspot/HotSpotCompilationResult") \ template(com_oracle_graal_hotspot_HotSpotRuntimeCallTarget, "com/oracle/graal/hotspot/HotSpotRuntimeCallTarget") \ template(com_oracle_graal_hotspot_bridge_VMToCompiler, "com/oracle/graal/hotspot/bridge/VMToCompiler") \ + template(com_oracle_graal_hotspot_bridge_CompilerToVMImpl, "com/oracle/graal/hotspot/bridge/CompilerToVMImpl") \ template(com_oracle_graal_hotspot_meta_HotSpotCodeInfo, "com/oracle/graal/hotspot/meta/HotSpotCodeInfo") \ template(com_oracle_graal_hotspot_meta_HotSpotInstalledCode, "com/oracle/graal/hotspot/meta/HotSpotInstalledCode") \ template(com_oracle_graal_hotspot_meta_HotSpotJavaType, "com/oracle/graal/hotspot/meta/HotSpotJavaType") \ @@ -340,6 +341,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") \ @@ -380,7 +382,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") \ @@ -1129,6 +1130,9 @@ do_intrinsic(_Double_valueOf, java_lang_Double, valueOf_name, Double_valueOf_signature, F_S) \ do_name( Double_valueOf_signature, "(D)Ljava/lang/Double;") \ \ + do_intrinsic(_CompilerToVMImpl_executeCompiledMethod, com_oracle_graal_hotspot_bridge_CompilerToVMImpl, executeCompiledMethod_name, CompilerToVMImpl_executeCompiledMethod_signature, F_SN)\ + do_name( CompilerToVMImpl_executeCompiledMethod_signature, "(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;J)Ljava/lang/Object;") \ + do_name( executeCompiledMethod_name, "executeCompiledMethodIntrinsic") \ /*end*/
--- a/src/share/vm/code/nmethod.cpp Thu Apr 11 15:41:48 2013 -0700 +++ b/src/share/vm/code/nmethod.cpp Fri Apr 12 04:51:28 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/compiler/compileBroker.cpp Thu Apr 11 15:41:48 2013 -0700 +++ b/src/share/vm/compiler/compileBroker.cpp Fri Apr 12 04:51:28 2013 +0200 @@ -1225,7 +1225,7 @@ assert(method->method_holder()->oop_is_instance(), "not an instance method"); assert(osr_bci == InvocationEntryBci || (0 <= osr_bci && osr_bci < method->code_size()), "bci out of range"); assert(!method->is_abstract() && (osr_bci == InvocationEntryBci || !method->is_native()), "cannot compile abstract/native methods"); - assert(!method->method_holder()->is_not_initialized(), "method holder must be initialized"); + assert(!method->method_holder()->is_not_initialized() || method->intrinsic_id() == vmIntrinsics::_CompilerToVMImpl_executeCompiledMethod, "method holder must be initialized"); if (!TieredCompilation) { comp_level = CompLevel_highest_tier;
--- a/src/share/vm/graal/graalCompilerToVM.cpp Thu Apr 11 15:41:48 2013 -0700 +++ b/src/share/vm/graal/graalCompilerToVM.cpp Fri Apr 12 04:51:28 2013 +0200 @@ -907,23 +907,17 @@ return JNIHandles::make_local(element); C2V_END -C2V_VMENTRY(jobject, executeCompiledMethodVarargs, (JNIEnv *env, jobject, jlong metaspace_method, jlong metaspace_nmethod, jobject args)) +C2V_VMENTRY(jobject, executeCompiledMethodVarargs, (JNIEnv *env, jobject, jobject args, jlong nativeMethod)) ResourceMark rm; HandleMark hm; - assert(metaspace_method != 0, "just checking"); - methodHandle mh = asMethod(metaspace_method); + nmethod* nm = (nmethod*) (address) nativeMethod; + methodHandle mh = nm->method(); Symbol* signature = mh->signature(); JavaCallArguments jca(mh->size_of_parameters()); JavaArgumentUnboxer jap(signature, &jca, (arrayOop) JNIHandles::resolve(args), mh->is_static()); 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); @@ -937,29 +931,6 @@ } C2V_END -C2V_VMENTRY(jobject, executeCompiledMethod, (JNIEnv *env, jobject, jlong metaspace_method, jlong metaspace_nmethod, jobject arg1, jobject arg2, jobject arg3)) - ResourceMark rm; - HandleMark hm; - - methodHandle method = asMethod(metaspace_method); - assert(!method.is_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*) (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); - - return JNIHandles::make_local((oop) result.get_jobject()); -C2V_END - C2V_VMENTRY(jint, getVtableEntryOffset, (JNIEnv *, jobject, jlong metaspace_method)) Method* method = asMethod(metaspace_method); @@ -1078,6 +1049,20 @@ C2V_END +C2V_VMENTRY(void, invalidateInstalledCode, (JNIEnv *env, jobject, jlong nativeMethod)) + nmethod* m = (nmethod*)nativeMethod; + if (!m->is_not_entrant()) { + 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() && !m->is_not_entrant(); +C2V_END #define CC (char*) /*cast a literal from (const char*)*/ #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &(c2v_ ## f)) @@ -1147,14 +1132,15 @@ {CC"installCode0", CC"("HS_COMP_RESULT HS_INSTALLED_CODE"[Z)I", FN_PTR(installCode0)}, {CC"getCode", CC"(J)[B", FN_PTR(getCode)}, {CC"disassembleNMethod", CC"(J)"STRING, FN_PTR(disassembleNMethod)}, - {CC"executeCompiledMethod", CC"("METASPACE_METHOD NMETHOD OBJECT OBJECT OBJECT")"OBJECT, FN_PTR(executeCompiledMethod)}, - {CC"executeCompiledMethodVarargs", CC"("METASPACE_METHOD NMETHOD "["OBJECT")"OBJECT, FN_PTR(executeCompiledMethodVarargs)}, + {CC"executeCompiledMethodVarargs", CC"(["OBJECT NMETHOD")"OBJECT, FN_PTR(executeCompiledMethodVarargs)}, {CC"getDeoptedLeafGraphIds", CC"()[J", FN_PTR(getDeoptedLeafGraphIds)}, {CC"getLineNumberTable", CC"("HS_RESOLVED_METHOD")[J", FN_PTR(getLineNumberTable)}, {CC"getLocalVariableTable", CC"("HS_RESOLVED_METHOD")["LOCAL, FN_PTR(getLocalVariableTable)}, {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/interpreter/abstractInterpreter.hpp Thu Apr 11 15:41:48 2013 -0700 +++ b/src/share/vm/interpreter/abstractInterpreter.hpp Fri Apr 12 04:51:28 2013 +0200 @@ -85,6 +85,7 @@ zerolocals_synchronized, // method needs locals initialization & is synchronized native, // native method native_synchronized, // native method & is synchronized + execute_compiled_method, // direct call to compiled method address empty, // empty method (code: _return) accessor, // accessor method (code: _aload_0, _getfield, _(a|i)return) abstract, // abstract method (throws an AbstractMethodException)
--- a/src/share/vm/interpreter/interpreter.cpp Thu Apr 11 15:41:48 2013 -0700 +++ b/src/share/vm/interpreter/interpreter.cpp Fri Apr 12 04:51:28 2013 +0200 @@ -188,6 +188,9 @@ // Method handle primitive? if (m->is_method_handle_intrinsic()) { vmIntrinsics::ID id = m->intrinsic_id(); + if (id == vmIntrinsics::_CompilerToVMImpl_executeCompiledMethod) { + return AbstractInterpreter::execute_compiled_method; + } assert(MethodHandles::is_signature_polymorphic(id), "must match an intrinsic"); MethodKind kind = (MethodKind)( method_handle_invoke_FIRST + ((int)id - vmIntrinsics::FIRST_MH_SIG_POLY) ); @@ -287,6 +290,7 @@ case zerolocals_synchronized: tty->print("zerolocals_synchronized"); break; case native : tty->print("native" ); break; case native_synchronized : tty->print("native_synchronized" ); break; + case execute_compiled_method: tty->print("execute_compiled_method"); break; case empty : tty->print("empty" ); break; case accessor : tty->print("accessor" ); break; case abstract : tty->print("abstract" ); break;
--- a/src/share/vm/interpreter/templateInterpreter.cpp Thu Apr 11 15:41:48 2013 -0700 +++ b/src/share/vm/interpreter/templateInterpreter.cpp Fri Apr 12 04:51:28 2013 +0200 @@ -360,6 +360,7 @@ method_entry(zerolocals) method_entry(zerolocals_synchronized) method_entry(empty) + method_entry(execute_compiled_method) method_entry(accessor) method_entry(abstract) method_entry(java_lang_math_sin )
--- a/src/share/vm/oops/method.cpp Thu Apr 11 15:41:48 2013 -0700 +++ b/src/share/vm/oops/method.cpp Fri Apr 12 04:51:28 2013 +0200 @@ -722,7 +722,7 @@ if (number_of_breakpoints() > 0) return true; if (is_method_handle_intrinsic()) - return !is_synthetic(); // the generated adapters must be compiled + return !is_synthetic() && intrinsic_id() != vmIntrinsics::_CompilerToVMImpl_executeCompiledMethod; // the generated adapters must be compiled if (comp_level == CompLevel_any) return is_not_c1_compilable() || is_not_c2_compilable(); if (is_c1_compile(comp_level)) @@ -850,7 +850,10 @@ (void) make_adapters(h_method, CHECK); // ONLY USE the h_method now as make_adapter may have blocked - + if (h_method->intrinsic_id() == vmIntrinsics::_CompilerToVMImpl_executeCompiledMethod) { + CompileBroker::compile_method(h_method, InvocationEntryBci, CompLevel_highest_tier, + methodHandle(), CompileThreshold, "executeCompiledMethod", CHECK); + } } address Method::make_adapters(methodHandle mh, TRAPS) { @@ -1014,8 +1017,8 @@ // Test if this method is an internal MH primitive method. bool Method::is_method_handle_intrinsic() const { vmIntrinsics::ID iid = intrinsic_id(); - return (MethodHandles::is_signature_polymorphic(iid) && - MethodHandles::is_signature_polymorphic_intrinsic(iid)); + return ((MethodHandles::is_signature_polymorphic(iid) && + MethodHandles::is_signature_polymorphic_intrinsic(iid))) || iid == vmIntrinsics::_CompilerToVMImpl_executeCompiledMethod; } bool Method::has_member_arg() const {
--- a/src/share/vm/runtime/javaCalls.cpp Thu Apr 11 15:41:48 2013 -0700 +++ b/src/share/vm/runtime/javaCalls.cpp Fri Apr 12 04:51:28 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 15:41:48 2013 -0700 +++ b/src/share/vm/runtime/sharedRuntime.cpp Fri Apr 12 04:51:28 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,12 @@ 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; + ThreadInVMfromJava tiv(THREAD); + THROW_(vmSymbols::com_oracle_graal_api_code_InvalidInstalledCodeException(), 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 15:41:48 2013 -0700 +++ b/src/share/vm/runtime/sharedRuntime.hpp Fri Apr 12 04:51:28 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