# HG changeset patch # User Lukas Stadler # Date 1368091928 -7200 # Node ID bce1c7759d9da610b437d8a81b9fe69ca323b114 # Parent 87eafaddf9d9db1a7929535cfad836ac04ba73d7# Parent ac96c2062de4ba08522e8366b471b83b4bd90717 Merge diff -r 87eafaddf9d9 -r bce1c7759d9d graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeUtil.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeUtil.java Wed May 08 18:05:57 2013 +0200 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeUtil.java Thu May 09 11:32:08 2013 +0200 @@ -326,9 +326,17 @@ public static CallingConvention getCallingConvention(CodeCacheProvider codeCache, CallingConvention.Type type, ResolvedJavaMethod method, boolean stackOnly) { Signature sig = method.getSignature(); JavaType retType = sig.getReturnType(null); - JavaType[] argTypes = new JavaType[sig.getParameterCount(!Modifier.isStatic(method.getModifiers()))]; - for (int i = 0; i < argTypes.length; i++) { - argTypes[i] = sig.getParameterType(i, null); + int sigCount = sig.getParameterCount(false); + JavaType[] argTypes; + int argIndex = 0; + if (!Modifier.isStatic(method.getModifiers())) { + argTypes = new JavaType[sigCount + 1]; + argTypes[argIndex++] = method.getDeclaringClass(); + } else { + argTypes = new JavaType[sigCount]; + } + for (int i = 0; i < sigCount; i++) { + argTypes[argIndex++] = sig.getParameterType(i, null); } RegisterConfig registerConfig = codeCache.lookupRegisterConfig(); diff -r 87eafaddf9d9 -r bce1c7759d9d graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaMethod.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaMethod.java Wed May 08 18:05:57 2013 +0200 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaMethod.java Thu May 09 11:32:08 2013 +0200 @@ -208,4 +208,11 @@ * @return a constant representing a reference to this method */ Constant getEncoding(); + + /** + * Checks if this method is present in the virtual table. + * + * @return true is this method is present in the virtual table + */ + boolean isInVirtualMethodTable(); } diff -r 87eafaddf9d9 -r bce1c7759d9d graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java --- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Wed May 08 18:05:57 2013 +0200 +++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Thu May 09 11:32:08 2013 +0200 @@ -92,8 +92,8 @@ } } - public AMD64LIRGenerator(StructuredGraph graph, CodeCacheProvider runtime, TargetDescription target, FrameMap frameMap, ResolvedJavaMethod method, LIR lir) { - super(graph, runtime, target, frameMap, method, lir); + public AMD64LIRGenerator(StructuredGraph graph, CodeCacheProvider runtime, TargetDescription target, FrameMap frameMap, CallingConvention cc, LIR lir) { + super(graph, runtime, target, frameMap, cc, lir); lir.spillMoveFactory = new AMD64SpillMoveFactory(); } @@ -919,8 +919,7 @@ sig[i] = node.arguments.get(i).stamp().javaType(runtime); } - CallingConvention cc = frameMap.registerConfig.getCallingConvention(CallingConvention.Type.JavaCall, null, sig, target(), false); - Value[] parameters = visitInvokeArguments(cc, node.arguments); + Value[] parameters = visitInvokeArguments(frameMap.registerConfig.getCallingConvention(CallingConvention.Type.JavaCall, null, sig, target(), false), node.arguments); append(new AMD64BreakpointOp(parameters)); } diff -r 87eafaddf9d9 -r bce1c7759d9d graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/PTXTestBase.java --- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/PTXTestBase.java Wed May 08 18:05:57 2013 +0200 +++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/PTXTestBase.java Thu May 09 11:32:08 2013 +0200 @@ -22,11 +22,11 @@ */ package com.oracle.graal.compiler.ptx.test; +import static com.oracle.graal.api.code.CodeUtil.*; import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; -import com.oracle.graal.api.code.CompilationResult; -import com.oracle.graal.api.code.SpeculationLog; -import com.oracle.graal.api.code.TargetDescription; +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.code.CallingConvention.*; import com.oracle.graal.api.runtime.Graal; import com.oracle.graal.compiler.GraalCompiler; import com.oracle.graal.compiler.ptx.PTXBackend; @@ -56,9 +56,9 @@ phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase); phasePlan.addPhase(PhasePosition.AFTER_PARSING, new PTXPhase()); new PTXPhase().apply(graph); - CompilationResult result = GraalCompiler.compileMethod(runtime, graalRuntime().getReplacements(), - ptxBackend, target, graph.method(), graph, null, phasePlan, - OptimisticOptimizations.NONE, new SpeculationLog()); + CallingConvention cc = getCallingConvention(runtime, Type.JavaCallee, graph.method(), false); + CompilationResult result = GraalCompiler.compileGraph(graph, cc, graph.method(), runtime, graalRuntime().getReplacements(), ptxBackend, target, null, phasePlan, OptimisticOptimizations.NONE, + new SpeculationLog()); return result; } @@ -71,7 +71,8 @@ try { // not quite yet - need multi-architecture Method changes from JDK-8013168 // Object[] executeArgs = argsWithReceiver(this, args); - // InstalledCode installedCode = runtime.addMethod(getStructuredGraph().method(), result); + // InstalledCode installedCode = + // runtime.addMethod(getStructuredGraph().method(), result); // installedCode.executeVarargs(executeArgs); } catch (Throwable th) { th.printStackTrace(); diff -r 87eafaddf9d9 -r bce1c7759d9d graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXBackend.java --- a/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXBackend.java Wed May 08 18:05:57 2013 +0200 +++ b/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXBackend.java Thu May 09 11:32:08 2013 +0200 @@ -42,8 +42,8 @@ } @Override - public LIRGenerator newLIRGenerator(StructuredGraph graph, FrameMap frameMap, ResolvedJavaMethod method, LIR lir) { - return new PTXLIRGenerator(graph, runtime(), target, frameMap, method, lir); + public LIRGenerator newLIRGenerator(StructuredGraph graph, FrameMap frameMap, CallingConvention cc, LIR lir) { + return new PTXLIRGenerator(graph, runtime(), target, frameMap, cc, lir); } class HotSpotFrameContext implements FrameContext { @@ -79,16 +79,17 @@ } @Override - public void emitCode(TargetMethodAssembler tasm, ResolvedJavaMethod method, LIRGenerator lirGen) { + public void emitCode(TargetMethodAssembler tasm, LIRGenerator lirGen, ResolvedJavaMethod codeCacheOwner) { // Emit the prologue - final String name = method.getName(); + assert codeCacheOwner != null : lirGen.getGraph() + " is not associated with a method"; + final String name = codeCacheOwner.getName(); Buffer codeBuffer = tasm.asm.codeBuffer; codeBuffer.emitString(".version 1.4"); codeBuffer.emitString(".target sm_10"); codeBuffer.emitString0(".entry " + name + " ("); codeBuffer.emitString(""); - Signature signature = method.getSignature(); + Signature signature = codeCacheOwner.getSignature(); for (int i = 0; i < signature.getParameterCount(false); i++) { String param = ".param .u32 param" + i; codeBuffer.emitString(param); diff -r 87eafaddf9d9 -r bce1c7759d9d graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java --- a/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java Wed May 08 18:05:57 2013 +0200 +++ b/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java Thu May 09 11:32:08 2013 +0200 @@ -28,11 +28,7 @@ import static com.oracle.graal.lir.ptx.PTXBitManipulationOp.IntrinsicOpcode.*; import static com.oracle.graal.lir.ptx.PTXCompare.*; -import com.oracle.graal.api.code.CodeCacheProvider; -import com.oracle.graal.api.code.DeoptimizationAction; -import com.oracle.graal.api.code.RuntimeCallTarget; -import com.oracle.graal.api.code.StackSlot; -import com.oracle.graal.api.code.TargetDescription; +import com.oracle.graal.api.code.*; import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.NumUtil; @@ -85,8 +81,8 @@ } } - public PTXLIRGenerator(StructuredGraph graph, CodeCacheProvider runtime, TargetDescription target, FrameMap frameMap, ResolvedJavaMethod method, LIR lir) { - super(graph, runtime, target, frameMap, method, lir); + public PTXLIRGenerator(StructuredGraph graph, CodeCacheProvider runtime, TargetDescription target, FrameMap frameMap, CallingConvention cc, LIR lir) { + super(graph, runtime, target, frameMap, cc, lir); lir.spillMoveFactory = new PTXSpillMoveFactory(); } diff -r 87eafaddf9d9 -r bce1c7759d9d graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXTargetMethodAssembler.java --- a/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXTargetMethodAssembler.java Wed May 08 18:05:57 2013 +0200 +++ b/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXTargetMethodAssembler.java Thu May 09 11:32:08 2013 +0200 @@ -22,16 +22,14 @@ */ package com.oracle.graal.compiler.ptx; -import com.oracle.graal.api.code.CodeCacheProvider; -import com.oracle.graal.api.code.CompilationResult; -import com.oracle.graal.api.code.TargetDescription; -import com.oracle.graal.asm.AbstractAssembler; -import com.oracle.graal.hotspot.HotSpotGraalRuntime; -import com.oracle.graal.hotspot.bridge.CompilerToGPU; -import com.oracle.graal.hotspot.meta.HotSpotMethod; -import com.oracle.graal.lir.FrameMap; -import com.oracle.graal.lir.asm.FrameContext; -import com.oracle.graal.lir.asm.TargetMethodAssembler; +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.*; +import com.oracle.graal.hotspot.*; +import com.oracle.graal.hotspot.bridge.*; +import com.oracle.graal.lir.*; +import com.oracle.graal.lir.asm.*; +import com.oracle.graal.nodes.*; public class PTXTargetMethodAssembler extends TargetMethodAssembler { @@ -40,20 +38,18 @@ // detach ?? - public PTXTargetMethodAssembler(TargetDescription target, - CodeCacheProvider runtime, FrameMap frameMap, - AbstractAssembler asm, FrameContext frameContext, - CompilationResult compilationResult) { + public PTXTargetMethodAssembler(TargetDescription target, CodeCacheProvider runtime, FrameMap frameMap, AbstractAssembler asm, FrameContext frameContext, CompilationResult compilationResult) { super(target, runtime, frameMap, asm, frameContext, compilationResult); } @Override - public CompilationResult finishTargetMethod(Object name, boolean isStub) { - CompilationResult graalCompile = super.finishTargetMethod(name, isStub); + public CompilationResult finishTargetMethod(StructuredGraph graph) { + ResolvedJavaMethod method = graph.method(); + assert method != null : graph + " is not associated wth a method"; + CompilationResult graalCompile = super.finishTargetMethod(graph); try { if (validDevice) { - HotSpotMethod method = (HotSpotMethod) name; toGPU.generateKernel(graalCompile.getTargetCode(), method.getName()); } } catch (Throwable th) { diff -r 87eafaddf9d9 -r bce1c7759d9d graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java --- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Wed May 08 18:05:57 2013 +0200 +++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Thu May 09 11:32:08 2013 +0200 @@ -38,8 +38,8 @@ */ public class SPARCLIRGenerator extends LIRGenerator { - public SPARCLIRGenerator(StructuredGraph graph, CodeCacheProvider runtime, TargetDescription target, FrameMap frameMap, ResolvedJavaMethod method, LIR lir) { - super(graph, runtime, target, frameMap, method, lir); + public SPARCLIRGenerator(StructuredGraph graph, CodeCacheProvider runtime, TargetDescription target, FrameMap frameMap, CallingConvention cc, LIR lir) { + super(graph, runtime, target, frameMap, cc, lir); // SPARC: Implement lir generator. } diff -r 87eafaddf9d9 -r bce1c7759d9d graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Wed May 08 18:05:57 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Thu May 09 11:32:08 2013 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.compiler.test; +import static com.oracle.graal.api.code.CodeUtil.*; + import java.lang.reflect.*; import java.util.*; import java.util.concurrent.*; @@ -29,6 +31,7 @@ import org.junit.*; import com.oracle.graal.api.code.*; +import com.oracle.graal.api.code.CallingConvention.Type; import com.oracle.graal.api.meta.*; import com.oracle.graal.api.runtime.*; import com.oracle.graal.compiler.*; @@ -410,7 +413,8 @@ phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase); phasePlan.addPhase(PhasePosition.LOW_LEVEL, new WriteBarrierAdditionPhase()); editPhasePlan(method, graph, phasePlan); - CompilationResult compResult = GraalCompiler.compileMethod(runtime(), replacements, backend, runtime().getTarget(), method, graph, null, phasePlan, OptimisticOptimizations.ALL, + CallingConvention cc = getCallingConvention(runtime, Type.JavaCallee, graph.method(), false); + CompilationResult compResult = GraalCompiler.compileGraph(graph, cc, method, runtime, replacements, backend, runtime().getTarget(), null, phasePlan, OptimisticOptimizations.ALL, new SpeculationLog()); if (printCompilation) { TTY.println(String.format("@%-6d Graal %-70s %-45s %-50s | %4dms %5dB", id, "", "", "", System.currentTimeMillis() - start, compResult.getTargetCodeSize())); diff -r 87eafaddf9d9 -r bce1c7759d9d graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InfopointReasonTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InfopointReasonTest.java Wed May 08 18:05:57 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InfopointReasonTest.java Thu May 09 11:32:08 2013 +0200 @@ -22,6 +22,7 @@ */ package com.oracle.graal.compiler.test; +import static com.oracle.graal.api.code.CodeUtil.*; import static org.junit.Assert.*; import java.lang.reflect.*; @@ -29,6 +30,7 @@ import org.junit.*; import com.oracle.graal.api.code.*; +import com.oracle.graal.api.code.CallingConvention.Type; import com.oracle.graal.api.code.CompilationResult.Call; import com.oracle.graal.api.code.CompilationResult.Infopoint; import com.oracle.graal.compiler.*; @@ -56,7 +58,8 @@ public void callInfopoints() { final Method method = getMethod("testMethod"); final StructuredGraph graph = parse(method); - final CompilationResult cr = GraalCompiler.compileMethod(runtime, replacements, backend, runtime.getTarget(), runtime.lookupJavaMethod(method), graph, null, getDefaultPhasePlan(), + CallingConvention cc = getCallingConvention(runtime, Type.JavaCallee, graph.method(), false); + final CompilationResult cr = GraalCompiler.compileGraph(graph, cc, graph.method(), runtime, replacements, backend, runtime.getTarget(), null, getDefaultPhasePlan(), OptimisticOptimizations.ALL, new SpeculationLog()); for (Infopoint sp : cr.getInfopoints()) { assertNotNull(sp.reason); @@ -77,7 +80,8 @@ } } assertTrue(graphLineSPs > 0); - final CompilationResult cr = GraalCompiler.compileMethod(runtime, replacements, backend, runtime.getTarget(), runtime.lookupJavaMethod(method), graph, null, getDefaultPhasePlan(true), + CallingConvention cc = getCallingConvention(runtime, Type.JavaCallee, graph.method(), false); + final CompilationResult cr = GraalCompiler.compileGraph(graph, cc, graph.method(), runtime, replacements, backend, runtime.getTarget(), null, getDefaultPhasePlan(true), OptimisticOptimizations.ALL, new SpeculationLog()); int lineSPs = 0; for (Infopoint sp : cr.getInfopoints()) { diff -r 87eafaddf9d9 -r bce1c7759d9d graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java Wed May 08 18:05:57 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java Thu May 09 11:32:08 2013 +0200 @@ -22,12 +22,15 @@ */ package com.oracle.graal.compiler.test.backend; +import static com.oracle.graal.api.code.CodeUtil.*; + import java.util.*; import java.util.concurrent.*; import org.junit.*; import com.oracle.graal.api.code.*; +import com.oracle.graal.api.code.CallingConvention.Type; import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.*; import com.oracle.graal.compiler.test.*; @@ -123,7 +126,8 @@ @Override public RegisterStats call() { - GraalCompiler.emitLIR(backend, backend.target, lir, graph, graph.method()); + CallingConvention cc = getCallingConvention(runtime, Type.JavaCallee, graph.method(), false); + GraalCompiler.emitLIR(backend, backend.target, lir, graph, cc); return new RegisterStats(lir); } }); diff -r 87eafaddf9d9 -r bce1c7759d9d graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Wed May 08 18:05:57 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Thu May 09 11:32:08 2013 +0200 @@ -22,7 +22,6 @@ */ package com.oracle.graal.compiler; -import java.lang.reflect.*; import java.util.*; import java.util.concurrent.*; @@ -47,15 +46,26 @@ import com.oracle.graal.phases.tiers.*; import com.oracle.graal.virtual.phases.ea.*; +/** + * Static methods for orchestrating the compilation of a {@linkplain StructuredGraph graph}. + */ public class GraalCompiler { - public static CompilationResult compileMethod(final GraalCodeCacheProvider runtime, final Replacements replacements, final Backend backend, final TargetDescription target, - final ResolvedJavaMethod method, final StructuredGraph graph, final GraphCache cache, final PhasePlan plan, final OptimisticOptimizations optimisticOpts, + /** + * Requests compilation of a given graph. + * + * @param graph the graph to be compiled + * @param cc the calling convention for calls to the code compiled for {@code graph} + * @param installedCodeOwner the method the compiled code will be + * {@linkplain InstalledCode#getMethod() associated} with once installed. This + * argument can be null. + * @return the result of the compilation + */ + public static CompilationResult compileGraph(final StructuredGraph graph, final CallingConvention cc, final ResolvedJavaMethod installedCodeOwner, final GraalCodeCacheProvider runtime, + final Replacements replacements, final Backend backend, final TargetDescription target, final GraphCache cache, final PhasePlan plan, final OptimisticOptimizations optimisticOpts, final SpeculationLog speculationLog) { - assert (method.getModifiers() & Modifier.NATIVE) == 0 : "compiling native methods is not supported"; - final CompilationResult compilationResult = new CompilationResult(); - Debug.scope("GraalCompiler", new Object[]{graph, method, runtime}, new Runnable() { + Debug.scope("GraalCompiler", new Object[]{graph, runtime}, new Runnable() { public void run() { final Assumptions assumptions = new Assumptions(GraalOptions.OptAssumptions); @@ -68,13 +78,13 @@ final LIRGenerator lirGen = Debug.scope("BackEnd", lir, new Callable() { public LIRGenerator call() { - return emitLIR(backend, target, lir, graph, method); + return emitLIR(backend, target, lir, graph, cc); } }); Debug.scope("CodeGen", lirGen, new Runnable() { public void run() { - emitCode(backend, getLeafGraphIdArray(graph), assumptions, method, lirGen, compilationResult); + emitCode(backend, getLeafGraphIdArray(graph), assumptions, lirGen, compilationResult, installedCodeOwner); } }); @@ -174,9 +184,9 @@ } - public static LIRGenerator emitLIR(Backend backend, final TargetDescription target, final LIR lir, StructuredGraph graph, final ResolvedJavaMethod method) { + public static LIRGenerator emitLIR(Backend backend, final TargetDescription target, final LIR lir, StructuredGraph graph, CallingConvention cc) { final FrameMap frameMap = backend.newFrameMap(); - final LIRGenerator lirGen = backend.newLIRGenerator(graph, frameMap, method, lir); + final LIRGenerator lirGen = backend.newLIRGenerator(graph, frameMap, cc, lir); Debug.scope("LIRGen", lirGen, new Runnable() { @@ -205,16 +215,16 @@ Debug.scope("Allocator", new Runnable() { public void run() { - new LinearScan(target, method, lir, lirGen, frameMap).allocate(); + new LinearScan(target, lir, lirGen, frameMap).allocate(); } }); return lirGen; } - public static void emitCode(Backend backend, long[] leafGraphIds, Assumptions assumptions, ResolvedJavaMethod method, LIRGenerator lirGen, CompilationResult compilationResult) { + public static void emitCode(Backend backend, long[] leafGraphIds, Assumptions assumptions, LIRGenerator lirGen, CompilationResult compilationResult, ResolvedJavaMethod installedCodeOwner) { TargetMethodAssembler tasm = backend.newAssembler(lirGen, compilationResult); - backend.emitCode(tasm, method, lirGen); - CompilationResult result = tasm.finishTargetMethod(method, false); + backend.emitCode(tasm, lirGen, installedCodeOwner); + CompilationResult result = tasm.finishTargetMethod(lirGen.getGraph()); if (!assumptions.isEmpty()) { result.setAssumptions(assumptions); } diff -r 87eafaddf9d9 -r bce1c7759d9d graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java Wed May 08 18:05:57 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java Thu May 09 11:32:08 2013 +0200 @@ -29,6 +29,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; +import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.util.*; import com.oracle.graal.phases.*; @@ -94,6 +95,24 @@ return filter != null && filter.matches(currentScope); } + /** + * Extracts a {@link JavaMethod} from an opaque debug context. + * + * @return the {@link JavaMethod} represented by {@code context} or null + */ + public static JavaMethod asJavaMethod(Object context) { + if (context instanceof JavaMethod) { + return (JavaMethod) context; + } + if (context instanceof StructuredGraph) { + ResolvedJavaMethod method = ((StructuredGraph) context).method(); + if (method != null) { + return method; + } + } + return null; + } + private boolean checkMethodFilter() { if (methodFilter == null && extraFilters.isEmpty()) { return true; @@ -102,9 +121,10 @@ if (extraFilters.contains(o)) { return true; } else if (methodFilter != null) { - if (o instanceof JavaMethod) { + JavaMethod method = asJavaMethod(o); + if (method != null) { for (MethodFilter filter : methodFilter) { - if (filter.matches((JavaMethod) o)) { + if (filter.matches(method)) { return true; } } diff -r 87eafaddf9d9 -r bce1c7759d9d graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java Wed May 08 18:05:57 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java Thu May 09 11:32:08 2013 +0200 @@ -56,7 +56,6 @@ public final class LinearScan { final TargetDescription target; - final JavaMethod method; final LIR ir; final LIRGenerator gen; final FrameMap frameMap; @@ -156,9 +155,8 @@ */ private final int firstVariableNumber; - public LinearScan(TargetDescription target, ResolvedJavaMethod method, LIR ir, LIRGenerator gen, FrameMap frameMap) { + public LinearScan(TargetDescription target, LIR ir, LIRGenerator gen, FrameMap frameMap) { this.target = target; - this.method = method; this.ir = ir; this.gen = gen; this.frameMap = frameMap; @@ -884,7 +882,7 @@ } private void reportFailure(int numBlocks) { - TTY.println(method.toString()); + TTY.println(gen.getGraph().toString()); TTY.println("Error: liveIn set of first block must be empty (when this fails, variables are used before they are defined)"); TTY.print("affected registers:"); TTY.println(blockData.get(ir.cfg.getStartBlock()).liveIn.toString()); diff -r 87eafaddf9d9 -r bce1c7759d9d graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Wed May 08 18:05:57 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Thu May 09 11:32:08 2013 +0200 @@ -61,7 +61,7 @@ protected final StructuredGraph graph; protected final CodeCacheProvider runtime; protected final TargetDescription target; - protected final ResolvedJavaMethod method; + protected final CallingConvention cc; protected final DebugInfoBuilder debugInfoBuilder; @@ -85,12 +85,18 @@ */ public abstract boolean canStoreConstant(Constant c); - public LIRGenerator(StructuredGraph graph, CodeCacheProvider runtime, TargetDescription target, FrameMap frameMap, ResolvedJavaMethod method, LIR lir) { + public LIRGenerator(StructuredGraph graph, CodeCacheProvider runtime, TargetDescription target, FrameMap frameMap, CallingConvention cc, LIR lir) { this.graph = graph; this.runtime = runtime; this.target = target; this.frameMap = frameMap; - this.method = method; + if (graph.getEntryBCI() == StructuredGraph.INVOCATION_ENTRY_BCI) { + this.cc = cc; + } else { + JavaType[] parameterTypes = new JavaType[]{runtime.lookupJavaType(long.class)}; + CallingConvention tmp = frameMap.registerConfig.getCallingConvention(JavaCallee, runtime.lookupJavaType(void.class), parameterTypes, target, false); + this.cc = new CallingConvention(cc.getStackSize(), cc.getReturn(), tmp.getArgument(0)); + } this.nodeOperands = graph.createNodeMap(); this.lir = lir; this.debugInfoBuilder = createDebugInfoBuilder(nodeOperands); @@ -112,8 +118,8 @@ return runtime; } - public ResolvedJavaMethod method() { - return method; + public StructuredGraph getGraph() { + return graph; } /** @@ -423,12 +429,8 @@ ((LIRLowerable) node).generate(this); } - protected CallingConvention createCallingConvention() { - return frameMap.registerConfig.getCallingConvention(JavaCallee, method.getSignature().getReturnType(null), MetaUtil.signatureToTypes(method), target, false); - } - protected void emitPrologue() { - CallingConvention incomingArguments = createCallingConvention(); + CallingConvention incomingArguments = cc; Value[] params = new Value[incomingArguments.getArgumentCount()]; for (int i = 0; i < params.length; i++) { @@ -594,10 +596,10 @@ @Override public void emitInvoke(Invoke x) { LoweredCallTargetNode callTarget = (LoweredCallTargetNode) x.callTarget(); - CallingConvention cc = frameMap.registerConfig.getCallingConvention(callTarget.callType(), x.asNode().stamp().javaType(runtime), callTarget.signature(), target(), false); - frameMap.callsMethod(cc); + CallingConvention invokeCc = frameMap.registerConfig.getCallingConvention(callTarget.callType(), x.asNode().stamp().javaType(runtime), callTarget.signature(), target(), false); + frameMap.callsMethod(invokeCc); - Value[] parameters = visitInvokeArguments(cc, callTarget.arguments()); + Value[] parameters = visitInvokeArguments(invokeCc, callTarget.arguments()); LabelRef exceptionEdge = null; if (x instanceof InvokeWithExceptionNode) { @@ -605,11 +607,11 @@ } LIRFrameState callState = stateWithExceptionEdge(x, exceptionEdge); - Value result = cc.getReturn(); + Value result = invokeCc.getReturn(); if (callTarget instanceof DirectCallTargetNode) { - emitDirectCall((DirectCallTargetNode) callTarget, result, parameters, cc.getTemporaries(), callState); + emitDirectCall((DirectCallTargetNode) callTarget, result, parameters, invokeCc.getTemporaries(), callState); } else if (callTarget instanceof IndirectCallTargetNode) { - emitIndirectCall((IndirectCallTargetNode) callTarget, result, parameters, cc.getTemporaries(), callState); + emitIndirectCall((IndirectCallTargetNode) callTarget, result, parameters, invokeCc.getTemporaries(), callState); } else { throw GraalInternalError.shouldNotReachHere(); } @@ -640,13 +642,13 @@ return value; } - public Value[] visitInvokeArguments(CallingConvention cc, Collection arguments) { + public Value[] visitInvokeArguments(CallingConvention invokeCc, Collection arguments) { // for each argument, load it into the correct location Value[] result = new Value[arguments.size()]; int j = 0; for (ValueNode arg : arguments) { if (arg != null) { - AllocatableValue operand = toStackKind(cc.getArgument(j)); + AllocatableValue operand = toStackKind(invokeCc.getArgument(j)); emitMove(operand, operand(arg)); result[j] = operand; j++; @@ -658,23 +660,23 @@ } @Override - public Variable emitCall(RuntimeCallTarget callTarget, CallingConvention cc, DeoptimizingNode info, Value... args) { + public Variable emitCall(RuntimeCallTarget callTarget, CallingConvention callCc, DeoptimizingNode info, Value... args) { LIRFrameState state = info != null ? state(info) : null; // move the arguments into the correct location - frameMap.callsMethod(cc); - assert cc.getArgumentCount() == args.length : "argument count mismatch"; + frameMap.callsMethod(callCc); + assert callCc.getArgumentCount() == args.length : "argument count mismatch"; Value[] argLocations = new Value[args.length]; for (int i = 0; i < args.length; i++) { Value arg = args[i]; - AllocatableValue loc = cc.getArgument(i); + AllocatableValue loc = callCc.getArgument(i); emitMove(loc, arg); argLocations[i] = loc; } - emitCall(callTarget, cc.getReturn(), argLocations, cc.getTemporaries(), state); + emitCall(callTarget, callCc.getReturn(), argLocations, callCc.getTemporaries(), state); - if (isLegal(cc.getReturn())) { - return emitMove(cc.getReturn()); + if (isLegal(callCc.getReturn())) { + return emitMove(callCc.getReturn()); } else { return null; } @@ -683,12 +685,12 @@ @Override public void visitRuntimeCall(RuntimeCallNode x) { RuntimeCallTarget call = runtime.lookupRuntimeCall(x.getDescriptor()); - CallingConvention cc = call.getCallingConvention(); - frameMap.callsMethod(cc); - Value resultOperand = cc.getReturn(); - Value[] args = visitInvokeArguments(cc, x.arguments()); + CallingConvention callCc = call.getCallingConvention(); + frameMap.callsMethod(callCc); + Value resultOperand = callCc.getReturn(); + Value[] args = visitInvokeArguments(callCc, x.arguments()); - emitCall(call, resultOperand, args, cc.getTemporaries(), state(x)); + emitCall(call, resultOperand, args, callCc.getTemporaries(), state(x)); if (isLegal(resultOperand)) { setResult(x, emitMove(resultOperand)); diff -r 87eafaddf9d9 -r bce1c7759d9d graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/Backend.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/Backend.java Wed May 08 18:05:57 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/Backend.java Thu May 09 11:32:08 2013 +0200 @@ -51,17 +51,18 @@ return new FrameMap(runtime, target, runtime.lookupRegisterConfig()); } - public abstract LIRGenerator newLIRGenerator(StructuredGraph graph, FrameMap frameMap, ResolvedJavaMethod method, LIR lir); + public abstract LIRGenerator newLIRGenerator(StructuredGraph graph, FrameMap frameMap, CallingConvention cc, LIR lir); protected abstract AbstractAssembler createAssembler(FrameMap frameMap); public abstract TargetMethodAssembler newAssembler(LIRGenerator lirGen, CompilationResult compilationResult); /** - * Emits the code for a given method. This includes any architecture/runtime specific - * prefix/suffix. A prefix typically contains the code for setting up the frame, spilling - * callee-save registers, stack overflow checking, handling multiple entry points etc. A suffix - * may contain out-of-line stubs and method end guard instructions. + * Emits the code for a given graph. + * + * @param installedCodeOwner the method the compiled code will be + * {@linkplain InstalledCode#getMethod() associated} with once installed. This + * argument can be null. */ - public abstract void emitCode(TargetMethodAssembler tasm, ResolvedJavaMethod method, LIRGenerator lirGen); + public abstract void emitCode(TargetMethodAssembler tasm, LIRGenerator lirGen, ResolvedJavaMethod installedCodeOwner); } diff -r 87eafaddf9d9 -r bce1c7759d9d graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java Wed May 08 18:05:57 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java Thu May 09 11:32:08 2013 +0200 @@ -26,8 +26,8 @@ import static com.oracle.graal.api.code.CallingConvention.Type.*; import static com.oracle.graal.api.code.ValueUtil.*; import static com.oracle.graal.phases.GraalOptions.*; +import static java.lang.reflect.Modifier.*; -import java.lang.reflect.*; import java.util.*; import sun.misc.*; @@ -64,8 +64,8 @@ } @Override - public LIRGenerator newLIRGenerator(StructuredGraph graph, FrameMap frameMap, ResolvedJavaMethod method, LIR lir) { - return new AMD64HotSpotLIRGenerator(graph, runtime(), target, frameMap, method, lir); + public LIRGenerator newLIRGenerator(StructuredGraph graph, FrameMap frameMap, CallingConvention cc, LIR lir) { + return new AMD64HotSpotLIRGenerator(graph, runtime(), target, frameMap, cc, lir); } /** @@ -160,7 +160,7 @@ LIR lir = gen.lir; boolean omitFrame = CanOmitFrame && !frameMap.frameNeedsAllocating() && !lir.hasArgInCallerFrame(); - Stub stub = runtime().asStub(lirGen.method()); + Stub stub = gen.getStub(); AbstractAssembler masm = createAssembler(frameMap); HotSpotFrameContext frameContext = omitFrame ? null : new HotSpotFrameContext(stub != null); TargetMethodAssembler tasm = new TargetMethodAssembler(target, runtime(), frameMap, masm, frameContext, compilationResult); @@ -219,17 +219,16 @@ } @Override - public void emitCode(TargetMethodAssembler tasm, ResolvedJavaMethod method, LIRGenerator lirGen) { + public void emitCode(TargetMethodAssembler tasm, LIRGenerator lirGen, ResolvedJavaMethod installedCodeOwner) { AMD64MacroAssembler asm = (AMD64MacroAssembler) tasm.asm; FrameMap frameMap = tasm.frameMap; RegisterConfig regConfig = frameMap.registerConfig; HotSpotVMConfig config = runtime().config; - boolean isStatic = Modifier.isStatic(method.getModifiers()); - Label unverifiedStub = isStatic ? null : new Label(); + Label unverifiedStub = installedCodeOwner == null || isStatic(installedCodeOwner.getModifiers()) ? null : new Label(); // Emit the prefix - if (!isStatic) { + if (unverifiedStub != null) { tasm.recordMark(Marks.MARK_UNVERIFIED_ENTRY); CallingConvention cc = regConfig.getCallingConvention(JavaCallee, null, new JavaType[]{runtime().lookupJavaType(Object.class)}, target, false); Register inlineCacheKlass = rax; // see definition of IC_Klass in @@ -257,7 +256,7 @@ } else { // No need to emit the stubs for entries back into the method since // it has no calls that can cause such "return" entries - assert !frameMap.accessesCallerFrame() : method; + assert !frameMap.accessesCallerFrame() : lirGen.getGraph(); } if (unverifiedStub != null) { diff -r 87eafaddf9d9 -r bce1c7759d9d graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Wed May 08 18:05:57 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Thu May 09 11:32:08 2013 +0200 @@ -23,7 +23,6 @@ package com.oracle.graal.hotspot.amd64; import static com.oracle.graal.amd64.AMD64.*; -import static com.oracle.graal.api.code.CallingConvention.Type.*; import static com.oracle.graal.api.code.ValueUtil.*; import static com.oracle.graal.hotspot.HotSpotBackend.*; @@ -60,8 +59,8 @@ return (HotSpotRuntime) runtime; } - protected AMD64HotSpotLIRGenerator(StructuredGraph graph, CodeCacheProvider runtime, TargetDescription target, FrameMap frameMap, ResolvedJavaMethod method, LIR lir) { - super(graph, runtime, target, frameMap, method, lir); + protected AMD64HotSpotLIRGenerator(StructuredGraph graph, CodeCacheProvider runtime, TargetDescription target, FrameMap frameMap, CallingConvention cc, LIR lir) { + super(graph, runtime, target, frameMap, cc, lir); } /** @@ -139,7 +138,7 @@ @Override protected void emitPrologue() { - CallingConvention incomingArguments = createCallingConvention(); + CallingConvention incomingArguments = cc; RegisterValue rbpParam = rbp.asValue(Kind.Long); Value[] params = new Value[incomingArguments.getArgumentCount() + 1]; @@ -175,7 +174,7 @@ @Override protected boolean needOnlyOopMaps() { // Stubs only need oop maps - return runtime().asStub(method) != null; + return graph.start() instanceof StubStartNode; } /** @@ -202,11 +201,18 @@ append(new AMD64RestoreRegistersOp(save.getSlots().clone(), save)); } + Stub getStub() { + if (graph.start() instanceof StubStartNode) { + return ((StubStartNode) graph.start()).getStub(); + } + return null; + } + @Override - public Variable emitCall(RuntimeCallTarget callTarget, CallingConvention cc, DeoptimizingNode info, Value... args) { - Stub stub = runtime().asStub(method); + public Variable emitCall(RuntimeCallTarget callTarget, CallingConvention callCc, DeoptimizingNode info, Value... args) { + Stub stub = getStub(); boolean isCRuntimeCall = ((HotSpotRuntimeCallTarget) callTarget).isCRuntimeCall(); - assert !isCRuntimeCall || stub != null : "direct call to C runtime can only be made from compiled stubs, not from " + method; + assert !isCRuntimeCall || stub != null : "direct call to C runtime can only be made from compiled stubs, not from " + graph; AMD64SaveRegistersOp save = null; StackSlot[] savedRegisterLocations = null; @@ -225,7 +231,7 @@ append(new AMD64HotSpotCRuntimeCallPrologueOp()); } - Variable result = super.emitCall(callTarget, cc, info, args); + Variable result = super.emitCall(callTarget, callCc, info, args); if (isCRuntimeCall) { append(new AMD64HotSpotCRuntimeCallEpilogueOp()); @@ -261,20 +267,6 @@ } @Override - protected CallingConvention createCallingConvention() { - Stub stub = runtime().asStub(method); - if (stub != null) { - return stub.getLinkage().getCallingConvention(); - } - - if (graph.getEntryBCI() == StructuredGraph.INVOCATION_ENTRY_BCI) { - return super.createCallingConvention(); - } else { - return frameMap.registerConfig.getCallingConvention(JavaCallee, method.getSignature().getReturnType(null), new JavaType[]{runtime.lookupJavaType(long.class)}, target, false); - } - } - - @Override public void visitSafepointNode(SafepointNode i) { LIRFrameState info = state(i); append(new AMD64SafepointOp(info, runtime().config, this)); @@ -340,9 +332,9 @@ @Override public void emitUnwind(Value exception) { RuntimeCallTarget stub = getRuntime().lookupRuntimeCall(HotSpotBackend.UNWIND_EXCEPTION_TO_CALLER); - CallingConvention cc = stub.getCallingConvention(); - assert cc.getArgumentCount() == 2; - RegisterValue exceptionParameter = (RegisterValue) cc.getArgument(0); + CallingConvention stubCc = stub.getCallingConvention(); + assert stubCc.getArgumentCount() == 2; + RegisterValue exceptionParameter = (RegisterValue) stubCc.getArgument(0); emitMove(exceptionParameter, exception); append(new AMD64HotSpotUnwindOp(exceptionParameter)); } @@ -366,10 +358,10 @@ public void emitJumpToExceptionHandlerInCaller(ValueNode handlerInCallerPc, ValueNode exception, ValueNode exceptionPc) { Variable handler = load(operand(handlerInCallerPc)); RuntimeCallTarget stub = getRuntime().lookupRuntimeCall(EXCEPTION_HANDLER_IN_CALLER); - CallingConvention cc = stub.getCallingConvention(); - assert cc.getArgumentCount() == 2; - RegisterValue exceptionFixed = (RegisterValue) cc.getArgument(0); - RegisterValue exceptionPcFixed = (RegisterValue) cc.getArgument(1); + CallingConvention stubCc = stub.getCallingConvention(); + assert stubCc.getArgumentCount() == 2; + RegisterValue exceptionFixed = (RegisterValue) stubCc.getArgument(0); + RegisterValue exceptionPcFixed = (RegisterValue) stubCc.getArgument(1); emitMove(exceptionFixed, operand(exception)); emitMove(exceptionPcFixed, operand(exceptionPc)); AMD64HotSpotJumpToExceptionHandlerInCallerOp op = new AMD64HotSpotJumpToExceptionHandlerInCallerOp(handler, exceptionFixed, exceptionPcFixed); diff -r 87eafaddf9d9 -r bce1c7759d9d graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java Wed May 08 18:05:57 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java Thu May 09 11:32:08 2013 +0200 @@ -43,8 +43,8 @@ } @Override - public LIRGenerator newLIRGenerator(StructuredGraph graph, FrameMap frameMap, ResolvedJavaMethod method, LIR lir) { - return new SPARCLIRGenerator(graph, this.runtime(), this.target, frameMap, method, lir); + public LIRGenerator newLIRGenerator(StructuredGraph graph, FrameMap frameMap, CallingConvention cc, LIR lir) { + return new SPARCLIRGenerator(graph, this.runtime(), this.target, frameMap, cc, lir); } @Override @@ -60,7 +60,7 @@ } @Override - public void emitCode(TargetMethodAssembler tasm, ResolvedJavaMethod method, LIRGenerator lirGen) { + public void emitCode(TargetMethodAssembler tasm, LIRGenerator lirGen, ResolvedJavaMethod codeCacheOwner) { // SPARC: Emit code } } diff -r 87eafaddf9d9 -r bce1c7759d9d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Wed May 08 18:05:57 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Thu May 09 11:32:08 2013 +0200 @@ -22,6 +22,7 @@ */ package com.oracle.graal.hotspot; +import static com.oracle.graal.api.code.CodeUtil.*; import static com.oracle.graal.nodes.StructuredGraph.*; import static com.oracle.graal.phases.common.InliningUtil.*; @@ -29,6 +30,7 @@ import java.util.concurrent.*; import com.oracle.graal.api.code.*; +import com.oracle.graal.api.code.CallingConvention.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.*; import com.oracle.graal.debug.*; @@ -157,8 +159,10 @@ graph = graph.copy(); } InlinedBytecodes.add(method.getCodeSize()); - return GraalCompiler.compileMethod(graalRuntime.getRuntime(), replacements, graalRuntime.getBackend(), graalRuntime.getTarget(), method, graph, graalRuntime.getCache(), plan, - optimisticOpts, method.getSpeculationLog()); + HotSpotRuntime runtime = graalRuntime.getRuntime(); + CallingConvention cc = getCallingConvention(runtime, Type.JavaCallee, graph.method(), false); + return GraalCompiler.compileGraph(graph, cc, method, runtime, replacements, graalRuntime.getBackend(), graalRuntime.getTarget(), graalRuntime.getCache(), plan, optimisticOpts, + method.getSpeculationLog()); } }); } finally { diff -r 87eafaddf9d9 -r bce1c7759d9d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotRuntimeCallTarget.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotRuntimeCallTarget.java Wed May 08 18:05:57 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotRuntimeCallTarget.java Thu May 09 11:32:08 2013 +0200 @@ -74,7 +74,7 @@ @Override public String toString() { - return (stub == null ? descriptor.toString() : MetaUtil.format("%h.%n", stub.getMethod())) + "@0x" + Long.toHexString(address) + ":" + cc; + return (stub == null ? descriptor.toString() : stub) + "@0x" + Long.toHexString(address) + ":" + cc; } public CallingConvention getCallingConvention() { diff -r 87eafaddf9d9 -r bce1c7759d9d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java Wed May 08 18:05:57 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java Thu May 09 11:32:08 2013 +0200 @@ -210,6 +210,8 @@ int getVtableEntryOffset(long metaspaceMethod); + boolean hasVtableEntry(long metaspaceMethod); + long[] getDeoptedLeafGraphIds(); long[] getLineNumberTable(HotSpotResolvedJavaMethod method); diff -r 87eafaddf9d9 -r bce1c7759d9d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java Wed May 08 18:05:57 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java Thu May 09 11:32:08 2013 +0200 @@ -145,6 +145,9 @@ public native int getVtableEntryOffset(long metaspaceMethod); @Override + public native boolean hasVtableEntry(long metaspaceMethod); + + @Override public native long[] getDeoptedLeafGraphIds(); @Override diff -r 87eafaddf9d9 -r bce1c7759d9d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java Wed May 08 18:05:57 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java Thu May 09 11:32:08 2013 +0200 @@ -383,7 +383,8 @@ /** * Returns the offset of this method into the v-table. If the holder is not initialized, returns - * -1 + * -1. If it is initialized the method must have a v-table entry has indicated by + * {@link #hasVtableEntry()}. * * @return the offset of this method into the v-table */ @@ -394,6 +395,10 @@ return graalRuntime().getCompilerToVM().getVtableEntryOffset(metaspaceMethod); } + public boolean hasVtableEntry() { + return graalRuntime().getCompilerToVM().hasVtableEntry(metaspaceMethod); + } + public void setCurrentTask(CompilationTask task) { currentTask = task; } @@ -455,4 +460,9 @@ throw new IllegalArgumentException(ex); } } + + @Override + public boolean isInVirtualMethodTable() { + return hasVtableEntry(); + } } diff -r 87eafaddf9d9 -r bce1c7759d9d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Wed May 08 18:05:57 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Thu May 09 11:32:08 2013 +0200 @@ -56,6 +56,7 @@ import static com.oracle.graal.hotspot.stubs.NewMultiArrayStub.*; import static com.oracle.graal.hotspot.stubs.OSRMigrationEndStub.*; import static com.oracle.graal.hotspot.stubs.RegisterFinalizerStub.*; +import static com.oracle.graal.hotspot.stubs.StubUtil.*; import static com.oracle.graal.hotspot.stubs.ThreadIsInterruptedStub.*; import static com.oracle.graal.hotspot.stubs.UnwindExceptionToCallerStub.*; import static com.oracle.graal.hotspot.stubs.VMErrorStub.*; @@ -123,7 +124,6 @@ private LoadExceptionObjectSnippets.Templates exceptionObjectSnippets; private final Map runtimeCalls = new HashMap<>(); - private final Map stubs = new HashMap<>(); /** * The offset from the origin of an array to the first element. @@ -577,31 +577,30 @@ boxingSnippets = new BoxingSnippets.Templates(this, replacements, graalRuntime.getTarget()); exceptionObjectSnippets = new LoadExceptionObjectSnippets.Templates(this, replacements, graalRuntime.getTarget()); - registerStub(new NewInstanceStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(NEW_INSTANCE))); - registerStub(new NewArrayStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(NEW_ARRAY))); - registerStub(new NewMultiArrayStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(NEW_MULTI_ARRAY))); - registerStub(new RegisterFinalizerStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(REGISTER_FINALIZER))); - registerStub(new ThreadIsInterruptedStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(THREAD_IS_INTERRUPTED))); - registerStub(new IdentityHashCodeStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(IDENTITY_HASHCODE))); - registerStub(new ExceptionHandlerStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(EXCEPTION_HANDLER))); - registerStub(new UnwindExceptionToCallerStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(UNWIND_EXCEPTION_TO_CALLER))); - registerStub(new VerifyOopStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(VERIFY_OOP))); - registerStub(new OSRMigrationEndStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(OSR_MIGRATION_END))); - registerStub(new MonitorEnterStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(MONITORENTER))); - registerStub(new MonitorExitStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(MONITOREXIT))); - registerStub(new CreateNullPointerExceptionStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(CREATE_NULL_POINTER_EXCEPTION))); - registerStub(new CreateOutOfBoundsExceptionStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(CREATE_OUT_OF_BOUNDS_EXCEPTION))); - registerStub(new LogPrimitiveStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(LOG_PRIMITIVE))); - registerStub(new LogObjectStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(LOG_OBJECT))); - registerStub(new LogPrintfStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(LOG_PRINTF))); - registerStub(new VMErrorStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(VM_ERROR))); - registerStub(new WriteBarrierPreStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(WRITE_BARRIER_PRE))); - registerStub(new WriteBarrierPostStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(WRITE_BARRIER_POST))); + link(new NewInstanceStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(NEW_INSTANCE))); + link(new NewArrayStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(NEW_ARRAY))); + link(new NewMultiArrayStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(NEW_MULTI_ARRAY))); + link(new RegisterFinalizerStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(REGISTER_FINALIZER))); + link(new ThreadIsInterruptedStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(THREAD_IS_INTERRUPTED))); + link(new IdentityHashCodeStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(IDENTITY_HASHCODE))); + link(new ExceptionHandlerStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(EXCEPTION_HANDLER))); + link(new UnwindExceptionToCallerStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(UNWIND_EXCEPTION_TO_CALLER))); + link(new VerifyOopStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(VERIFY_OOP))); + link(new OSRMigrationEndStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(OSR_MIGRATION_END))); + link(new MonitorEnterStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(MONITORENTER))); + link(new MonitorExitStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(MONITOREXIT))); + link(new CreateNullPointerExceptionStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(CREATE_NULL_POINTER_EXCEPTION))); + link(new CreateOutOfBoundsExceptionStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(CREATE_OUT_OF_BOUNDS_EXCEPTION))); + link(new LogPrimitiveStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(LOG_PRIMITIVE))); + link(new LogObjectStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(LOG_OBJECT))); + link(new LogPrintfStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(LOG_PRINTF))); + link(new VMErrorStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(VM_ERROR))); + link(new WriteBarrierPreStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(WRITE_BARRIER_PRE))); + link(new WriteBarrierPostStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(WRITE_BARRIER_POST))); } - private void registerStub(Stub stub) { + private static void link(Stub stub) { stub.getLinkage().setStub(stub); - stubs.put(stub.getMethod(), stub); } public HotSpotGraalRuntime getGraalRuntime() { @@ -773,8 +772,8 @@ HotSpotResolvedJavaMethod hsMethod = (HotSpotResolvedJavaMethod) callTarget.targetMethod(); if (!hsMethod.getDeclaringClass().isInterface()) { - int vtableEntryOffset = hsMethod.vtableEntryOffset(); - if (vtableEntryOffset > 0) { + if (hsMethod.hasVtableEntry()) { + int vtableEntryOffset = hsMethod.vtableEntryOffset(); assert vtableEntryOffset > 0; ReadNode hub = this.createReadHub(tool, graph, wordKind, receiver); ReadNode metaspaceMethod = createReadVirtualMethod(graph, wordKind, hub, hsMethod); @@ -1049,6 +1048,7 @@ private static ReadNode createReadVirtualMethod(StructuredGraph graph, Kind wordKind, ValueNode hub, ResolvedJavaMethod method) { HotSpotResolvedJavaMethod hsMethod = (HotSpotResolvedJavaMethod) method; assert !hsMethod.getDeclaringClass().isInterface(); + assert hsMethod.hasVtableEntry(); int vtableEntryOffset = hsMethod.vtableEntryOffset(); assert vtableEntryOffset > 0; @@ -1130,16 +1130,6 @@ return HotSpotResolvedObjectType.fromClass(clazz); } - /** - * Gets the stub corresponding to a given method. - * - * @return the stub {@linkplain Stub#getMethod() implemented} by {@code method} or null if - * {@code method} does not implement a stub - */ - public Stub asStub(ResolvedJavaMethod method) { - return stubs.get(method); - } - public HotSpotRuntimeCallTarget lookupRuntimeCall(Descriptor descriptor) { HotSpotRuntimeCallTarget callTarget = runtimeCalls.get(descriptor); assert runtimeCalls != null : descriptor; diff -r 87eafaddf9d9 -r bce1c7759d9d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/StubStartNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/StubStartNode.java Thu May 09 11:32:08 2013 +0200 @@ -0,0 +1,42 @@ +/* + * 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.hotspot.nodes; + +import com.oracle.graal.hotspot.stubs.*; +import com.oracle.graal.nodes.*; + +/** + * Start node for a {@link Stub}'s graph. + */ +public class StubStartNode extends StartNode { + + private final Stub stub; + + public StubStartNode(Stub stub) { + this.stub = stub; + } + + public Stub getStub() { + return stub; + } +} diff -r 87eafaddf9d9 -r bce1c7759d9d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VMErrorNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VMErrorNode.java Wed May 08 18:05:57 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VMErrorNode.java Thu May 09 11:32:08 2013 +0200 @@ -49,7 +49,7 @@ @Override public void generate(LIRGenerator gen) { - String whereString = "in compiled code for " + MetaUtil.format("%H.%n(%p)", gen.method()); + String whereString = "in compiled code for " + graph(); // As these strings will end up embedded as oops in the code, they // must be interned or else they will cause the nmethod to be unloaded diff -r 87eafaddf9d9 -r bce1c7759d9d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/CRuntimeStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/CRuntimeStub.java Wed May 08 18:05:57 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/CRuntimeStub.java Thu May 09 11:32:08 2013 +0200 @@ -32,7 +32,7 @@ /** * Base class for a stub that saves registers around a C runtime call. */ -public abstract class CRuntimeStub extends Stub { +public abstract class CRuntimeStub extends SnippetStub { public CRuntimeStub(final HotSpotRuntime runtime, Replacements replacements, TargetDescription target, HotSpotRuntimeCallTarget linkage) { super(runtime, replacements, target, linkage); diff -r 87eafaddf9d9 -r bce1c7759d9d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/CreateNullPointerExceptionStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/CreateNullPointerExceptionStub.java Wed May 08 18:05:57 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/CreateNullPointerExceptionStub.java Thu May 09 11:32:08 2013 +0200 @@ -46,11 +46,11 @@ @Snippet private static Object createNullPointerException() { createNullPointerExceptionC(CREATE_NULL_POINTER_EXCEPTION_C, thread()); - handlePendingException(true); - return verifyObject(getAndClearObjectResult(thread())); + StubUtil.handlePendingException(true); + return StubUtil.verifyObject(getAndClearObjectResult(thread())); } - public static final Descriptor CREATE_NULL_POINTER_EXCEPTION_C = descriptorFor(CreateNullPointerExceptionStub.class, "createNullPointerExceptionC", false); + public static final Descriptor CREATE_NULL_POINTER_EXCEPTION_C = StubUtil.descriptorFor(CreateNullPointerExceptionStub.class, "createNullPointerExceptionC", false); @NodeIntrinsic(CRuntimeCall.class) public static native void createNullPointerExceptionC(@ConstantNodeParameter Descriptor createNullPointerExceptionC, Word thread); diff -r 87eafaddf9d9 -r bce1c7759d9d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/CreateOutOfBoundsExceptionStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/CreateOutOfBoundsExceptionStub.java Wed May 08 18:05:57 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/CreateOutOfBoundsExceptionStub.java Thu May 09 11:32:08 2013 +0200 @@ -46,11 +46,11 @@ @Snippet private static Object createOutOfBoundsException(int index) { createOutOfBoundsExceptionC(CREATE_OUT_OF_BOUNDS_C, thread(), index); - handlePendingException(true); - return verifyObject(getAndClearObjectResult(thread())); + StubUtil.handlePendingException(true); + return StubUtil.verifyObject(getAndClearObjectResult(thread())); } - public static final Descriptor CREATE_OUT_OF_BOUNDS_C = descriptorFor(CreateOutOfBoundsExceptionStub.class, "createOutOfBoundsExceptionC", false); + public static final Descriptor CREATE_OUT_OF_BOUNDS_C = StubUtil.descriptorFor(CreateOutOfBoundsExceptionStub.class, "createOutOfBoundsExceptionC", false); @NodeIntrinsic(CRuntimeCall.class) public static native void createOutOfBoundsExceptionC(@ConstantNodeParameter Descriptor createOutOfBoundsExceptionC, Word thread, int index); diff -r 87eafaddf9d9 -r bce1c7759d9d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ExceptionHandlerStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ExceptionHandlerStub.java Wed May 08 18:05:57 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ExceptionHandlerStub.java Thu May 09 11:32:08 2013 +0200 @@ -70,11 +70,11 @@ writeExceptionOop(thread(), exception); writeExceptionPc(thread(), exceptionPc); if (logging()) { - printf("handling exception %p (", Word.fromObject(exception).rawValue()); - decipher(Word.fromObject(exception).rawValue()); - printf(") at %p (", Word.fromObject(exception).rawValue(), exceptionPc.rawValue()); - decipher(exceptionPc.rawValue()); - printf(")\n"); + StubUtil.printf("handling exception %p (", Word.fromObject(exception).rawValue()); + StubUtil.decipher(Word.fromObject(exception).rawValue()); + StubUtil.printf(") at %p (", Word.fromObject(exception).rawValue(), exceptionPc.rawValue()); + StubUtil.decipher(exceptionPc.rawValue()); + StubUtil.printf(")\n"); } // patch throwing pc into return address so that deoptimization finds the right debug info @@ -83,9 +83,9 @@ Word handlerPc = exceptionHandlerForPc(EXCEPTION_HANDLER_FOR_PC, thread()); if (logging()) { - printf("handler for exception %p at %p is at %p (", Word.fromObject(exception).rawValue(), exceptionPc.rawValue(), handlerPc.rawValue()); - decipher(handlerPc.rawValue()); - printf(")\n"); + StubUtil.printf("handler for exception %p at %p is at %p (", Word.fromObject(exception).rawValue(), exceptionPc.rawValue(), handlerPc.rawValue()); + StubUtil.decipher(handlerPc.rawValue()); + StubUtil.printf(")\n"); } // patch the return address so that this stub returns to the exception handler @@ -96,18 +96,18 @@ if (enabled) { Object currentException = readExceptionOop(thread()); if (currentException != null) { - fatal("exception object in thread must be null, not %p", Word.fromObject(currentException).rawValue()); + StubUtil.fatal("exception object in thread must be null, not %p", Word.fromObject(currentException).rawValue()); } Word currentExceptionPc = readExceptionPc(thread()); if (currentExceptionPc.notEqual(Word.zero())) { - fatal("exception PC in thread must be zero, not %p", currentExceptionPc.rawValue()); + StubUtil.fatal("exception PC in thread must be zero, not %p", currentExceptionPc.rawValue()); } } } static void checkExceptionNotNull(boolean enabled, Object exception) { if (enabled && exception == null) { - fatal("exception must not be null"); + StubUtil.fatal("exception must not be null"); } } @@ -124,7 +124,7 @@ return enabled || graalRuntime().getConfig().cAssertions; } - public static final Descriptor EXCEPTION_HANDLER_FOR_PC = descriptorFor(ExceptionHandlerStub.class, "exceptionHandlerForPc", false); + public static final Descriptor EXCEPTION_HANDLER_FOR_PC = StubUtil.descriptorFor(ExceptionHandlerStub.class, "exceptionHandlerForPc", false); @NodeIntrinsic(value = CRuntimeCall.class, setStampFromReturnType = true) public static native Word exceptionHandlerForPc(@ConstantNodeParameter Descriptor exceptionHandlerForPc, Word thread); diff -r 87eafaddf9d9 -r bce1c7759d9d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/IdentityHashCodeStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/IdentityHashCodeStub.java Wed May 08 18:05:57 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/IdentityHashCodeStub.java Thu May 09 11:32:08 2013 +0200 @@ -47,11 +47,11 @@ @Snippet private static int identityHashCode(Object object) { int result = identityHashCodeC(IDENTITY_HASH_CODE_C, thread(), object); - handlePendingException(false); + StubUtil.handlePendingException(false); return result; } - public static final Descriptor IDENTITY_HASH_CODE_C = descriptorFor(IdentityHashCodeStub.class, "identityHashCodeC", false); + public static final Descriptor IDENTITY_HASH_CODE_C = StubUtil.descriptorFor(IdentityHashCodeStub.class, "identityHashCodeC", false); @NodeIntrinsic(CRuntimeCall.class) public static native int identityHashCodeC(@ConstantNodeParameter Descriptor identityHashCodeC, Word thread, Object object); diff -r 87eafaddf9d9 -r bce1c7759d9d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/LogObjectStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/LogObjectStub.java Wed May 08 18:05:57 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/LogObjectStub.java Thu May 09 11:32:08 2013 +0200 @@ -49,7 +49,7 @@ logObjectC(LOG_OBJECT_C, thread(), object, flags); } - public static final Descriptor LOG_OBJECT_C = descriptorFor(LogObjectStub.class, "logObjectC", false); + public static final Descriptor LOG_OBJECT_C = StubUtil.descriptorFor(LogObjectStub.class, "logObjectC", false); @NodeIntrinsic(CRuntimeCall.class) public static native void logObjectC(@ConstantNodeParameter Descriptor logObjectC, Word thread, Object object, int flags); diff -r 87eafaddf9d9 -r bce1c7759d9d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/LogPrimitiveStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/LogPrimitiveStub.java Wed May 08 18:05:57 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/LogPrimitiveStub.java Thu May 09 11:32:08 2013 +0200 @@ -49,7 +49,7 @@ logPrimitivefC(LOG_PRIMITIVE_C, thread(), typeChar, value, newline); } - public static final Descriptor LOG_PRIMITIVE_C = descriptorFor(LogPrimitiveStub.class, "logPrimitivefC", false); + public static final Descriptor LOG_PRIMITIVE_C = StubUtil.descriptorFor(LogPrimitiveStub.class, "logPrimitivefC", false); @NodeIntrinsic(CRuntimeCall.class) public static native void logPrimitivefC(@ConstantNodeParameter Descriptor logPrimitivefC, Word thread, char typeChar, long value, boolean newline); diff -r 87eafaddf9d9 -r bce1c7759d9d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/LogPrintfStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/LogPrintfStub.java Wed May 08 18:05:57 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/LogPrintfStub.java Thu May 09 11:32:08 2013 +0200 @@ -49,7 +49,7 @@ logPrintfC(LOG_PRINTF_C, thread(), format, v1, v2, v3); } - public static final Descriptor LOG_PRINTF_C = descriptorFor(LogPrintfStub.class, "logPrintfC", false); + public static final Descriptor LOG_PRINTF_C = StubUtil.descriptorFor(LogPrintfStub.class, "logPrintfC", false); @NodeIntrinsic(CRuntimeCall.class) public static native void logPrintfC(@ConstantNodeParameter Descriptor logPrintfC, Word thread, String format, long v1, long v2, long v3); diff -r 87eafaddf9d9 -r bce1c7759d9d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/MonitorEnterStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/MonitorEnterStub.java Wed May 08 18:05:57 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/MonitorEnterStub.java Thu May 09 11:32:08 2013 +0200 @@ -47,10 +47,10 @@ @Snippet private static void monitorenter(Object object, Word lock) { monitorenterC(MONITORENTER_C, thread(), object, lock); - handlePendingException(false); + StubUtil.handlePendingException(false); } - public static final Descriptor MONITORENTER_C = descriptorFor(MonitorEnterStub.class, "monitorenterC", false); + public static final Descriptor MONITORENTER_C = StubUtil.descriptorFor(MonitorEnterStub.class, "monitorenterC", false); @NodeIntrinsic(CRuntimeCall.class) public static native void monitorenterC(@ConstantNodeParameter Descriptor monitorenterC, Word thread, Object object, Word lock); diff -r 87eafaddf9d9 -r bce1c7759d9d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/MonitorExitStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/MonitorExitStub.java Wed May 08 18:05:57 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/MonitorExitStub.java Thu May 09 11:32:08 2013 +0200 @@ -49,7 +49,7 @@ monitorexitC(MONITOREXIT_C, thread(), object, lock); } - public static final Descriptor MONITOREXIT_C = descriptorFor(MonitorExitStub.class, "monitorexitC", false); + public static final Descriptor MONITOREXIT_C = StubUtil.descriptorFor(MonitorExitStub.class, "monitorexitC", false); @NodeIntrinsic(CRuntimeCall.class) public static native void monitorexitC(@ConstantNodeParameter Descriptor monitorexitC, Word thread, Object object, Word lock); diff -r 87eafaddf9d9 -r bce1c7759d9d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java Wed May 08 18:05:57 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java Thu May 09 11:32:08 2013 +0200 @@ -50,7 +50,7 @@ * code when TLAB allocation fails. If this stub fails to refill the TLAB or allocate the object, it * calls out to the HotSpot C++ runtime to complete the allocation. */ -public class NewArrayStub extends Stub { +public class NewArrayStub extends SnippetStub { public NewArrayStub(final HotSpotRuntime runtime, Replacements replacements, TargetDescription target, HotSpotRuntimeCallTarget linkage) { super(runtime, replacements, target, linkage); @@ -94,10 +94,10 @@ int elementKind = (layoutHelper >> layoutHelperElementTypeShift()) & layoutHelperElementTypeMask(); int sizeInBytes = computeArrayAllocationSize(length, wordSize(), headerSize, log2ElementSize); if (logging()) { - printf("newArray: element kind %d\n", elementKind); - printf("newArray: array length %d\n", length); - printf("newArray: array size %d\n", sizeInBytes); - printf("newArray: hub=%p\n", hub.rawValue()); + StubUtil.printf("newArray: element kind %d\n", elementKind); + StubUtil.printf("newArray: array length %d\n", length); + StubUtil.printf("newArray: array size %d\n", sizeInBytes); + StubUtil.printf("newArray: hub=%p\n", hub.rawValue()); } // check that array length is small enough for fast path. @@ -105,29 +105,29 @@ Word memory = refillAllocate(intArrayHub, sizeInBytes, logging()); if (memory.notEqual(0)) { if (logging()) { - printf("newArray: allocated new array at %p\n", memory.rawValue()); + StubUtil.printf("newArray: allocated new array at %p\n", memory.rawValue()); } formatArray(hub, sizeInBytes, length, headerSize, memory, Word.unsigned(arrayPrototypeMarkWord()), true); - return verifyObject(memory.toObject()); + return StubUtil.verifyObject(memory.toObject()); } } if (logging()) { - printf("newArray: calling new_array_c\n"); + StubUtil.printf("newArray: calling new_array_c\n"); } newArrayC(NEW_ARRAY_C, thread(), hub, length); if (clearPendingException(thread())) { if (logging()) { - printf("newArray: deoptimizing to caller\n"); + StubUtil.printf("newArray: deoptimizing to caller\n"); } getAndClearObjectResult(thread()); DeoptimizeCallerNode.deopt(InvalidateReprofile, RuntimeConstraint); } - return verifyObject(getAndClearObjectResult(thread())); + return StubUtil.verifyObject(getAndClearObjectResult(thread())); } - public static final Descriptor NEW_ARRAY_C = descriptorFor(NewArrayStub.class, "newArrayC", false); + public static final Descriptor NEW_ARRAY_C = StubUtil.descriptorFor(NewArrayStub.class, "newArrayC", false); @NodeIntrinsic(CRuntimeCall.class) public static native void newArrayC(@ConstantNodeParameter Descriptor newArrayC, Word thread, Word hub, int length); diff -r 87eafaddf9d9 -r bce1c7759d9d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java Wed May 08 18:05:57 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java Thu May 09 11:32:08 2013 +0200 @@ -52,7 +52,7 @@ * code when TLAB allocation fails. If this stub fails to refill the TLAB or allocate the object, it * calls out to the HotSpot C++ runtime for to complete the allocation. */ -public class NewInstanceStub extends Stub { +public class NewInstanceStub extends SnippetStub { public NewInstanceStub(final HotSpotRuntime runtime, Replacements replacements, TargetDescription target, HotSpotRuntimeCallTarget linkage) { super(runtime, replacements, target, linkage); @@ -98,25 +98,25 @@ for (int offset = 2 * wordSize(); offset < sizeInBytes; offset += wordSize()) { memory.writeWord(offset, Word.zero(), ANY_LOCATION); } - return verifyObject(memory.toObject()); + return StubUtil.verifyObject(memory.toObject()); } } } if (logging()) { - printf("newInstance: calling new_instance_c\n"); + StubUtil.printf("newInstance: calling new_instance_c\n"); } newInstanceC(NEW_INSTANCE_C, thread(), hub); if (clearPendingException(thread())) { if (logging()) { - printf("newInstance: deoptimizing to caller\n"); + StubUtil.printf("newInstance: deoptimizing to caller\n"); } getAndClearObjectResult(thread()); DeoptimizeCallerNode.deopt(InvalidateReprofile, RuntimeConstraint); } - return verifyObject(getAndClearObjectResult(thread())); + return StubUtil.verifyObject(getAndClearObjectResult(thread())); } /** @@ -143,10 +143,10 @@ Word tlabFreeSpaceInBytes = end.subtract(top); if (log) { - printf("refillTLAB: thread=%p\n", thread.rawValue()); - printf("refillTLAB: top=%p\n", top.rawValue()); - printf("refillTLAB: end=%p\n", end.rawValue()); - printf("refillTLAB: tlabFreeSpaceInBytes=%d\n", tlabFreeSpaceInBytes.rawValue()); + StubUtil.printf("refillTLAB: thread=%p\n", thread.rawValue()); + StubUtil.printf("refillTLAB: top=%p\n", top.rawValue()); + StubUtil.printf("refillTLAB: end=%p\n", end.rawValue()); + StubUtil.printf("refillTLAB: tlabFreeSpaceInBytes=%d\n", tlabFreeSpaceInBytes.rawValue()); } Word tlabFreeSpaceInWords = tlabFreeSpaceInBytes.unsignedShiftRight(log2WordSize()); @@ -159,12 +159,12 @@ // increment number of refills thread.writeInt(tlabNumberOfRefillsOffset(), thread.readInt(tlabNumberOfRefillsOffset(), TLAB_NOF_REFILLS_LOCATION) + 1, TLAB_NOF_REFILLS_LOCATION); if (log) { - printf("thread: %p -- number_of_refills %d\n", thread.rawValue(), thread.readInt(tlabNumberOfRefillsOffset(), TLAB_NOF_REFILLS_LOCATION)); + StubUtil.printf("thread: %p -- number_of_refills %d\n", thread.rawValue(), thread.readInt(tlabNumberOfRefillsOffset(), TLAB_NOF_REFILLS_LOCATION)); } // accumulate wastage Word wastage = thread.readWord(tlabFastRefillWasteOffset(), TLAB_FAST_REFILL_WASTE_LOCATION).add(tlabFreeSpaceInWords); if (log) { - printf("thread: %p -- accumulated wastage %d\n", thread.rawValue(), wastage.rawValue()); + StubUtil.printf("thread: %p -- accumulated wastage %d\n", thread.rawValue(), wastage.rawValue()); } thread.writeWord(tlabFastRefillWasteOffset(), wastage, TLAB_FAST_REFILL_WASTE_LOCATION); } @@ -202,7 +202,7 @@ Word newRefillWasteLimit = refillWasteLimit.add(tlabRefillWasteIncrement()); thread.writeWord(tlabRefillWasteLimitOffset(), newRefillWasteLimit, TLAB_REFILL_WASTE_LIMIT_LOCATION); if (log) { - printf("refillTLAB: retaining TLAB - newRefillWasteLimit=%p\n", newRefillWasteLimit.rawValue()); + StubUtil.printf("refillTLAB: retaining TLAB - newRefillWasteLimit=%p\n", newRefillWasteLimit.rawValue()); } if (tlabStats()) { @@ -247,7 +247,7 @@ return Boolean.getBoolean("graal.newInstanceStub.forceSlowPath"); } - public static final Descriptor NEW_INSTANCE_C = descriptorFor(NewInstanceStub.class, "newInstanceC", false); + public static final Descriptor NEW_INSTANCE_C = StubUtil.descriptorFor(NewInstanceStub.class, "newInstanceC", false); @NodeIntrinsic(CRuntimeCall.class) public static native void newInstanceC(@ConstantNodeParameter Descriptor newInstanceC, Word thread, Word hub); diff -r 87eafaddf9d9 -r bce1c7759d9d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewMultiArrayStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewMultiArrayStub.java Wed May 08 18:05:57 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewMultiArrayStub.java Thu May 09 11:32:08 2013 +0200 @@ -47,11 +47,11 @@ @Snippet private static Object newMultiArray(Word hub, int rank, Word dims) { newMultiArrayC(NEW_MULTI_ARRAY_C, thread(), hub, rank, dims); - handlePendingException(true); + StubUtil.handlePendingException(true); return getAndClearObjectResult(thread()); } - public static final Descriptor NEW_MULTI_ARRAY_C = descriptorFor(NewMultiArrayStub.class, "newMultiArrayC", false); + public static final Descriptor NEW_MULTI_ARRAY_C = StubUtil.descriptorFor(NewMultiArrayStub.class, "newMultiArrayC", false); @NodeIntrinsic(CRuntimeCall.class) public static native void newMultiArrayC(@ConstantNodeParameter Descriptor newArrayC, Word thread, Word hub, int rank, Word dims); diff -r 87eafaddf9d9 -r bce1c7759d9d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/OSRMigrationEndStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/OSRMigrationEndStub.java Wed May 08 18:05:57 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/OSRMigrationEndStub.java Thu May 09 11:32:08 2013 +0200 @@ -48,7 +48,7 @@ osrMigrationEndC(OSR_MIGRATION_END_C, buffer); } - public static final Descriptor OSR_MIGRATION_END_C = descriptorFor(OSRMigrationEndStub.class, "osrMigrationEndC", false); + public static final Descriptor OSR_MIGRATION_END_C = StubUtil.descriptorFor(OSRMigrationEndStub.class, "osrMigrationEndC", false); @NodeIntrinsic(CRuntimeCall.class) public static native void osrMigrationEndC(@ConstantNodeParameter Descriptor osrMigrationEndC, Word buffer); diff -r 87eafaddf9d9 -r bce1c7759d9d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/RegisterFinalizerStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/RegisterFinalizerStub.java Wed May 08 18:05:57 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/RegisterFinalizerStub.java Thu May 09 11:32:08 2013 +0200 @@ -48,10 +48,10 @@ @Snippet private static void registerFinalizer(Object object) { registerFinalizerC(REGISTER_FINALIZER_C, thread(), object); - handlePendingException(false); + StubUtil.handlePendingException(false); } - public static final Descriptor REGISTER_FINALIZER_C = descriptorFor(RegisterFinalizerStub.class, "registerFinalizerC", false); + public static final Descriptor REGISTER_FINALIZER_C = StubUtil.descriptorFor(RegisterFinalizerStub.class, "registerFinalizerC", false); @NodeIntrinsic(CRuntimeCall.class) public static native void registerFinalizerC(@ConstantNodeParameter Descriptor registerFinalizerC, Word thread, Object object); diff -r 87eafaddf9d9 -r bce1c7759d9d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/SnippetStub.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/SnippetStub.java Thu May 09 11:32:08 2013 +0200 @@ -0,0 +1,94 @@ +/* + * 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.stubs; + +import static com.oracle.graal.api.meta.MetaUtil.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.hotspot.*; +import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.replacements.Snippet.ConstantParameter; +import com.oracle.graal.replacements.*; +import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates; +import com.oracle.graal.replacements.SnippetTemplate.Arguments; +import com.oracle.graal.replacements.SnippetTemplate.SnippetInfo; + +/** + * Base class for a stub defined by a snippet. + */ +public abstract class SnippetStub extends Stub implements Snippets { + + static class Template extends AbstractTemplates { + + Template(HotSpotRuntime runtime, Replacements replacements, TargetDescription target, Class declaringClass) { + super(runtime, replacements, target); + this.info = snippet(declaringClass, null); + } + + /** + * Info for the method implementing the stub. + */ + protected final SnippetInfo info; + + protected StructuredGraph getGraph(Arguments args) { + SnippetTemplate template = template(args); + return template.copySpecializedGraph(); + } + } + + protected final Template snippet; + + /** + * Creates a new snippet stub. + * + * @param linkage linkage details for a call to the stub + */ + public SnippetStub(HotSpotRuntime runtime, Replacements replacements, TargetDescription target, HotSpotRuntimeCallTarget linkage) { + super(runtime, replacements, linkage); + this.snippet = new Template(runtime, replacements, target, getClass()); + } + + @Override + protected StructuredGraph getGraph() { + return snippet.getGraph(makeArguments(snippet.info)); + } + + /** + * Adds the {@linkplain ConstantParameter constant} arguments of this stub. + */ + protected abstract Arguments makeArguments(SnippetInfo stub); + + @Override + public ResolvedJavaMethod getInstalledCodeOwner() { + return snippet.info.getMethod(); + } + + @Override + public String toString() { + ResolvedJavaMethod method = getInstalledCodeOwner(); + return "Stub<" + (method != null ? format("%h.%n", method) : linkage) + ">"; + } +} diff -r 87eafaddf9d9 -r bce1c7759d9d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java Wed May 08 18:05:57 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java Thu May 09 11:32:08 2013 +0200 @@ -22,15 +22,8 @@ */ package com.oracle.graal.hotspot.stubs; -import static com.oracle.graal.api.code.DeoptimizationAction.*; -import static com.oracle.graal.api.meta.DeoptimizationReason.*; -import static com.oracle.graal.api.meta.MetaUtil.*; import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; -import static com.oracle.graal.hotspot.nodes.CStringNode.*; -import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; -import static com.oracle.graal.word.Word.*; -import java.lang.reflect.*; import java.util.*; import java.util.concurrent.*; @@ -38,14 +31,11 @@ import com.oracle.graal.api.code.CompilationResult.Call; import com.oracle.graal.api.code.CompilationResult.DataPatch; import com.oracle.graal.api.code.CompilationResult.Infopoint; -import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor; import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.*; import com.oracle.graal.compiler.target.*; import com.oracle.graal.debug.*; import com.oracle.graal.debug.internal.*; -import com.oracle.graal.graph.Node.ConstantNodeParameter; -import com.oracle.graal.graph.Node.NodeIntrinsic; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.nodes.*; @@ -54,29 +44,15 @@ import com.oracle.graal.nodes.spi.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.PhasePlan.PhasePosition; -import com.oracle.graal.replacements.*; -import com.oracle.graal.replacements.Snippet.*; -import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates; -import com.oracle.graal.replacements.SnippetTemplate.Arguments; -import com.oracle.graal.replacements.SnippetTemplate.SnippetInfo; -import com.oracle.graal.word.*; //JaCoCo Exclude /** - * Base class for implementing some low level code providing the out-of-line slow path for a - * snippet. A stub may make a direct call to a HotSpot C/C++ runtime function. Stubs are installed - * as an instance of the C++ RuntimeStub class (as opposed to nmethod). - *

- * Implementation detail: The stub classes re-use some of the functionality for {@link Snippet}s - * purely for convenience (e.g., can re-use the {@link ReplacementsImpl}). + * Base class for implementing some low level code providing the out-of-line slow path for a snippet + * and/or a callee saved call to a HotSpot C/C++ runtime function or even a another compiled Java + * method. */ -public abstract class Stub extends AbstractTemplates implements Snippets { - - /** - * The method implementing the stub. - */ - protected final SnippetInfo stubInfo; +public abstract class Stub { /** * The linkage information for the stub. @@ -116,31 +92,19 @@ return true; } + protected final HotSpotRuntime runtime; + + protected final Replacements replacements; + /** - * Creates a new stub container.. + * Creates a new stub. * * @param linkage linkage details for a call to the stub */ - public Stub(HotSpotRuntime runtime, Replacements replacements, TargetDescription target, HotSpotRuntimeCallTarget linkage) { - super(runtime, replacements, target); - this.stubInfo = snippet(getClass(), null); + public Stub(HotSpotRuntime runtime, Replacements replacements, HotSpotRuntimeCallTarget linkage) { this.linkage = linkage; - } - - /** - * Adds the {@linkplain ConstantParameter constant} arguments of this stub. - */ - protected abstract Arguments makeArguments(SnippetInfo stub); - - protected HotSpotRuntime runtime() { - return (HotSpotRuntime) runtime; - } - - /** - * Gets the method implementing this stub. - */ - public ResolvedJavaMethod getMethod() { - return stubInfo.getMethod(); + this.runtime = runtime; + this.replacements = replacements; } public HotSpotRuntimeCallTarget getLinkage() { @@ -153,40 +117,32 @@ private boolean checkStubInvariants(CompilationResult compResult) { for (DataPatch data : compResult.getDataReferences()) { Constant constant = data.constant; - assert constant.getKind() != Kind.Object : format("%h.%n(%p): ", getMethod()) + "cannot have embedded object constant: " + constant; - assert constant.getPrimitiveAnnotation() == null : format("%h.%n(%p): ", getMethod()) + "cannot have embedded metadata: " + constant; + assert constant.getKind() != Kind.Object : this + " cannot have embedded object constant: " + constant; + assert constant.getPrimitiveAnnotation() == null : this + " cannot have embedded metadata: " + constant; } for (Infopoint infopoint : compResult.getInfopoints()) { - assert infopoint instanceof Call : format("%h.%n(%p): ", getMethod()) + "cannot have non-call infopoint: " + infopoint; + assert infopoint instanceof Call : this + " cannot have non-call infopoint: " + infopoint; Call call = (Call) infopoint; - assert call.target instanceof HotSpotRuntimeCallTarget : format("%h.%n(%p): ", getMethod()) + "cannot have non runtime call: " + call.target; + assert call.target instanceof HotSpotRuntimeCallTarget : this + " cannot have non runtime call: " + call.target; HotSpotRuntimeCallTarget callTarget = (HotSpotRuntimeCallTarget) call.target; - assert callTarget.getAddress() == graalRuntime().getConfig().uncommonTrapStub || callTarget.isCRuntimeCall() : format("%h.%n(%p): ", getMethod()) + - "must only call C runtime or deoptimization stub, not " + call.target; + assert callTarget.getAddress() == graalRuntime().getConfig().uncommonTrapStub || callTarget.isCRuntimeCall() : this + "must only call C runtime or deoptimization stub, not " + call.target; } return true; } + protected abstract StructuredGraph getGraph(); + + @Override + public abstract String toString(); + /** - * Looks for a {@link CRuntimeCall} node intrinsic named {@code name} in {@code stubClass} and - * returns a {@link Descriptor} based on its signature and the value of {@code hasSideEffect}. + * Gets the method the stub's code will be {@linkplain InstalledCode#getMethod() associated} + * with once installed. This may be null. */ - protected static Descriptor descriptorFor(Class stubClass, String name, boolean hasSideEffect) { - Method found = null; - for (Method method : stubClass.getDeclaredMethods()) { - if (Modifier.isStatic(method.getModifiers()) && method.getAnnotation(NodeIntrinsic.class) != null && method.getName().equals(name)) { - if (method.getAnnotation(NodeIntrinsic.class).value() == CRuntimeCall.class) { - assert found == null : "found more than one C runtime call named " + name + " in " + stubClass; - assert method.getParameterTypes().length != 0 && method.getParameterTypes()[0] == Descriptor.class : "first parameter of C runtime call '" + name + "' in " + stubClass + - " must be of type " + Descriptor.class.getSimpleName(); - found = method; - } - } - } - assert found != null : "could not find C runtime call named " + name + " in " + stubClass; - List> paramList = Arrays.asList(found.getParameterTypes()); - Class[] cCallTypes = paramList.subList(1, paramList.size()).toArray(new Class[paramList.size() - 1]); - return new Descriptor(name, hasSideEffect, found.getReturnType(), cCallTypes); + protected abstract ResolvedJavaMethod getInstalledCodeOwner(); + + protected Object debugScopeContext() { + return getInstalledCodeOwner(); } /** @@ -194,19 +150,22 @@ */ public synchronized InstalledCode getCode(final Backend backend) { if (code == null) { - Debug.sandbox("CompilingStub", new Object[]{runtime(), getMethod()}, DebugScope.getConfig(), new Runnable() { + Debug.sandbox("CompilingStub", new Object[]{runtime, debugScopeContext()}, DebugScope.getConfig(), new Runnable() { @Override public void run() { - Arguments args = makeArguments(stubInfo); - SnippetTemplate template = template(args); - StructuredGraph graph = template.copySpecializedGraph(); + final StructuredGraph graph = getGraph(); + StubStartNode newStart = graph.add(new StubStartNode(Stub.this)); + newStart.setStateAfter(graph.start().stateAfter()); + graph.replaceFixed(graph.start(), newStart); + graph.setStart(newStart); PhasePlan phasePlan = new PhasePlan(); GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL); phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase); - final CompilationResult compResult = GraalCompiler.compileMethod(runtime(), replacements, backend, runtime().getTarget(), getMethod(), graph, null, phasePlan, + CallingConvention cc = linkage.getCallingConvention(); + final CompilationResult compResult = GraalCompiler.compileGraph(graph, cc, getInstalledCodeOwner(), runtime, replacements, backend, runtime.getTarget(), null, phasePlan, OptimisticOptimizations.ALL, new SpeculationLog()); assert checkStubInvariants(compResult); @@ -216,8 +175,8 @@ @Override public InstalledCode call() { - InstalledCode installedCode = runtime().addMethod(getMethod(), compResult); - assert installedCode != null : "error installing stub " + getMethod(); + InstalledCode installedCode = runtime.addMethod(getInstalledCodeOwner(), compResult); + assert installedCode != null : "error installing stub " + this; if (Debug.isDumpEnabled()) { Debug.dump(new Object[]{compResult, installedCode}, "After code installation"); } @@ -228,181 +187,8 @@ }); } }); - assert code != null : "error installing stub " + getMethod(); + assert code != null : "error installing stub " + this; } return code; } - - static void handlePendingException(boolean isObjectResult) { - if (clearPendingException(thread())) { - if (isObjectResult) { - getAndClearObjectResult(thread()); - } - DeoptimizeCallerNode.deopt(InvalidateReprofile, RuntimeConstraint); - } - } - - public static final Descriptor VM_MESSAGE_C = descriptorFor(Stub.class, "vmMessageC", false); - - @NodeIntrinsic(CRuntimeCall.class) - private static native void vmMessageC(@ConstantNodeParameter Descriptor stubPrintfC, boolean vmError, Word format, long v1, long v2, long v3); - - /** - * Prints a message to the log stream. - *

- * Stubs must use this instead of {@link Log#printf(String, long)} to avoid an object - * constant in a RuntimeStub. - * - * @param message a message string - */ - public static void printf(String message) { - vmMessageC(VM_MESSAGE_C, false, cstring(message), 0L, 0L, 0L); - } - - /** - * Prints a message to the log stream. - *

- * Stubs must use this instead of {@link Log#printf(String, long)} to avoid an object - * constant in a RuntimeStub. - * - * @param format a C style printf format value - * @param value the value associated with the first conversion specifier in {@code format} - */ - public static void printf(String format, long value) { - vmMessageC(VM_MESSAGE_C, false, cstring(format), value, 0L, 0L); - } - - /** - * Prints a message to the log stream. - *

- * Stubs must use this instead of {@link Log#printf(String, long, long)} to avoid an object - * constant in a RuntimeStub. - * - * @param format a C style printf format value - * @param v1 the value associated with the first conversion specifier in {@code format} - * @param v2 the value associated with the second conversion specifier in {@code format} - */ - public static void printf(String format, long v1, long v2) { - vmMessageC(VM_MESSAGE_C, false, cstring(format), v1, v2, 0L); - } - - /** - * Prints a message to the log stream. - *

- * Stubs must use this instead of {@link Log#printf(String, long, long, long)} to avoid an - * object constant in a RuntimeStub. - * - * @param format a C style printf format value - * @param v1 the value associated with the first conversion specifier in {@code format} - * @param v2 the value associated with the second conversion specifier in {@code format} - * @param v3 the value associated with the third conversion specifier in {@code format} - */ - public static void printf(String format, long v1, long v2, long v3) { - vmMessageC(VM_MESSAGE_C, false, cstring(format), v1, v2, v3); - } - - /** - * Analyzes a given value and prints information about it to the log stream. - */ - public static void decipher(long value) { - vmMessageC(VM_MESSAGE_C, false, Word.zero(), value, 0L, 0L); - } - - /** - * Exits the VM with a given error message. - *

- * Stubs must use this instead of {@link VMErrorNode#vmError(String, long)} to avoid an - * object constant in a RuntimeStub. - * - * @param message an error message - */ - public static void fatal(String message) { - vmMessageC(VM_MESSAGE_C, true, cstring(message), 0L, 0L, 0L); - } - - /** - * Exits the VM with a given error message. - *

- * Stubs must use this instead of {@link Log#printf(String, long, long, long)} to avoid an - * object constant in a RuntimeStub. - * - * @param format a C style printf format value - * @param value the value associated with the first conversion specifier in {@code format} - */ - public static void fatal(String format, long value) { - vmMessageC(VM_MESSAGE_C, true, cstring(format), value, 0L, 0L); - } - - /** - * Exits the VM with a given error message. - *

- * Stubs must use this instead of {@link Log#printf(String, long, long, long)} to avoid an - * object constant in a RuntimeStub. - * - * @param format a C style printf format value - * @param v1 the value associated with the first conversion specifier in {@code format} - * @param v2 the value associated with the second conversion specifier in {@code format} - */ - public static void fatal(String format, long v1, long v2) { - vmMessageC(VM_MESSAGE_C, true, cstring(format), v1, v2, 0L); - } - - /** - * Exits the VM with a given error message. - *

- * Stubs must use this instead of {@link Log#printf(String, long, long, long)} to avoid an - * object constant in a RuntimeStub. - * - * @param format a C style printf format value - * @param v1 the value associated with the first conversion specifier in {@code format} - * @param v2 the value associated with the second conversion specifier in {@code format} - * @param v3 the value associated with the third conversion specifier in {@code format} - */ - public static void fatal(String format, long v1, long v2, long v3) { - vmMessageC(VM_MESSAGE_C, true, cstring(format), v1, v2, v3); - } - - /** - * Verifies that a given object value is well formed if {@code -XX:+VerifyOops} is enabled. - */ - public static Object verifyObject(Object object) { - if (verifyOops()) { - Word verifyOopCounter = Word.unsigned(verifyOopCounterAddress()); - verifyOopCounter.writeInt(0, verifyOopCounter.readInt(0) + 1); - - Pointer oop = Word.fromObject(object); - if (object != null) { - // make sure object is 'reasonable' - if (!oop.and(unsigned(verifyOopMask())).equal(unsigned(verifyOopBits()))) { - fatal("oop not in heap: %p", oop.rawValue()); - } - - Word klass = oop.readWord(hubOffset()); - if (klass.equal(Word.zero())) { - fatal("klass for oop %p is null", oop.rawValue()); - } - } - } - return object; - } - - @Fold - private static long verifyOopCounterAddress() { - return config().verifyOopCounterAddress; - } - - @Fold - private static long verifyOopMask() { - return config().verifyOopMask; - } - - @Fold - private static long verifyOopBits() { - return config().verifyOopBits; - } - - @Fold - private static int hubOffset() { - return config().hubOffset; - } } diff -r 87eafaddf9d9 -r bce1c7759d9d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/StubUtil.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/StubUtil.java Thu May 09 11:32:08 2013 +0200 @@ -0,0 +1,243 @@ +/* + * 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.hotspot.stubs; + +import static com.oracle.graal.api.code.DeoptimizationAction.*; +import static com.oracle.graal.api.meta.DeoptimizationReason.*; +import static com.oracle.graal.hotspot.nodes.CStringNode.*; +import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; +import static com.oracle.graal.word.Word.*; + +import java.lang.reflect.*; +import java.util.*; + +import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor; +import com.oracle.graal.graph.Node.ConstantNodeParameter; +import com.oracle.graal.graph.Node.NodeIntrinsic; +import com.oracle.graal.hotspot.nodes.*; +import com.oracle.graal.replacements.*; +import com.oracle.graal.replacements.Snippet.Fold; +import com.oracle.graal.word.*; + +//JaCoCo Exclude + +/** + * A collection of methods used in {@link Stub}s. + */ +public class StubUtil { + + public static final Descriptor VM_MESSAGE_C = descriptorFor(StubUtil.class, "vmMessageC", false); + + /** + * Looks for a {@link CRuntimeCall} node intrinsic named {@code name} in {@code stubClass} and + * returns a {@link Descriptor} based on its signature and the value of {@code hasSideEffect}. + */ + public static Descriptor descriptorFor(Class stubClass, String name, boolean hasSideEffect) { + Method found = null; + for (Method method : stubClass.getDeclaredMethods()) { + if (Modifier.isStatic(method.getModifiers()) && method.getAnnotation(NodeIntrinsic.class) != null && method.getName().equals(name)) { + if (method.getAnnotation(NodeIntrinsic.class).value() == CRuntimeCall.class) { + assert found == null : "found more than one C runtime call named " + name + " in " + stubClass; + assert method.getParameterTypes().length != 0 && method.getParameterTypes()[0] == Descriptor.class : "first parameter of C runtime call '" + name + "' in " + stubClass + + " must be of type " + Descriptor.class.getSimpleName(); + found = method; + } + } + } + assert found != null : "could not find C runtime call named " + name + " in " + stubClass; + List> paramList = Arrays.asList(found.getParameterTypes()); + Class[] cCallTypes = paramList.subList(1, paramList.size()).toArray(new Class[paramList.size() - 1]); + return new Descriptor(name, hasSideEffect, found.getReturnType(), cCallTypes); + } + + public static void handlePendingException(boolean isObjectResult) { + if (clearPendingException(thread())) { + if (isObjectResult) { + getAndClearObjectResult(thread()); + } + DeoptimizeCallerNode.deopt(InvalidateReprofile, RuntimeConstraint); + } + } + + @NodeIntrinsic(CRuntimeCall.class) + private static native void vmMessageC(@ConstantNodeParameter Descriptor stubPrintfC, boolean vmError, Word format, long v1, long v2, long v3); + + /** + * Prints a message to the log stream. + *

+ * Stubs must use this instead of {@link Log#printf(String, long)} to avoid an object + * constant in a RuntimeStub. + * + * @param message a message string + */ + public static void printf(String message) { + vmMessageC(VM_MESSAGE_C, false, cstring(message), 0L, 0L, 0L); + } + + /** + * Prints a message to the log stream. + *

+ * Stubs must use this instead of {@link Log#printf(String, long)} to avoid an object + * constant in a RuntimeStub. + * + * @param format a C style printf format value + * @param value the value associated with the first conversion specifier in {@code format} + */ + public static void printf(String format, long value) { + vmMessageC(VM_MESSAGE_C, false, cstring(format), value, 0L, 0L); + } + + /** + * Prints a message to the log stream. + *

+ * Stubs must use this instead of {@link Log#printf(String, long, long)} to avoid an object + * constant in a RuntimeStub. + * + * @param format a C style printf format value + * @param v1 the value associated with the first conversion specifier in {@code format} + * @param v2 the value associated with the second conversion specifier in {@code format} + */ + public static void printf(String format, long v1, long v2) { + vmMessageC(VM_MESSAGE_C, false, cstring(format), v1, v2, 0L); + } + + /** + * Prints a message to the log stream. + *

+ * Stubs must use this instead of {@link Log#printf(String, long, long, long)} to avoid an + * object constant in a RuntimeStub. + * + * @param format a C style printf format value + * @param v1 the value associated with the first conversion specifier in {@code format} + * @param v2 the value associated with the second conversion specifier in {@code format} + * @param v3 the value associated with the third conversion specifier in {@code format} + */ + public static void printf(String format, long v1, long v2, long v3) { + vmMessageC(VM_MESSAGE_C, false, cstring(format), v1, v2, v3); + } + + /** + * Analyzes a given value and prints information about it to the log stream. + */ + public static void decipher(long value) { + vmMessageC(VM_MESSAGE_C, false, Word.zero(), value, 0L, 0L); + } + + /** + * Exits the VM with a given error message. + *

+ * Stubs must use this instead of {@link VMErrorNode#vmError(String, long)} to avoid an + * object constant in a RuntimeStub. + * + * @param message an error message + */ + public static void fatal(String message) { + vmMessageC(VM_MESSAGE_C, true, cstring(message), 0L, 0L, 0L); + } + + /** + * Exits the VM with a given error message. + *

+ * Stubs must use this instead of {@link Log#printf(String, long, long, long)} to avoid an + * object constant in a RuntimeStub. + * + * @param format a C style printf format value + * @param value the value associated with the first conversion specifier in {@code format} + */ + public static void fatal(String format, long value) { + vmMessageC(VM_MESSAGE_C, true, cstring(format), value, 0L, 0L); + } + + /** + * Exits the VM with a given error message. + *

+ * Stubs must use this instead of {@link Log#printf(String, long, long, long)} to avoid an + * object constant in a RuntimeStub. + * + * @param format a C style printf format value + * @param v1 the value associated with the first conversion specifier in {@code format} + * @param v2 the value associated with the second conversion specifier in {@code format} + */ + public static void fatal(String format, long v1, long v2) { + vmMessageC(VM_MESSAGE_C, true, cstring(format), v1, v2, 0L); + } + + /** + * Exits the VM with a given error message. + *

+ * Stubs must use this instead of {@link Log#printf(String, long, long, long)} to avoid an + * object constant in a RuntimeStub. + * + * @param format a C style printf format value + * @param v1 the value associated with the first conversion specifier in {@code format} + * @param v2 the value associated with the second conversion specifier in {@code format} + * @param v3 the value associated with the third conversion specifier in {@code format} + */ + public static void fatal(String format, long v1, long v2, long v3) { + vmMessageC(VM_MESSAGE_C, true, cstring(format), v1, v2, v3); + } + + /** + * Verifies that a given object value is well formed if {@code -XX:+VerifyOops} is enabled. + */ + public static Object verifyObject(Object object) { + if (verifyOops()) { + Word verifyOopCounter = Word.unsigned(verifyOopCounterAddress()); + verifyOopCounter.writeInt(0, verifyOopCounter.readInt(0) + 1); + + Pointer oop = Word.fromObject(object); + if (object != null) { + // make sure object is 'reasonable' + if (!oop.and(unsigned(verifyOopMask())).equal(unsigned(verifyOopBits()))) { + fatal("oop not in heap: %p", oop.rawValue()); + } + + Word klass = oop.readWord(hubOffset()); + if (klass.equal(Word.zero())) { + fatal("klass for oop %p is null", oop.rawValue()); + } + } + } + return object; + } + + @Fold + private static long verifyOopCounterAddress() { + return config().verifyOopCounterAddress; + } + + @Fold + private static long verifyOopMask() { + return config().verifyOopMask; + } + + @Fold + private static long verifyOopBits() { + return config().verifyOopBits; + } + + @Fold + private static int hubOffset() { + return config().hubOffset; + } +} diff -r 87eafaddf9d9 -r bce1c7759d9d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ThreadIsInterruptedStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ThreadIsInterruptedStub.java Wed May 08 18:05:57 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ThreadIsInterruptedStub.java Thu May 09 11:32:08 2013 +0200 @@ -47,11 +47,11 @@ @Snippet private static boolean threadIsInterrupted(Thread receiverThread, boolean clearIsInterrupted) { boolean result = threadIsInterruptedC(THREAD_IS_INTERRUPTED_C, thread(), receiverThread, clearIsInterrupted); - handlePendingException(false); + StubUtil.handlePendingException(false); return result; } - public static final Descriptor THREAD_IS_INTERRUPTED_C = descriptorFor(ThreadIsInterruptedStub.class, "threadIsInterruptedC", false); + public static final Descriptor THREAD_IS_INTERRUPTED_C = StubUtil.descriptorFor(ThreadIsInterruptedStub.class, "threadIsInterruptedC", false); @NodeIntrinsic(CRuntimeCall.class) public static native boolean threadIsInterruptedC(@ConstantNodeParameter Descriptor threadIsInterruptedC, Word thread, Thread receiverThread, boolean clearIsInterrupted); diff -r 87eafaddf9d9 -r bce1c7759d9d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/UnwindExceptionToCallerStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/UnwindExceptionToCallerStub.java Wed May 08 18:05:57 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/UnwindExceptionToCallerStub.java Thu May 09 11:32:08 2013 +0200 @@ -63,11 +63,11 @@ private static void unwindExceptionToCaller(Object exception, Word returnAddress) { Pointer exceptionOop = Word.fromObject(exception); if (logging()) { - printf("unwinding exception %p (", exceptionOop.rawValue()); - decipher(exceptionOop.rawValue()); - printf(") at %p (", exceptionOop.rawValue(), returnAddress.rawValue()); - decipher(returnAddress.rawValue()); - printf(")\n"); + StubUtil.printf("unwinding exception %p (", exceptionOop.rawValue()); + StubUtil.decipher(exceptionOop.rawValue()); + StubUtil.printf(") at %p (", exceptionOop.rawValue(), returnAddress.rawValue()); + StubUtil.decipher(returnAddress.rawValue()); + StubUtil.printf(")\n"); } checkNoExceptionInThread(assertionsEnabled()); checkExceptionNotNull(assertionsEnabled(), exception); @@ -75,9 +75,9 @@ Word handlerInCallerPc = exceptionHandlerForReturnAddress(EXCEPTION_HANDLER_FOR_RETURN_ADDRESS, thread(), returnAddress); if (logging()) { - printf("handler for exception %p at return address %p is at %p (", exceptionOop.rawValue(), returnAddress.rawValue(), handlerInCallerPc.rawValue()); - decipher(handlerInCallerPc.rawValue()); - printf(")\n"); + StubUtil.printf("handler for exception %p at return address %p is at %p (", exceptionOop.rawValue(), returnAddress.rawValue(), handlerInCallerPc.rawValue()); + StubUtil.decipher(handlerInCallerPc.rawValue()); + StubUtil.printf(")\n"); } jumpToExceptionHandlerInCaller(handlerInCallerPc, exception, returnAddress); @@ -96,7 +96,7 @@ return enabled || graalRuntime().getConfig().cAssertions; } - public static final Descriptor EXCEPTION_HANDLER_FOR_RETURN_ADDRESS = descriptorFor(UnwindExceptionToCallerStub.class, "exceptionHandlerForReturnAddress", false); + public static final Descriptor EXCEPTION_HANDLER_FOR_RETURN_ADDRESS = StubUtil.descriptorFor(UnwindExceptionToCallerStub.class, "exceptionHandlerForReturnAddress", false); @NodeIntrinsic(value = CRuntimeCall.class, setStampFromReturnType = true) public static native Word exceptionHandlerForReturnAddress(@ConstantNodeParameter Descriptor exceptionHandlerForReturnAddress, Word thread, Word returnAddress); diff -r 87eafaddf9d9 -r bce1c7759d9d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/VMErrorStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/VMErrorStub.java Wed May 08 18:05:57 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/VMErrorStub.java Thu May 09 11:32:08 2013 +0200 @@ -49,7 +49,7 @@ vmErrorC(VM_ERROR_C, thread(), where, format, value); } - public static final Descriptor VM_ERROR_C = descriptorFor(VMErrorStub.class, "vmErrorC", false); + public static final Descriptor VM_ERROR_C = StubUtil.descriptorFor(VMErrorStub.class, "vmErrorC", false); @NodeIntrinsic(CRuntimeCall.class) public static native void vmErrorC(@ConstantNodeParameter Descriptor vmErrorC, Word thread, String where, String format, long value); diff -r 87eafaddf9d9 -r bce1c7759d9d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/VerifyOopStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/VerifyOopStub.java Wed May 08 18:05:57 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/VerifyOopStub.java Thu May 09 11:32:08 2013 +0200 @@ -40,6 +40,6 @@ @Snippet private static Object verifyOop(Object object) { - return verifyObject(object); + return StubUtil.verifyObject(object); } } diff -r 87eafaddf9d9 -r bce1c7759d9d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/WriteBarrierPostStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/WriteBarrierPostStub.java Wed May 08 18:05:57 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/WriteBarrierPostStub.java Thu May 09 11:32:08 2013 +0200 @@ -49,7 +49,7 @@ writeBarrierPostC(WRITE_BARRIER_POST_C, thread(), object, card); } - public static final Descriptor WRITE_BARRIER_POST_C = descriptorFor(WriteBarrierPostStub.class, "writeBarrierPostC", false); + public static final Descriptor WRITE_BARRIER_POST_C = StubUtil.descriptorFor(WriteBarrierPostStub.class, "writeBarrierPostC", false); @NodeIntrinsic(CRuntimeCall.class) public static native void writeBarrierPostC(@ConstantNodeParameter Descriptor vmErrorC, Word thread, Object object, Word card); diff -r 87eafaddf9d9 -r bce1c7759d9d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/WriteBarrierPreStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/WriteBarrierPreStub.java Wed May 08 18:05:57 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/WriteBarrierPreStub.java Thu May 09 11:32:08 2013 +0200 @@ -49,7 +49,7 @@ writeBarrierPreC(WRITE_BARRIER_PRE_C, thread(), object); } - public static final Descriptor WRITE_BARRIER_PRE_C = descriptorFor(WriteBarrierPreStub.class, "writeBarrierPreC", false); + public static final Descriptor WRITE_BARRIER_PRE_C = StubUtil.descriptorFor(WriteBarrierPreStub.class, "writeBarrierPreC", false); @NodeIntrinsic(CRuntimeCall.class) public static native void writeBarrierPreC(@ConstantNodeParameter Descriptor vmErrorC, Word thread, Object object); diff -r 87eafaddf9d9 -r bce1c7759d9d graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/TargetMethodAssembler.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/TargetMethodAssembler.java Wed May 08 18:05:57 2013 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/TargetMethodAssembler.java Thu May 09 11:32:08 2013 +0200 @@ -33,6 +33,7 @@ import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; import com.oracle.graal.lir.*; +import com.oracle.graal.nodes.*; public class TargetMethodAssembler { @@ -88,7 +89,7 @@ compilationResult.addAnnotation(new CompilationResult.CodeComment(asm.codeBuffer.position(), s)); } - public CompilationResult finishTargetMethod(Object name, boolean isStub) { + public CompilationResult finishTargetMethod(StructuredGraph graph) { // Install code, data and frame size compilationResult.setTargetCode(asm.codeBuffer.close(false), asm.codeBuffer.position()); @@ -117,7 +118,7 @@ Debug.metric("DataPatches").add(ldp.size()); Debug.metric("ExceptionHandlersEmitted").add(compilationResult.getExceptionHandlers().size()); } - Debug.log("Finished target method %s, isStub %b", name, isStub); + Debug.log("Finished compiling %s", graph); return compilationResult; } diff -r 87eafaddf9d9 -r bce1c7759d9d graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java Wed May 08 18:05:57 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java Thu May 09 11:32:08 2013 +0200 @@ -106,6 +106,11 @@ return start; } + /** + * Gets the method from which this graph was built. + * + * @return null if this method was not built from a method or the method is not available + */ public ResolvedJavaMethod method() { return method; } diff -r 87eafaddf9d9 -r bce1c7759d9d graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadMethodNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadMethodNode.java Wed May 08 18:05:57 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadMethodNode.java Thu May 09 11:32:08 2013 +0200 @@ -47,6 +47,7 @@ this.method = method; assert !Modifier.isAbstract(method.getModifiers()) : "Cannot load abstract method from a hub"; assert !Modifier.isStatic(method.getModifiers()) : "Cannot load a static method from a hub"; + assert method.isInVirtualMethodTable(); } @Override diff -r 87eafaddf9d9 -r bce1c7759d9d graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Wed May 08 18:05:57 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Thu May 09 11:32:08 2013 +0200 @@ -640,7 +640,6 @@ assert concretes.size() > 0; Debug.log("Method check cascade with %d methods", concretes.size()); - LoadMethodNode[] methods = new LoadMethodNode[concretes.size()]; ValueNode[] constantMethods = new ValueNode[concretes.size()]; double[] probability = new double[concretes.size()]; for (int i = 0; i < concretes.size(); ++i) { @@ -665,8 +664,7 @@ FixedNode lastSucc = successors[concretes.size()]; for (int i = concretes.size() - 1; i >= 0; --i) { LoadMethodNode method = graph.add(new LoadMethodNode(concretes.get(i), hub, constantMethods[i].kind())); - methods[i] = method; - CompareNode methodCheck = CompareNode.createCompareNode(Condition.EQ, methods[i], constantMethods[i]); + CompareNode methodCheck = CompareNode.createCompareNode(Condition.EQ, method, constantMethods[i]); IfNode ifNode = graph.add(new IfNode(methodCheck, successors[i], lastSucc, probability[i])); method.setNext(ifNode); lastSucc = method; @@ -698,6 +696,12 @@ } private boolean chooseMethodDispatch() { + for (ResolvedJavaMethod concrete : concretes) { + if (!concrete.isInVirtualMethodTable()) { + return false; + } + } + if (concretes.size() == 1 && this.notRecordedTypeProbability > 0) { // Always chose method dispatch if there is a single concrete method and the call // site is megamorphic. diff -r 87eafaddf9d9 -r bce1c7759d9d graal/com.oracle.graal.printer/src/com/oracle/graal/printer/GraphPrinterDumpHandler.java --- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/GraphPrinterDumpHandler.java Wed May 08 18:05:57 2013 +0200 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/GraphPrinterDumpHandler.java Thu May 09 11:32:08 2013 +0200 @@ -30,6 +30,7 @@ import java.util.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.*; import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; import com.oracle.graal.phases.*; @@ -181,8 +182,8 @@ private static List getInlineContext() { List result = new ArrayList<>(); for (Object o : Debug.context()) { - if (o instanceof ResolvedJavaMethod) { - ResolvedJavaMethod method = (ResolvedJavaMethod) o; + JavaMethod method = GraalDebugConfig.asJavaMethod(o); + if (method != null) { result.add(MetaUtil.format("%H::%n(%p)", method)); } else if (o instanceof DebugDumpScope) { DebugDumpScope debugDumpScope = (DebugDumpScope) o; diff -r 87eafaddf9d9 -r bce1c7759d9d graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/AbstractTest.java --- a/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/AbstractTest.java Wed May 08 18:05:57 2013 +0200 +++ b/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/AbstractTest.java Thu May 09 11:32:08 2013 +0200 @@ -49,7 +49,7 @@ return result.toString(); } - protected void executeSL(String[] input, String[] expectedOutput, boolean useConsole) { + protected static void executeSL(String[] input, String[] expectedOutput, boolean useConsole) { InputStream in = new ByteArrayInputStream(concat(input).getBytes()); ByteArrayOutputStream out = new ByteArrayOutputStream(); diff -r 87eafaddf9d9 -r bce1c7759d9d src/share/vm/graal/graalCompilerToVM.cpp --- a/src/share/vm/graal/graalCompilerToVM.cpp Wed May 08 18:05:57 2013 +0200 +++ b/src/share/vm/graal/graalCompilerToVM.cpp Thu May 09 11:32:08 2013 +0200 @@ -1001,6 +1001,7 @@ Method* method = asMethod(metaspace_method); assert(!InstanceKlass::cast(method->method_holder())->is_interface(), "vtableEntryOffset cannot be called for interface methods"); assert(InstanceKlass::cast(method->method_holder())->is_linked(), "vtableEntryOffset cannot be called is holder is not linked"); + assert(method->vtable_index() >= 0, "vtable entry offset should not be used"); // get entry offset in words int vtable_entry_offset = InstanceKlass::vtable_start_offset() + method->vtable_index() * vtableEntry::size(); @@ -1010,6 +1011,11 @@ return vtable_entry_offset; C2V_END +C2V_VMENTRY(jboolean, hasVtableEntry, (JNIEnv *, jobject, jlong metaspace_method)) + Method* method = asMethod(metaspace_method); + return method->vtable_index() >= 0; +C2V_END + C2V_VMENTRY(jobject, getDeoptedLeafGraphIds, (JNIEnv *, jobject)) // the contract for this method is as follows: @@ -1177,6 +1183,7 @@ {CC"getInvocationCount", CC"("METASPACE_METHOD")I", FN_PTR(getInvocationCount)}, {CC"getCompiledCodeSize", CC"("METASPACE_METHOD")I", FN_PTR(getCompiledCodeSize)}, {CC"getVtableEntryOffset", CC"("METASPACE_METHOD")I", FN_PTR(getVtableEntryOffset)}, + {CC"hasVtableEntry", CC"("METASPACE_METHOD")Z", FN_PTR(hasVtableEntry)}, {CC"constantPoolLength", CC"("HS_RESOLVED_TYPE")I", FN_PTR(constantPoolLength)}, {CC"lookupType", CC"("STRING HS_RESOLVED_TYPE"Z)"TYPE, FN_PTR(lookupType)}, {CC"lookupConstantInPool", CC"("HS_RESOLVED_TYPE"I)"OBJECT, FN_PTR(lookupConstantInPool)},