# HG changeset patch # User Lukas Stadler # Date 1364482840 -3600 # Node ID 8cb3984da2f8efcc403b5342f5f03cd2da2d3a06 # Parent af0c1352f969b7e33623a7a6af7347c470dc7548# Parent 88610e3ca2366c5cd50f75ad234e6879134df677 Merge diff -r af0c1352f969 -r 8cb3984da2f8 graal/com.oracle.graal.api.runtime/src/com/oracle/graal/api/runtime/ServiceProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.api.runtime/src/com/oracle/graal/api/runtime/ServiceProvider.java Thu Mar 28 16:00:40 2013 +0100 @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.api.runtime; + +import java.lang.annotation.*; + +@Retention(RetentionPolicy.SOURCE) +@Target(ElementType.TYPE) +public @interface ServiceProvider { + + Class value(); +} diff -r af0c1352f969 -r 8cb3984da2f8 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/DegeneratedLoopsTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/DegeneratedLoopsTest.java Thu Mar 28 15:57:51 2013 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/DegeneratedLoopsTest.java Thu Mar 28 16:00:40 2013 +0100 @@ -27,6 +27,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.debug.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; /** @@ -80,13 +81,11 @@ public void run() { StructuredGraph graph = parse(snippet); + new InliningPhase(runtime(), null, new Assumptions(false), null, getDefaultPhasePlan(), OptimisticOptimizations.ALL).apply(graph); + new CanonicalizerPhase(runtime(), new Assumptions(false)).apply(graph); Debug.dump(graph, "Graph"); - for (Invoke invoke : graph.getInvokes()) { - invoke.intrinsify(null); - } - new CanonicalizerPhase(runtime(), new Assumptions(false)).apply(graph); StructuredGraph referenceGraph = parse(REFERENCE_SNIPPET); - Debug.dump(referenceGraph, "Graph"); + Debug.dump(referenceGraph, "ReferenceGraph"); assertEquals(referenceGraph, graph); } }); diff -r af0c1352f969 -r 8cb3984da2f8 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraphScheduleTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraphScheduleTest.java Thu Mar 28 15:57:51 2013 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraphScheduleTest.java Thu Mar 28 16:00:40 2013 +0100 @@ -47,11 +47,11 @@ Block block = bBlock; while (block != null) { if (block == aBlock) { - break; + return; } block = block.getDominator(); } - Assert.assertSame(block, aBlock); + Assert.fail("block of A doesn't dominate the block of B"); } } } diff -r af0c1352f969 -r 8cb3984da2f8 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReadAfterCheckCast.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReadAfterCheckCast.java Thu Mar 28 16:00:40 2013 +0100 @@ -0,0 +1,130 @@ +/* + * 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.compiler.test; + +import java.util.*; + +import org.junit.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.debug.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.phases.common.*; + +/* consider + * B b = (B) a; + * return b.x10; + * + * With snippets a typecheck is performed and if it was successful, a UnsafeCastNode is created. + * For the read node, however, there is only a dependency to the UnsafeCastNode, but not to the + * typecheck itself. With special crafting, it's possible to get the scheduler moving the + * FloatingReadNode before the typecheck. Assuming the object is of the wrong type (here for + * example A), an invalid field read is done. + * + * In order to avoid this situation, an anchor node is introduced in CheckCastSnippts. + */ + +public class ReadAfterCheckCast extends GraphScheduleTest { + + public static long foo = 0; + + public static class A { + + public long x1; + } + + public static class B extends A { + + public long x10; + } + + public static long test1Snippet(A a) { + if (foo > 4) { + B b = (B) a; + b.x10 += 1; + return b.x10; + } else { + B b = (B) a; + b.x10 += 1; + return b.x10; + } + } + + @Test + public void test1() { + test("test1Snippet"); + } + + private void test(final String snippet) { + Debug.scope("FloatingReadTest", new DebugDumpScope(snippet), new Runnable() { + + // check shape of graph, with lots of assumptions. will probably fail if graph + // structure changes significantly + public void run() { + StructuredGraph graph = parse(snippet); + new LoweringPhase(null, runtime(), new Assumptions(false)).apply(graph); + new FloatingReadPhase().apply(graph); + new EliminatePartiallyRedundantGuardsPhase(true, false).apply(graph); + new ReadEliminationPhase().apply(graph); + new CanonicalizerPhase(runtime(), null).apply(graph); + + Debug.dump(graph, "After lowering"); + + ArrayList merges = new ArrayList<>(); + ArrayList reads = new ArrayList<>(); + for (Node n : graph.getNodes()) { + if (n instanceof MergeNode) { + // check shape + MergeNode merge = (MergeNode) n; + + if (merge.inputs().count() == 2) { + for (EndNode m : merge.forwardEnds()) { + if (m.predecessor() != null && m.predecessor() instanceof BeginNode && m.predecessor().predecessor() instanceof IfNode) { + IfNode o = (IfNode) m.predecessor().predecessor(); + if (o.falseSuccessor().next() instanceof DeoptimizeNode) { + merges.add(merge); + } + } + } + } + } + if (n instanceof IntegerAddNode) { + IntegerAddNode ian = (IntegerAddNode) n; + + Assert.assertTrue(ian.y() instanceof ConstantNode); + Assert.assertTrue(ian.x() instanceof FloatingReadNode); + reads.add((FloatingReadNode) ian.x()); + } + } + + Assert.assertTrue(merges.size() >= reads.size()); + for (int i = 0; i < reads.size(); i++) { + assertOrderedAfterSchedule(graph, merges.get(i), reads.get(i)); + } + } + }); + } +} diff -r af0c1352f969 -r 8cb3984da2f8 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 Thu Mar 28 15:57:51 2013 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Thu Mar 28 16:00:40 2013 +0100 @@ -204,6 +204,10 @@ new EliminatePartiallyRedundantGuardsPhase(true, true).apply(graph); } + if (GraalOptions.OptCanonicalizer) { + new CanonicalizerPhase(runtime, assumptions).apply(graph); + } + plan.runPhases(PhasePosition.MID_LEVEL, graph); plan.runPhases(PhasePosition.LOW_LEVEL, graph); diff -r af0c1352f969 -r 8cb3984da2f8 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 Thu Mar 28 15:57:51 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Thu Mar 28 16:00:40 2013 +0100 @@ -88,6 +88,10 @@ return inProgress; } + public boolean isCancelled() { + return cancelled; + } + public int getEntryBCI() { return entryBCI; } @@ -106,10 +110,11 @@ } } runCompilation(); - if (method.currentTask() == this && entryBCI == StructuredGraph.INVOCATION_ENTRY_BCI) { + } finally { + if (method.currentTask() == this) { method.setCurrentTask(null); } - } finally { + graalRuntime.getCompilerToVM().clearQueuedForCompilation(method); inProgress = false; withinEnqueue.set(Boolean.TRUE); } diff -r af0c1352f969 -r 8cb3984da2f8 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 Thu Mar 28 15:57:51 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java Thu Mar 28 16:00:40 2013 +0100 @@ -212,4 +212,6 @@ Local[] getLocalVariableTable(HotSpotResolvedJavaMethod method); String getFileName(HotSpotResolvedJavaType method); + + void clearQueuedForCompilation(HotSpotResolvedJavaMethod method); } diff -r af0c1352f969 -r 8cb3984da2f8 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 Thu Mar 28 15:57:51 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java Thu Mar 28 16:00:40 2013 +0100 @@ -152,4 +152,7 @@ @Override public native String getFileName(HotSpotResolvedJavaType method); + + @Override + public native void clearQueuedForCompilation(HotSpotResolvedJavaMethod method); } diff -r af0c1352f969 -r 8cb3984da2f8 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Thu Mar 28 15:57:51 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Thu Mar 28 16:00:40 2013 +0100 @@ -535,7 +535,7 @@ if (osrCompilation && bootstrapRunning) { // no OSR compilations during bootstrap - the compiler is just too slow at this point, // and we know that there are no endless loops - return current != null; + return current != null && (current.isInProgress() || !current.isCancelled()); } if (CompilationTask.withinEnqueue.get()) { @@ -543,7 +543,7 @@ // java.util.concurrent.BlockingQueue is used to implement the compilation worker // queues. If a compiler thread triggers a compilation, then it may be blocked trying // to add something to its own queue. - return current != null; + return current != null && (current.isInProgress() || !current.isCancelled()); } CompilationTask.withinEnqueue.set(Boolean.TRUE); @@ -560,7 +560,7 @@ // normally compilation tasks will only be re-queued when they get a // priority boost, so cancel the old task and add a new one current.cancel(); - } else { + } else if (!current.isCancelled()) { // without a prioritizing compile queue it makes no sense to re-queue the // compilation task return true; diff -r af0c1352f969 -r 8cb3984da2f8 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 Thu Mar 28 15:57:51 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Thu Mar 28 16:00:40 2013 +0100 @@ -568,9 +568,6 @@ graph.addAfterFixed(metaspaceMethod, compiledEntry); } } - } else if (callTarget.invokeKind() == InvokeKind.Special || callTarget.invokeKind() == InvokeKind.Static) { - loweredCallTarget = graph.add(new HotSpotDirectCallTargetNode(parameters, invoke.node().stamp(), signature, callTarget.targetMethod(), CallingConvention.Type.JavaCall, - callTarget.invokeKind())); } if (loweredCallTarget == null) { @@ -613,18 +610,12 @@ FixedWithNextNode first = memoryWrite; if (field.getKind() == Kind.Object && !memoryWrite.value().objectStamp().alwaysNull()) { - if (config.useG1GC) { - WriteBarrierPre writeBarrierPre = graph.add(new WriteBarrierPre(memoryWrite.object(), null, memoryWrite.location(), true)); - WriteBarrierPost writeBarrierPost = graph.add(new WriteBarrierPost(memoryWrite.object(), memoryWrite.value(), memoryWrite.location(), false)); - graph.addBeforeFixed(memoryWrite, writeBarrierPre); - graph.addAfterFixed(memoryWrite, writeBarrierPost); - first = writeBarrierPre; - last = writeBarrierPost; - } else { - FieldWriteBarrier writeBarrier = graph.add(new FieldWriteBarrier(memoryWrite.object())); - graph.addAfterFixed(memoryWrite, writeBarrier); - last = writeBarrier; - } + WriteBarrierPre writeBarrierPre = graph.add(new WriteBarrierPre(memoryWrite.object(), null, memoryWrite.location(), true)); + WriteBarrierPost writeBarrierPost = graph.add(new WriteBarrierPost(memoryWrite.object(), memoryWrite.value(), memoryWrite.location(), false)); + graph.addBeforeFixed(memoryWrite, writeBarrierPre); + graph.addAfterFixed(memoryWrite, writeBarrierPost); + first = writeBarrierPre; + last = writeBarrierPost; } if (storeField.isVolatile()) { MembarNode preMembar = graph.add(new MembarNode(JMM_PRE_VOLATILE_WRITE)); @@ -639,25 +630,14 @@ LocationNode location = IndexedLocationNode.create(LocationNode.ANY_LOCATION, cas.expected().kind(), cas.displacement(), cas.offset(), graph, 1); if (expected.kind() == Kind.Object && !cas.newValue().objectStamp().alwaysNull()) { ResolvedJavaType type = cas.object().objectStamp().type(); + WriteBarrierPre writeBarrierPre = graph.add(new WriteBarrierPre(cas.object(), null, location, true)); + graph.addBeforeFixed(cas, writeBarrierPre); if (type != null && !type.isArray() && !MetaUtil.isJavaLangObject(type)) { - // Use a field write barrier since it's not an array store - if (config.useG1GC) { - WriteBarrierPre writeBarrierPre = graph.add(new WriteBarrierPre(cas.object(), null, location, true)); - WriteBarrierPost writeBarrierPost = graph.add(new WriteBarrierPost(cas.object(), cas.newValue(), location, false)); - graph.addBeforeFixed(cas, writeBarrierPre); - graph.addAfterFixed(cas, writeBarrierPost); - } else { - graph.addAfterFixed(cas, graph.add(new FieldWriteBarrier(cas.object()))); - } + WriteBarrierPost writeBarrierPost = graph.add(new WriteBarrierPost(cas.object(), cas.newValue(), location, false)); + graph.addAfterFixed(cas, writeBarrierPost); } else { - // This may be an array store so use an array write barrier - if (config.useG1GC) { - WriteBarrierPre writeBarrierPre = graph.add(new WriteBarrierPre(cas.object(), null, location, true)); - graph.addBeforeFixed(cas, writeBarrierPre); - graph.addAfterFixed(cas, graph.add(new WriteBarrierPost(cas.object(), cas.newValue(), location, true))); - } else { - graph.addAfterFixed(cas, graph.add(new ArrayWriteBarrier(cas.object(), location))); - } + WriteBarrierPost writeBarrierPost = graph.add(new WriteBarrierPost(cas.object(), cas.newValue(), location, true)); + graph.addAfterFixed(cas, writeBarrierPost); } } } else if (n instanceof LoadIndexedNode) { @@ -701,14 +681,10 @@ graph.replaceFixedWithFixed(storeIndexed, memoryWrite); if (elementKind == Kind.Object && !value.objectStamp().alwaysNull()) { - if (config.useG1GC) { - WriteBarrierPre writeBarrierPre = graph.add(new WriteBarrierPre(array, null, arrayLocation, true)); - graph.addBeforeFixed(memoryWrite, writeBarrierPre); - WriteBarrierPost writeBarrierPost = graph.add(new WriteBarrierPost(array, value, arrayLocation, true)); - graph.addAfterFixed(memoryWrite, writeBarrierPost); - } else { - graph.addAfterFixed(memoryWrite, graph.add(new ArrayWriteBarrier(array, arrayLocation))); - } + WriteBarrierPre writeBarrierPre = graph.add(new WriteBarrierPre(array, null, arrayLocation, true)); + graph.addBeforeFixed(memoryWrite, writeBarrierPre); + WriteBarrierPost writeBarrierPost = graph.add(new WriteBarrierPost(array, value, arrayLocation, true)); + graph.addAfterFixed(memoryWrite, writeBarrierPost); } } else if (n instanceof UnsafeLoadNode) { UnsafeLoadNode load = (UnsafeLoadNode) n; @@ -728,25 +704,12 @@ graph.replaceFixedWithFixed(store, write); if (write.value().kind() == Kind.Object && !write.value().objectStamp().alwaysNull()) { ResolvedJavaType type = object.objectStamp().type(); - // WriteBarrier writeBarrier; + WriteBarrierPre writeBarrierPre = new WriteBarrierPre(object, null, location, true); + graph.addBeforeFixed(write, graph.add(writeBarrierPre)); if (type != null && !type.isArray() && !MetaUtil.isJavaLangObject(type)) { - // Use a field write barrier since it's not an array store - if (config.useG1GC) { - WriteBarrierPre writeBarrierPre = new WriteBarrierPre(object, null, location, true); - graph.addBeforeFixed(write, graph.add(writeBarrierPre)); - graph.addAfterFixed(write, graph.add(new WriteBarrierPost(object, write.value(), location, false))); - } else { - graph.addAfterFixed(write, graph.add(new FieldWriteBarrier(object))); - } + graph.addAfterFixed(write, graph.add(new WriteBarrierPost(object, write.value(), location, false))); } else { - // This may be an array store so use an array write barrier - if (config.useG1GC) { - WriteBarrierPre writeBarrierPre = graph.add(new WriteBarrierPre(object, null, location, true)); - graph.addBeforeFixed(write, writeBarrierPre); - graph.addAfterFixed(write, graph.add(new WriteBarrierPost(object, write.value(), location, true))); - } else { - graph.addAfterFixed(write, graph.add(new ArrayWriteBarrier(object, location))); - } + graph.addAfterFixed(write, graph.add(new WriteBarrierPost(object, write.value(), location, true))); } } } else if (n instanceof LoadHubNode) { @@ -779,14 +742,12 @@ monitorSnippets.lower((MonitorEnterNode) n, tool); } else if (n instanceof MonitorExitNode) { monitorSnippets.lower((MonitorExitNode) n, tool); - } else if (n instanceof FieldWriteBarrier) { - writeBarrierSnippets.lower((FieldWriteBarrier) n, tool); - } else if (n instanceof ArrayWriteBarrier) { - writeBarrierSnippets.lower((ArrayWriteBarrier) n, tool); - } else if (n instanceof WriteBarrierPre) { - writeBarrierSnippets.lower((WriteBarrierPre) n, tool); - } else if (n instanceof WriteBarrierPost) { - writeBarrierSnippets.lower((WriteBarrierPost) n, tool); + } else if (n instanceof SerialWriteBarrierPost) { + writeBarrierSnippets.lower((SerialWriteBarrierPost) n, tool); + } else if (n instanceof G1WriteBarrierPre) { + writeBarrierSnippets.lower((G1WriteBarrierPre) n, tool); + } else if (n instanceof G1WriteBarrierPost) { + writeBarrierSnippets.lower((G1WriteBarrierPost) n, tool); } else if (n instanceof TLABAllocateNode) { newObjectSnippets.lower((TLABAllocateNode) n, tool); } else if (n instanceof InitializeObjectNode) { diff -r af0c1352f969 -r 8cb3984da2f8 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ArrayWriteBarrier.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ArrayWriteBarrier.java Thu Mar 28 15:57:51 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.hotspot.nodes; - -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; - -public final class ArrayWriteBarrier extends FixedWithNextNode implements Lowerable { - - @Input private ValueNode object; - @Input private LocationNode location; - - public ValueNode getObject() { - return object; - } - - public LocationNode getLocation() { - return location; - } - - public ArrayWriteBarrier(ValueNode object, LocationNode location) { - super(StampFactory.forVoid()); - this.object = object; - this.location = location; - } - - public void lower(LoweringTool generator) { - generator.getRuntime().lower(this, generator); - } -} diff -r af0c1352f969 -r 8cb3984da2f8 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/FieldWriteBarrier.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/FieldWriteBarrier.java Thu Mar 28 15:57:51 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.hotspot.nodes; - -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; - -public final class FieldWriteBarrier extends FixedWithNextNode implements Lowerable { - - @Input private ValueNode object; - - public ValueNode getObject() { - return object; - } - - public FieldWriteBarrier(ValueNode object) { - super(StampFactory.forVoid()); - this.object = object; - } - - public void lower(LoweringTool generator) { - generator.getRuntime().lower(this, generator); - } -} diff -r af0c1352f969 -r 8cb3984da2f8 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/G1WriteBarrierPost.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/G1WriteBarrierPost.java Thu Mar 28 16:00:40 2013 +0100 @@ -0,0 +1,69 @@ +/* + * 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.nodes; + +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.spi.*; + +public class G1WriteBarrierPost extends WriteBarrierPost implements Lowerable { + + @Input private ValueNode object; + @Input private ValueNode value; + @Input private LocationNode location; + private final boolean precise; + + @Override + public ValueNode getObject() { + return object; + } + + @Override + public ValueNode getValue() { + return value; + } + + @Override + public LocationNode getLocation() { + return location; + } + + @Override + public boolean usePrecise() { + return precise; + } + + public G1WriteBarrierPost(ValueNode object, ValueNode value, LocationNode location, boolean precise) { + this.object = object; + this.value = value; + this.location = location; + this.precise = precise; + } + + @Override + public void lower(LoweringTool generator) { + generator.getRuntime().lower(this, generator); + } + +} diff -r af0c1352f969 -r 8cb3984da2f8 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/G1WriteBarrierPre.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/G1WriteBarrierPre.java Thu Mar 28 16:00:40 2013 +0100 @@ -0,0 +1,69 @@ +/* + * 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.nodes; + +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.spi.*; + +public final class G1WriteBarrierPre extends WriteBarrierPre implements Lowerable { + + @Input private ValueNode object; + @Input private LocationNode location; + @Input private ValueNode expectedObject; + private final boolean doLoad; + + @Override + public ValueNode getObject() { + return object; + } + + @Override + public ValueNode getExpectedObject() { + return expectedObject; + } + + @Override + public boolean doLoad() { + return doLoad; + } + + @Override + public LocationNode getLocation() { + return location; + } + + public G1WriteBarrierPre(ValueNode object, ValueNode expectedObject, LocationNode location, boolean doLoad) { + this.object = object; + this.doLoad = doLoad; + this.location = location; + this.expectedObject = expectedObject; + } + + @Override + public void lower(LoweringTool generator) { + generator.getRuntime().lower(this, generator); + } + +} diff -r af0c1352f969 -r 8cb3984da2f8 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/SerialWriteBarrierPost.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/SerialWriteBarrierPost.java Thu Mar 28 16:00:40 2013 +0100 @@ -0,0 +1,62 @@ +/* + * 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.nodes; + +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.spi.*; + +public class SerialWriteBarrierPost extends WriteBarrierPost implements Lowerable { + + @Input private ValueNode object; + @Input private LocationNode location; + private final boolean usePrecise; + + public SerialWriteBarrierPost(ValueNode object, LocationNode location, boolean usePrecise) { + this.object = object; + this.location = location; + this.usePrecise = usePrecise; + } + + @Override + public ValueNode getObject() { + return object; + } + + @Override + public LocationNode getLocation() { + return location; + } + + @Override + public boolean usePrecise() { + return usePrecise; + } + + @Override + public void lower(LoweringTool generator) { + generator.getRuntime().lower(this, generator); + } + +} diff -r af0c1352f969 -r 8cb3984da2f8 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrierPost.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrierPost.java Thu Mar 28 15:57:51 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrierPost.java Thu Mar 28 16:00:40 2013 +0100 @@ -22,15 +22,18 @@ */ package com.oracle.graal.hotspot.nodes; +import static com.oracle.graal.hotspot.replacements.HotSpotSnippetUtils.*; + +import com.oracle.graal.api.meta.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; -public final class WriteBarrierPost extends FixedWithNextNode implements Lowerable { +public class WriteBarrierPost extends WriteBarrier implements Lowerable { @Input private ValueNode object; @Input private ValueNode value; + @Input private ValueNode index; @Input private LocationNode location; private final boolean precise; @@ -50,15 +53,45 @@ return precise; } + public WriteBarrierPost() { + this.precise = false; + } + + public WriteBarrierPost(ValueNode object, ValueNode value, ValueNode index) { + this.object = object; + this.value = value; + this.index = index; + this.precise = true; + this.location = null; + } + public WriteBarrierPost(ValueNode object, ValueNode value, LocationNode location, boolean precise) { - super(StampFactory.forVoid()); this.object = object; this.value = value; this.location = location; this.precise = precise; } + @Override public void lower(LoweringTool generator) { - generator.getRuntime().lower(this, generator); + StructuredGraph graph = (StructuredGraph) this.graph(); + if (location == null) { // Come from array copy intrinsic + LocationNode arrayLocation = IndexedLocationNode.create(LocationNode.getArrayLocation(Kind.Object), Kind.Object, arrayBaseOffset(Kind.Object), index, graph, arrayIndexScale(Kind.Object)); + if (useG1GC()) { + graph.replaceFixedWithFixed(this, graph().add(new G1WriteBarrierPost(object, value, arrayLocation, true))); + } else { + graph.replaceFixedWithFixed(this, graph().add(new SerialWriteBarrierPost(object, arrayLocation, true))); + } + } else { // Normal WriteBarrier + assert location != null; + if (useG1GC()) { + graph.replaceFixedWithFixed(this, graph().add(new G1WriteBarrierPost(object, value, location, precise))); + } else { + graph.replaceFixedWithFixed(this, graph().add(new SerialWriteBarrierPost(object, location, precise))); + } + } } + + @NodeIntrinsic + public static native void arrayCopyWriteBarrier(Object array, Object value, long index); } diff -r af0c1352f969 -r 8cb3984da2f8 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrierPre.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrierPre.java Thu Mar 28 15:57:51 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrierPre.java Thu Mar 28 16:00:40 2013 +0100 @@ -22,12 +22,13 @@ */ package com.oracle.graal.hotspot.nodes; +import static com.oracle.graal.hotspot.replacements.HotSpotSnippetUtils.*; + import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; -public final class WriteBarrierPre extends FixedWithNextNode implements Lowerable { +public class WriteBarrierPre extends WriteBarrier implements Lowerable { @Input private ValueNode object; @Input private LocationNode location; @@ -50,16 +51,25 @@ return location; } + public WriteBarrierPre() { + this.doLoad = false; + } + public WriteBarrierPre(ValueNode object, ValueNode expectedObject, LocationNode location, boolean doLoad) { - super(StampFactory.forVoid()); this.object = object; this.doLoad = doLoad; this.location = location; this.expectedObject = expectedObject; } + @Override public void lower(LoweringTool generator) { - generator.getRuntime().lower(this, generator); + StructuredGraph graph = (StructuredGraph) this.graph(); + if (useG1GC()) { + graph.replaceFixedWithFixed(this, graph().add(new G1WriteBarrierPre(getObject(), getExpectedObject(), getLocation(), doLoad()))); + } else { + graph.removeFixed(this); + } } } diff -r af0c1352f969 -r 8cb3984da2f8 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/OnStackReplacementPhase.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/OnStackReplacementPhase.java Thu Mar 28 15:57:51 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/OnStackReplacementPhase.java Thu Mar 28 16:00:40 2013 +0100 @@ -82,8 +82,7 @@ throw new BailoutException("No OnStackReplacementNode generated"); } if (osrNodes.count() > 1) { - // this can happen with JSR inlining - throw new BailoutException("Multiple OnStackReplacementNodes generated"); + throw new GraalInternalError("Multiple OnStackReplacementNodes generated"); } if (osr.stateAfter().locksSize() != 0) { throw new BailoutException("OSR with locks not supported"); diff -r af0c1352f969 -r 8cb3984da2f8 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopySnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopySnippets.java Thu Mar 28 15:57:51 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopySnippets.java Thu Mar 28 16:00:40 2013 +0100 @@ -37,7 +37,7 @@ import com.oracle.graal.nodes.java.*; import com.oracle.graal.phases.*; import com.oracle.graal.replacements.*; -import com.oracle.graal.replacements.Snippet.*; +import com.oracle.graal.replacements.Snippet.ConstantParameter; import com.oracle.graal.replacements.nodes.*; import com.oracle.graal.word.*; @@ -236,9 +236,8 @@ } } - // Does NOT perform store checks @Snippet - public static void arraycopy(Object[] src, int srcPos, Object[] dest, int destPos, int length) { + private static void arrayObjectCopy(Object src, int srcPos, Object dest, int destPos, int length) { objectCounter.inc(); checkNonNull(src); checkNonNull(dest); @@ -247,44 +246,49 @@ int header = arrayBaseOffset(Kind.Object); if (src == dest && srcPos < destPos) { // bad aliased case long start = (long) (length - 1) * scale; + long j = (long) (length) - 1; for (long i = start; i >= 0; i -= scale) { Object a = UnsafeLoadNode.load(src, header, i + (long) srcPos * scale, Kind.Object); DirectObjectStoreNode.storeObject(dest, header, i + (long) destPos * scale, a); + WriteBarrierPost.arrayCopyWriteBarrier(dest, a, j); + j--; } } else { long end = (long) length * scale; + long j = srcPos; for (long i = 0; i < end; i += scale) { Object a = UnsafeLoadNode.load(src, header, i + (long) srcPos * scale, Kind.Object); DirectObjectStoreNode.storeObject(dest, header, i + (long) destPos * scale, a); - } - } - if (length > 0) { - int cardShift = cardTableShift(); - long cardStart = cardTableStart(); - long dstAddr = GetObjectAddressNode.get(dest); - long start = (dstAddr + header + (long) destPos * scale) >>> cardShift; - long end = (dstAddr + header + ((long) destPos + length - 1) * scale) >>> cardShift; - long count = end - start + 1; - while (count-- > 0) { - DirectStoreNode.store((start + cardStart) + count, false, Kind.Boolean); + WriteBarrierPost.arrayCopyWriteBarrier(dest, a, j); + j++; } } } + // Does NOT perform store checks + @Snippet + public static void arraycopy(Object[] src, int srcPos, Object[] dest, int destPos, int length) { + arrayObjectCopy(src, srcPos, dest, destPos, length); + } + @Snippet public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length) { - - // loading the hubs also checks for nullness Word srcHub = loadHub(src); Word destHub = loadHub(dest); - int layoutHelper = checkArrayType(srcHub); + int log2ElementSize = (layoutHelper >> layoutHelperLog2ElementSizeShift()) & layoutHelperLog2ElementSizeMask(); + final boolean isObjectArray = ((layoutHelper & layoutHelperElementTypePrimitiveInPlace()) == 0); if (srcHub.equal(destHub) && src != dest) { probability(FAST_PATH_PROBABILITY); - checkLimits(src, srcPos, dest, destPos, length); - - arraycopyInnerloop(src, srcPos, dest, destPos, length, layoutHelper); + if (isObjectArray) { + genericObjectExactCallCounter.inc(); + probability(FAST_PATH_PROBABILITY); + arrayObjectCopy(src, srcPos, dest, destPos, length); + } else { + genericPrimitiveCallCounter.inc(); + arraycopyInnerloop(src, srcPos, dest, destPos, length, layoutHelper); + } } else { genericObjectCallCounter.inc(); System.arraycopy(src, srcPos, dest, destPos, length); @@ -312,29 +316,11 @@ srcOffset = srcOffset.add(1); } while (destOffset.belowThan(destEnd)) { - destOffset.writeWord(0, srcOffset.readWord(0, UNKNOWN_LOCATION), ANY_LOCATION); + Word word = srcOffset.readWord(0, UNKNOWN_LOCATION); + destOffset.writeWord(0, word, ANY_LOCATION); destOffset = destOffset.add(wordSize()); srcOffset = srcOffset.add(wordSize()); } - - if ((layoutHelper & layoutHelperElementTypePrimitiveInPlace()) != 0) { - genericPrimitiveCallCounter.inc(); - - } else { - probability(LIKELY_PROBABILITY); - genericObjectExactCallCounter.inc(); - - if (length > 0) { - int cardShift = cardTableShift(); - long cardStart = cardTableStart(); - Word destCardOffset = destStart.unsignedShiftRight(cardShift).add(Word.unsigned(cardStart)); - Word destCardEnd = destEnd.subtract(1).unsignedShiftRight(cardShift).add(Word.unsigned(cardStart)); - while (destCardOffset.belowOrEqual(destCardEnd)) { - DirectStoreNode.store(destCardOffset.rawValue(), false, Kind.Boolean); - destCardOffset = destCardOffset.add(1); - } - } - } } private static final SnippetCounter.Group checkCounters = GraalOptions.SnippetCounters ? new SnippetCounter.Group("System.arraycopy checkInputs") : null; diff -r af0c1352f969 -r 8cb3984da2f8 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CheckCastSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CheckCastSnippets.java Thu Mar 28 15:57:51 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CheckCastSnippets.java Thu Mar 28 16:00:40 2013 +0100 @@ -81,7 +81,11 @@ } exactHit.inc(); } - return unsafeCast(verifyOop(object), StampFactory.forNodeIntrinsic()); + /** + * make sure that the unsafeCast is done *after* the check above, + * cf. {@link ReadAfterCheckCast}*/ + BeginNode anchorNode = BeginNode.anchor(StampFactory.forNodeIntrinsic()); + return unsafeCast(verifyOop(object), StampFactory.forNodeIntrinsic(), anchorNode); } /** @@ -109,7 +113,8 @@ } displayHit.inc(); } - return unsafeCast(verifyOop(object), StampFactory.forNodeIntrinsic()); + BeginNode anchorNode = BeginNode.anchor(StampFactory.forNodeIntrinsic()); + return unsafeCast(verifyOop(object), StampFactory.forNodeIntrinsic(), anchorNode); } /** @@ -132,14 +137,16 @@ Word hintHub = hints[i]; if (hintHub.equal(objectHub)) { hintsHit.inc(); - return unsafeCast(verifyOop(object), StampFactory.forNodeIntrinsic()); + BeginNode anchorNode = BeginNode.anchor(StampFactory.forNodeIntrinsic()); + return unsafeCast(verifyOop(object), StampFactory.forNodeIntrinsic(), anchorNode); } } if (!checkSecondarySubType(hub, objectHub)) { DeoptimizeNode.deopt(InvalidateReprofile, ClassCastException); } } - return unsafeCast(verifyOop(object), StampFactory.forNodeIntrinsic()); + BeginNode anchorNode = BeginNode.anchor(StampFactory.forNodeIntrinsic()); + return unsafeCast(verifyOop(object), StampFactory.forNodeIntrinsic(), anchorNode); } /** @@ -160,7 +167,8 @@ DeoptimizeNode.deopt(InvalidateReprofile, ClassCastException); } } - return unsafeCast(verifyOop(object), StampFactory.forNodeIntrinsic()); + BeginNode anchorNode = BeginNode.anchor(StampFactory.forNodeIntrinsic()); + return unsafeCast(verifyOop(object), StampFactory.forNodeIntrinsic(), anchorNode); } // @formatter:on diff -r af0c1352f969 -r 8cb3984da2f8 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java Thu Mar 28 15:57:51 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java Thu Mar 28 16:00:40 2013 +0100 @@ -40,7 +40,7 @@ public class WriteBarrierSnippets implements Snippets { @Snippet - public static void g1PreWriteBarrier(@Parameter("object") Object obj, @Parameter("expectedObject") Object expobj, @Parameter("location") Object location, + public static void g1WriteBarrierPre(@Parameter("object") Object obj, @Parameter("expectedObject") Object expobj, @Parameter("location") Object location, @ConstantParameter("doLoad") boolean doLoad) { Word thread = thread(); Object object = FixedValueAnchorNode.getObject(obj); @@ -48,11 +48,9 @@ Word field = (Word) Word.fromArray(object, location); Word previousOop = (Word) Word.fromObject(expectedObject); byte markingValue = thread.readByte(HotSpotSnippetUtils.g1SATBQueueMarkingOffset()); - Word bufferAddress = thread.readWord(HotSpotSnippetUtils.g1SATBQueueBufferOffset()); Word indexAddress = thread.add(HotSpotSnippetUtils.g1SATBQueueIndexOffset()); Word indexValue = indexAddress.readWord(0); - if (markingValue != (byte) 0) { if (doLoad) { previousOop = field.readWord(0); @@ -65,14 +63,13 @@ indexAddress.writeWord(0, nextIndex); } else { WriteBarrierPreStubCall.call(previousOop); - } } } } @Snippet - public static void g1PostWriteBarrier(@Parameter("object") Object obj, @Parameter("value") Object value, @Parameter("location") Object location, @ConstantParameter("usePrecise") boolean usePrecise) { + public static void g1WriteBarrierPost(@Parameter("object") Object obj, @Parameter("value") Object value, @Parameter("location") Object location, @ConstantParameter("usePrecise") boolean usePrecise) { Word thread = thread(); Object object = FixedValueAnchorNode.getObject(obj); Object wrObject = FixedValueAnchorNode.getObject(value); @@ -99,7 +96,6 @@ cardBase = cardBase.add(Word.unsigned(cardTableStart())); } Word cardAddress = cardBase.add(displacement); - if (xorResult.notEqual(Word.zero())) { if (writtenValue.notEqual(Word.zero())) { byte cardByte = cardAddress.readByte(0); @@ -119,24 +115,14 @@ } @Snippet - public static void serialFieldWriteBarrier(@Parameter("object") Object obj) { + public static void serialWriteBarrierPost(@Parameter("object") Object obj, @Parameter("location") Object location, @ConstantParameter("usePrecise") boolean usePrecise) { Object object = FixedValueAnchorNode.getObject(obj); - Pointer oop = Word.fromObject(object); - Word base = (Word) oop.unsignedShiftRight(cardTableShift()); - long startAddress = cardTableStart(); - int displacement = 0; - if (((int) startAddress) == startAddress) { - displacement = (int) startAddress; + Pointer oop; + if (usePrecise) { + oop = Word.fromArray(object, location); } else { - base = base.add(Word.unsigned(cardTableStart())); + oop = Word.fromObject(object); } - base.writeByte(displacement, (byte) 0); - } - - @Snippet - public static void serialArrayWriteBarrier(@Parameter("object") Object obj, @Parameter("location") Object location) { - Object object = FixedValueAnchorNode.getObject(obj); - Pointer oop = Word.fromArray(object, location); Word base = (Word) oop.unsignedShiftRight(cardTableShift()); long startAddress = cardTableStart(); int displacement = 0; @@ -150,40 +136,30 @@ public static class Templates extends AbstractTemplates { - private final ResolvedJavaMethod serialFieldWriteBarrier; - private final ResolvedJavaMethod serialArrayWriteBarrier; - private final ResolvedJavaMethod g1PreWriteBarrier; - private final ResolvedJavaMethod g1PostWriteBarrier; + private final ResolvedJavaMethod serialWriteBarrierPost; + private final ResolvedJavaMethod g1WriteBarrierPre; + private final ResolvedJavaMethod g1WriteBarrierPost; public Templates(CodeCacheProvider runtime, Assumptions assumptions, TargetDescription target) { super(runtime, assumptions, target, WriteBarrierSnippets.class); - serialFieldWriteBarrier = snippet("serialFieldWriteBarrier", Object.class); - serialArrayWriteBarrier = snippet("serialArrayWriteBarrier", Object.class, Object.class); - g1PreWriteBarrier = snippet("g1PreWriteBarrier", Object.class, Object.class, Object.class, boolean.class); - g1PostWriteBarrier = snippet("g1PostWriteBarrier", Object.class, Object.class, Object.class, boolean.class); + serialWriteBarrierPost = snippet("serialWriteBarrierPost", Object.class, Object.class, boolean.class); + g1WriteBarrierPre = snippet("g1WriteBarrierPre", Object.class, Object.class, Object.class, boolean.class); + g1WriteBarrierPost = snippet("g1WriteBarrierPost", Object.class, Object.class, Object.class, boolean.class); } - public void lower(ArrayWriteBarrier arrayWriteBarrier, @SuppressWarnings("unused") LoweringTool tool) { - ResolvedJavaMethod method = serialArrayWriteBarrier; + public void lower(SerialWriteBarrierPost fieldWriteBarrier, @SuppressWarnings("unused") LoweringTool tool) { + ResolvedJavaMethod method = serialWriteBarrierPost; Key key = new Key(method); - Arguments arguments = new Arguments(); - arguments.add("object", arrayWriteBarrier.getObject()); - arguments.add("location", arrayWriteBarrier.getLocation()); - SnippetTemplate template = cache.get(key, assumptions); - template.instantiate(runtime, arrayWriteBarrier, DEFAULT_REPLACER, arguments); - } - - public void lower(FieldWriteBarrier fieldWriteBarrier, @SuppressWarnings("unused") LoweringTool tool) { - ResolvedJavaMethod method = serialFieldWriteBarrier; - Key key = new Key(method); + key.add("usePrecise", fieldWriteBarrier.usePrecise()); Arguments arguments = new Arguments(); arguments.add("object", fieldWriteBarrier.getObject()); + arguments.add("location", fieldWriteBarrier.getLocation()); SnippetTemplate template = cache.get(key, assumptions); template.instantiate(runtime, fieldWriteBarrier, DEFAULT_REPLACER, arguments); } - public void lower(WriteBarrierPre writeBarrierPre, @SuppressWarnings("unused") LoweringTool tool) { - ResolvedJavaMethod method = g1PreWriteBarrier; + public void lower(G1WriteBarrierPre writeBarrierPre, @SuppressWarnings("unused") LoweringTool tool) { + ResolvedJavaMethod method = g1WriteBarrierPre; Key key = new Key(method); key.add("doLoad", writeBarrierPre.doLoad()); Arguments arguments = new Arguments(); @@ -194,8 +170,8 @@ template.instantiate(runtime, writeBarrierPre, DEFAULT_REPLACER, arguments); } - public void lower(WriteBarrierPost writeBarrierPost, @SuppressWarnings("unused") LoweringTool tool) { - ResolvedJavaMethod method = g1PostWriteBarrier; + public void lower(G1WriteBarrierPost writeBarrierPost, @SuppressWarnings("unused") LoweringTool tool) { + ResolvedJavaMethod method = g1WriteBarrierPost; Key key = new Key(method); key.add("usePrecise", writeBarrierPost.usePrecise()); Arguments arguments = new Arguments(); diff -r af0c1352f969 -r 8cb3984da2f8 graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Thu Mar 28 15:57:51 2013 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Thu Mar 28 16:00:40 2013 +0100 @@ -1688,6 +1688,9 @@ traceState(); traceInstruction(bci, opcode, bci == block.startBci); if (bci == entryBCI) { + if (block.jsrScope != JsrScope.EMPTY_SCOPE) { + throw new BailoutException("OSR into a JSR scope is not supported"); + } EntryMarkerNode x = currentGraph.add(new EntryMarkerNode()); append(x); frameState.insertProxies(x); diff -r af0c1352f969 -r 8cb3984da2f8 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BeginNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BeginNode.java Thu Mar 28 15:57:51 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BeginNode.java Thu Mar 28 16:00:40 2013 +0100 @@ -184,4 +184,7 @@ throw new UnsupportedOperationException(); } } + + @NodeIntrinsic + public static native T anchor(@ConstantNodeParameter Stamp stamp); } diff -r af0c1352f969 -r 8cb3984da2f8 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java Thu Mar 28 15:57:51 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java Thu Mar 28 16:00:40 2013 +0100 @@ -160,20 +160,15 @@ StateSplit stateSplit = (StateSplit) node; stateSplit.setStateAfter(stateAfter); } - if (node == null) { - assert kind() == Kind.Void && usages().isEmpty(); - ((StructuredGraph) graph()).removeFixed(this); + if (node instanceof FixedWithNextNode) { + ((StructuredGraph) graph()).replaceFixedWithFixed(this, (FixedWithNextNode) node); + } else if (node instanceof DeoptimizeNode) { + this.replaceAtPredecessor(node); + this.replaceAtUsages(null); + GraphUtil.killCFG(this); + return; } else { - if (node instanceof FixedWithNextNode) { - ((StructuredGraph) graph()).replaceFixedWithFixed(this, (FixedWithNextNode) node); - } else if (node instanceof DeoptimizeNode) { - this.replaceAtPredecessor(node); - this.replaceAtUsages(null); - GraphUtil.killCFG(this); - return; - } else { - ((StructuredGraph) graph()).replaceFixed(this, node); - } + ((StructuredGraph) graph()).replaceFixed(this, node); } call.safeDelete(); if (stateAfter.usages().isEmpty()) { diff -r af0c1352f969 -r 8cb3984da2f8 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java Thu Mar 28 15:57:51 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java Thu Mar 28 16:00:40 2013 +0100 @@ -44,6 +44,11 @@ this.object = object; } + public UnsafeCastNode(ValueNode object, Stamp stamp, ValueNode anchor) { + super(stamp, anchor); + this.object = object; + } + public UnsafeCastNode(ValueNode object, ResolvedJavaType toType, boolean exactType, boolean nonNull) { this(object, toType.getKind() == Kind.Object ? StampFactory.object(toType, exactType, nonNull || object.stamp().nonNull()) : StampFactory.forKind(toType.getKind())); } @@ -109,6 +114,9 @@ @NodeIntrinsic public static native T unsafeCast(Object object, @ConstantNodeParameter Stamp stamp); + @NodeIntrinsic + public static native T unsafeCast(Object object, @ConstantNodeParameter Stamp stamp, ValueNode anchor); + @SuppressWarnings("unused") @NodeIntrinsic public static T unsafeCast(Object object, @ConstantNodeParameter Class toType, @ConstantNodeParameter boolean exactType, @ConstantNodeParameter boolean nonNull) { diff -r af0c1352f969 -r 8cb3984da2f8 graal/com.oracle.graal.replacements/src/META-INF/services/com.oracle.graal.replacements.ReplacementsProvider --- a/graal/com.oracle.graal.replacements/src/META-INF/services/com.oracle.graal.replacements.ReplacementsProvider Thu Mar 28 15:57:51 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -com.oracle.graal.replacements.GraalMethodSubstitutions diff -r af0c1352f969 -r 8cb3984da2f8 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraalMethodSubstitutions.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraalMethodSubstitutions.java Thu Mar 28 15:57:51 2013 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraalMethodSubstitutions.java Thu Mar 28 16:00:40 2013 +0100 @@ -22,11 +22,13 @@ */ package com.oracle.graal.replacements; +import com.oracle.graal.api.runtime.*; import com.oracle.graal.phases.*; /** * Method substitutions that are VM-independent. */ +@ServiceProvider(ReplacementsProvider.class) public class GraalMethodSubstitutions implements ReplacementsProvider { public void installReplacements(ReplacementsInstaller installer) { diff -r af0c1352f969 -r 8cb3984da2f8 graal/com.oracle.graal.service.processor/src/META-INF/services/javax.annotation.processing.Processor --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.service.processor/src/META-INF/services/javax.annotation.processing.Processor Thu Mar 28 16:00:40 2013 +0100 @@ -0,0 +1,1 @@ +com.oracle.graal.service.processor.ServiceProviderProcessor diff -r af0c1352f969 -r 8cb3984da2f8 graal/com.oracle.graal.service.processor/src/com/oracle/graal/service/processor/ServiceProviderProcessor.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.service.processor/src/com/oracle/graal/service/processor/ServiceProviderProcessor.java Thu Mar 28 16:00:40 2013 +0100 @@ -0,0 +1,107 @@ +/* + * 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.service.processor; + +import java.io.*; +import java.util.*; + +import javax.annotation.processing.*; +import javax.lang.model.*; +import javax.lang.model.element.*; +import javax.lang.model.type.*; +import javax.tools.Diagnostic.Kind; +import javax.tools.*; + +import com.oracle.graal.api.runtime.*; + +@SupportedSourceVersion(SourceVersion.RELEASE_7) +@SupportedAnnotationTypes("com.oracle.graal.api.runtime.ServiceProvider") +public class ServiceProviderProcessor extends AbstractProcessor { + + private Map> serviceMap; + + public ServiceProviderProcessor() { + serviceMap = new HashMap<>(); + } + + private void addProvider(String serviceName, TypeElement serviceProvider) { + Set providers = serviceMap.get(serviceName); + if (providers == null) { + providers = new HashSet<>(); + serviceMap.put(serviceName, providers); + } + providers.add(serviceProvider); + } + + private void generateServicesFiles() { + Filer filer = processingEnv.getFiler(); + for (Map.Entry> entry : serviceMap.entrySet()) { + String filename = "META-INF/services/" + entry.getKey(); + TypeElement[] providers = entry.getValue().toArray(new TypeElement[0]); + try { + FileObject servicesFile = filer.createResource(StandardLocation.CLASS_OUTPUT, "", filename, providers); + PrintWriter writer = new PrintWriter(new OutputStreamWriter(servicesFile.openOutputStream(), "UTF-8")); + for (TypeElement provider : providers) { + writer.println(provider.getQualifiedName()); + } + writer.close(); + } catch (IOException e) { + processingEnv.getMessager().printMessage(Kind.ERROR, e.getMessage()); + } + } + } + + private boolean verifyAnnotation(TypeMirror serviceInterface, TypeElement serviceProvider) { + if (!processingEnv.getTypeUtils().isSubtype(serviceProvider.asType(), serviceInterface)) { + String msg = String.format("Service provider class %s doesn't implement service interface %s", serviceProvider.getSimpleName(), serviceInterface); + processingEnv.getMessager().printMessage(Kind.ERROR, msg, serviceProvider); + return false; + } + + return true; + } + + @Override + public boolean process(Set annotations, RoundEnvironment roundEnv) { + if (roundEnv.processingOver()) { + generateServicesFiles(); + return true; + } + + for (Element element : roundEnv.getElementsAnnotatedWith(ServiceProvider.class)) { + assert element.getKind().isClass(); + ServiceProvider annotation = element.getAnnotation(ServiceProvider.class); + try { + annotation.value(); + } catch (MirroredTypeException ex) { + TypeMirror serviceInterface = ex.getTypeMirror(); + TypeElement serviceProvider = (TypeElement) element; + if (verifyAnnotation(serviceInterface, serviceProvider)) { + String interfaceName = ex.getTypeMirror().toString(); + addProvider(interfaceName, serviceProvider); + } + } + } + return true; + } +} diff -r af0c1352f969 -r 8cb3984da2f8 make/build-graal.xml --- a/make/build-graal.xml Thu Mar 28 15:57:51 2013 +0100 +++ b/make/build-graal.xml Thu Mar 28 16:00:40 2013 +0100 @@ -49,8 +49,8 @@ + - diff -r af0c1352f969 -r 8cb3984da2f8 mx/projects --- a/mx/projects Thu Mar 28 15:57:51 2013 +0100 +++ b/mx/projects Thu Mar 28 16:00:40 2013 +0100 @@ -65,6 +65,13 @@ project@com.oracle.graal.api.replacements@checkstyle=com.oracle.graal.graph project@com.oracle.graal.api.replacements@javaCompliance=1.7 +# graal.service.processor +project@com.oracle.graal.service.processor@subDir=graal +project@com.oracle.graal.service.processor@sourceDirs=src +project@com.oracle.graal.service.processor@dependencies=com.oracle.graal.api.runtime +project@com.oracle.graal.service.processor@checkstyle=com.oracle.graal.graph +project@com.oracle.graal.service.processor@javaCompliance=1.7 + # graal.amd64 project@com.oracle.graal.amd64@subDir=graal project@com.oracle.graal.amd64@sourceDirs=src @@ -89,7 +96,7 @@ # graal.hotspot project@com.oracle.graal.hotspot@subDir=graal project@com.oracle.graal.hotspot@sourceDirs=src -project@com.oracle.graal.hotspot@dependencies=com.oracle.graal.replacements,com.oracle.graal.api.runtime,com.oracle.graal.printer +project@com.oracle.graal.hotspot@dependencies=com.oracle.graal.replacements,com.oracle.graal.printer project@com.oracle.graal.hotspot@checkstyle=com.oracle.graal.graph project@com.oracle.graal.hotspot@annotationProcessors=com.oracle.graal.replacements.verifier project@com.oracle.graal.hotspot@javaCompliance=1.7 @@ -193,10 +200,10 @@ # graal.replacements project@com.oracle.graal.replacements@subDir=graal project@com.oracle.graal.replacements@sourceDirs=src -project@com.oracle.graal.replacements@dependencies=com.oracle.graal.compiler,com.oracle.graal.java,com.oracle.graal.word +project@com.oracle.graal.replacements@dependencies=com.oracle.graal.compiler,com.oracle.graal.java,com.oracle.graal.word,com.oracle.graal.api.runtime project@com.oracle.graal.replacements@checkstyle=com.oracle.graal.graph project@com.oracle.graal.replacements@javaCompliance=1.7 -project@com.oracle.graal.replacements@annotationProcessors=com.oracle.graal.replacements.verifier +project@com.oracle.graal.replacements@annotationProcessors=com.oracle.graal.replacements.verifier,com.oracle.graal.service.processor # graal.replacements.amd64 project@com.oracle.graal.replacements.amd64@subDir=graal diff -r af0c1352f969 -r 8cb3984da2f8 mxtool/mx.py --- a/mxtool/mx.py Thu Mar 28 15:57:51 2013 +0100 +++ b/mxtool/mx.py Thu Mar 28 16:00:40 2013 +0100 @@ -2307,7 +2307,7 @@ launchOut.element('stringAttribute', {'key' : 'org.eclipse.ui.externaltools.ATTR_RUN_BUILD_KINDS', 'value': 'auto,full,incremental'}) launchOut.element('stringAttribute', {'key' : 'org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS', 'value': mxCommand}) launchOut.element('booleanAttribute', {'key' : 'org.eclipse.ui.externaltools.ATTR_TRIGGERS_CONFIGURED','value': 'true'}) - launchOut.element('stringAttribute', {'key' : 'org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY', 'value': baseDir}) + launchOut.element('stringAttribute', {'key' : 'org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY', 'value': p.suite.dir}) launchOut.close('launchConfiguration') diff -r af0c1352f969 -r 8cb3984da2f8 src/share/vm/graal/graalCodeInstaller.cpp --- a/src/share/vm/graal/graalCodeInstaller.cpp Thu Mar 28 15:57:51 2013 +0100 +++ b/src/share/vm/graal/graalCodeInstaller.cpp Thu Mar 28 16:00:40 2013 +0100 @@ -345,8 +345,6 @@ result = GraalEnv::register_method(method, nm, entry_bci, &_offsets, _custom_stack_area_offset, &buffer, stack_slots, _debug_recorder->_oopmaps, &_exception_handler_table, GraalCompiler::instance(), _debug_recorder, _dependencies, NULL, -1, true, false, leaf_graph_ids, installed_code, triggered_deoptimizations); - - method->clear_queued_for_compilation(); } // constructor used to create a stub diff -r af0c1352f969 -r 8cb3984da2f8 src/share/vm/graal/graalCompilerToVM.cpp --- a/src/share/vm/graal/graalCompilerToVM.cpp Thu Mar 28 15:57:51 2013 +0100 +++ b/src/share/vm/graal/graalCompilerToVM.cpp Thu Mar 28 16:00:40 2013 +0100 @@ -814,6 +814,17 @@ GraalEnv::CodeInstallResult result; CodeInstaller installer(compResultHandle, method, result, nm, installed_code_handle, triggered_deoptimizations_handle); + if (PrintCodeCacheOnCompilation) { + stringStream s; + // Dump code cache into a buffer before locking the tty, + { + MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); + CodeCache::print_summary(&s, false); + } + ttyLocker ttyl; + tty->print_cr(s.as_string()); + } + if (result != GraalEnv::ok) { assert(nm == NULL, "should be"); } else { @@ -828,6 +839,11 @@ return result; C2V_END +C2V_VMENTRY(void, clearQueuedForCompilation, (JNIEnv *jniEnv, jobject, jobject resolvedMethod)) + methodHandle method = getMethodFromHotSpotMethod(JNIHandles::resolve(resolvedMethod)); + method->clear_queued_for_compilation(); +C2V_END + C2V_VMENTRY(jobject, getCode, (JNIEnv *jniEnv, jobject, jlong metaspace_nmethod)) ResourceMark rm; HandleMark hm; @@ -1089,6 +1105,7 @@ {CC"getLineNumberTable", CC"("HS_RESOLVED_METHOD")[J", FN_PTR(getLineNumberTable)}, {CC"getLocalVariableTable", CC"("HS_RESOLVED_METHOD")["LOCAL, FN_PTR(getLocalVariableTable)}, {CC"getFileName", CC"("HS_RESOLVED_JAVA_TYPE")"STRING, FN_PTR(getFileName)}, + {CC"clearQueuedForCompilation", CC"("HS_RESOLVED_METHOD")V", FN_PTR(clearQueuedForCompilation)}, }; int CompilerToVM_methods_count() {