Mercurial > hg > graal-compiler
changeset 8519:c91917e43c98
-Merge
author | Christos Kotselidis <christos.kotselidis@oracle.com> |
---|---|
date | Tue, 26 Mar 2013 10:51:42 +0100 |
parents | 4a79f7c0d1a4 (diff) 95e21e035363 (current diff) |
children | 450abf358987 |
files | graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/SystemSubstitutions.java |
diffstat | 32 files changed, 859 insertions(+), 83 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java Mon Mar 25 22:38:05 2013 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java Tue Mar 26 10:51:42 2013 +0100 @@ -41,6 +41,8 @@ import static com.oracle.graal.hotspot.replacements.AESCryptSubstitutions.EncryptBlockStubCall.*; import static com.oracle.graal.hotspot.replacements.CipherBlockChainingSubstitutions.DecryptAESCryptStubCall.*; import static com.oracle.graal.hotspot.replacements.CipherBlockChainingSubstitutions.EncryptAESCryptStubCall.*; +import static com.oracle.graal.hotspot.nodes.WriteBarrierPostStubCall.*; +import static com.oracle.graal.hotspot.nodes.WriteBarrierPreStubCall.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; @@ -50,8 +52,8 @@ import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.replacements.amd64.*; import com.oracle.graal.replacements.*; -import com.oracle.graal.replacements.amd64.*; public class AMD64HotSpotRuntime extends HotSpotRuntime { @@ -88,6 +90,16 @@ /* arg0: object */ javaCallingConvention(Kind.Object, /* arg1: lock */ word)); + addRuntimeCall(WBPRECALL, config.wbPreCallStub, + /* temps */ null, + /* ret */ ret(Kind.Void), + /* arg0: object */ javaCallingConvention(Kind.Object)); + + addRuntimeCall(WBPOSTCALL, config.wbPostCallStub, + /* temps */ null, + /* ret */ ret(Kind.Void), + /* arg0: object */ javaCallingConvention(Kind.Object, word)); + addRuntimeCall(MONITOREXIT, config.monitorExitStub, /* temps */ null, /* ret */ ret(Kind.Void),
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Mon Mar 25 22:38:05 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Tue Mar 26 10:51:42 2013 +0100 @@ -22,7 +22,6 @@ */ package com.oracle.graal.hotspot; -import static com.oracle.graal.nodes.StructuredGraph.*; import static com.oracle.graal.phases.common.InliningUtil.*; import java.util.concurrent.*; @@ -36,6 +35,7 @@ import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.nodes.*; import com.oracle.graal.phases.*; +import static com.oracle.graal.nodes.StructuredGraph.*; public final class CompilationTask implements Runnable, Comparable<CompilationTask> {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Mon Mar 25 22:38:05 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Tue Mar 26 10:51:42 2013 +0100 @@ -42,6 +42,7 @@ public boolean useBiasedLocking; public boolean usePopCountInstruction; public boolean useAESIntrinsics; + public boolean useG1GC; // offsets, ... public int stackShadowPages; @@ -216,6 +217,16 @@ public boolean isPollingPageFar; /** + * G1 Collector Related Values. + */ + public int g1CardQueueIndexOffset; + public int g1CardQueueBufferOffset; + public int logOfHRGrainBytes; + public int g1SATBQueueMarkingOffset; + public int g1SATBQueueIndexOffset; + public int g1SATBQueueBufferOffset; + + /** * The offset of the _java_mirror field (of type {@link Class}) in a Klass. */ public int classMirrorOffset; @@ -317,6 +328,9 @@ public long handleDeoptStub; public long monitorEnterStub; public long monitorExitStub; + public long wbPreCallStub; + public long wbPostCallStub; + public long verifyOopStub; public long vmErrorStub; public long deoptimizeStub;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Mon Mar 25 22:38:05 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Tue Mar 26 10:51:42 2013 +0100 @@ -35,7 +35,7 @@ import static com.oracle.graal.nodes.java.RegisterFinalizerNode.*; import static com.oracle.graal.replacements.Log.*; import static com.oracle.graal.replacements.MathSubstitutionsX86.*; - +import com.oracle.graal.replacements.*; import java.lang.reflect.*; import java.util.*; @@ -69,7 +69,6 @@ import com.oracle.graal.nodes.type.*; import com.oracle.graal.phases.*; import com.oracle.graal.printer.*; -import com.oracle.graal.replacements.*; import com.oracle.graal.word.*; /** @@ -87,6 +86,7 @@ private InstanceOfSnippets.Templates instanceofSnippets; private NewObjectSnippets.Templates newObjectSnippets; private MonitorSnippets.Templates monitorSnippets; + private WriteBarrierSnippets.Templates writeBarrierSnippets; private NewInstanceStub newInstanceStub; private NewArrayStub newArrayStub; @@ -265,7 +265,6 @@ /* ret */ ret(Kind.Void), /* arg0: object */ javaCallingConvention(Kind.Object, /* arg1: flags */ Kind.Int)); - // @formatter:on } @@ -353,11 +352,13 @@ installer.installSnippets(NewInstanceStub.class); installer.installSnippets(NewArrayStub.class); + installer.installSnippets(WriteBarrierSnippets.class); checkcastSnippets = new CheckCastSnippets.Templates(this, assumptions, graalRuntime.getTarget()); instanceofSnippets = new InstanceOfSnippets.Templates(this, assumptions, graalRuntime.getTarget()); newObjectSnippets = new NewObjectSnippets.Templates(this, assumptions, graalRuntime.getTarget(), config.useTLAB); monitorSnippets = new MonitorSnippets.Templates(this, assumptions, graalRuntime.getTarget(), config.useFastLocking); + writeBarrierSnippets = new WriteBarrierSnippets.Templates(this, assumptions, graalRuntime.getTarget()); newInstanceStub = new NewInstanceStub(this, assumptions, graalRuntime.getTarget()); newArrayStub = new NewArrayStub(this, assumptions, graalRuntime.getTarget()); @@ -580,10 +581,17 @@ LoadFieldNode loadField = (LoadFieldNode) n; HotSpotResolvedJavaField field = (HotSpotResolvedJavaField) loadField.field(); ValueNode object = loadField.isStatic() ? ConstantNode.forObject(field.getDeclaringClass().mirror(), this, graph) : loadField.object(); + LocationNode location = LocationNode.create(field, field.getKind(), field.offset(), graph); assert loadField.kind() != Kind.Illegal; ReadNode memoryRead = graph.add(new ReadNode(object, LocationNode.create(field, field.getKind(), field.offset(), graph), loadField.stamp())); memoryRead.dependencies().add(tool.createNullCheckGuard(object)); + graph.replaceFixedWithFixed(loadField, memoryRead); + if (config.useG1GC && field.getKind() == Kind.Object && field.getDeclaringClass().getName().toString().equals("Ljava/lang/ref/Reference;") && field.getName().equals("referent")) { + WriteBarrierPre writeBarrierPre = graph.add(new WriteBarrierPre(memoryRead.object(), memoryRead, location, false)); + graph.addAfterFixed(memoryRead, writeBarrierPre); + } + if (loadField.isVolatile()) { MembarNode preMembar = graph.add(new MembarNode(JMM_PRE_VOLATILE_READ)); graph.addBeforeFixed(memoryRead, preMembar); @@ -594,19 +602,31 @@ StoreFieldNode storeField = (StoreFieldNode) n; HotSpotResolvedJavaField field = (HotSpotResolvedJavaField) storeField.field(); ValueNode object = storeField.isStatic() ? ConstantNode.forObject(field.getDeclaringClass().mirror(), this, graph) : storeField.object(); - WriteNode memoryWrite = graph.add(new WriteNode(object, storeField.value(), LocationNode.create(field, field.getKind(), field.offset(), graph))); + LocationNode location = LocationNode.create(field, field.getKind(), field.offset(), graph); + WriteNode memoryWrite = graph.add(new WriteNode(object, storeField.value(), location)); memoryWrite.dependencies().add(tool.createNullCheckGuard(object)); memoryWrite.setStateAfter(storeField.stateAfter()); graph.replaceFixedWithFixed(storeField, memoryWrite); FixedWithNextNode last = memoryWrite; + FixedWithNextNode first = memoryWrite; + if (field.getKind() == Kind.Object && !memoryWrite.value().objectStamp().alwaysNull()) { - FieldWriteBarrier writeBarrier = graph.add(new FieldWriteBarrier(memoryWrite.object())); - graph.addAfterFixed(memoryWrite, writeBarrier); - last = writeBarrier; + 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; + } } if (storeField.isVolatile()) { MembarNode preMembar = graph.add(new MembarNode(JMM_PRE_VOLATILE_WRITE)); - graph.addBeforeFixed(memoryWrite, preMembar); + graph.addBeforeFixed(first, preMembar); MembarNode postMembar = graph.add(new MembarNode(JMM_POST_VOLATILE_WRITE)); graph.addAfterFixed(last, postMembar); } @@ -614,16 +634,29 @@ // Separate out GC barrier semantics CompareAndSwapNode cas = (CompareAndSwapNode) n; ValueNode expected = cas.expected(); + IndexedLocationNode 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(); if (type != null && !type.isArray() && !MetaUtil.isJavaLangObject(type)) { // Use a field write barrier since it's not an array store - FieldWriteBarrier writeBarrier = graph.add(new FieldWriteBarrier(cas.object())); - graph.addAfterFixed(cas, writeBarrier); + 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 { + FieldWriteBarrier writeBarrier = graph.add(new FieldWriteBarrier(cas.object())); + graph.addAfterFixed(cas, writeBarrier); + } } else { // This may be an array store so use an array write barrier - LocationNode location = IndexedLocationNode.create(LocationNode.ANY_LOCATION, cas.expected().kind(), cas.displacement(), cas.offset(), graph, 1); - graph.addAfterFixed(cas, graph.add(new ArrayWriteBarrier(cas.object(), location))); + 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))); + } } } } else if (n instanceof LoadIndexedNode) { @@ -637,9 +670,8 @@ } else if (n instanceof StoreIndexedNode) { StoreIndexedNode storeIndexed = (StoreIndexedNode) n; ValueNode boundsCheck = createBoundsCheck(storeIndexed, tool); - Kind elementKind = storeIndexed.elementKind(); - LocationNode arrayLocation = createArrayLocation(graph, elementKind, storeIndexed.index()); + IndexedLocationNode arrayLocation = createArrayLocation(graph, elementKind, storeIndexed.index()); ValueNode value = storeIndexed.value(); ValueNode array = storeIndexed.array(); if (elementKind == Kind.Object && !value.objectStamp().alwaysNull()) { @@ -665,11 +697,17 @@ WriteNode memoryWrite = graph.add(new WriteNode(array, value, arrayLocation)); memoryWrite.dependencies().add(boundsCheck); memoryWrite.setStateAfter(storeIndexed.stateAfter()); - graph.replaceFixedWithFixed(storeIndexed, memoryWrite); if (elementKind == Kind.Object && !value.objectStamp().alwaysNull()) { - graph.addAfterFixed(memoryWrite, graph.add(new ArrayWriteBarrier(array, arrayLocation))); + 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))); + } } } else if (n instanceof UnsafeLoadNode) { UnsafeLoadNode load = (UnsafeLoadNode) n; @@ -689,15 +727,28 @@ graph.replaceFixedWithFixed(store, write); if (write.value().kind() == Kind.Object && !write.value().objectStamp().alwaysNull()) { ResolvedJavaType type = object.objectStamp().type(); - WriteBarrier writeBarrier; + // WriteBarrier writeBarrier; if (type != null && !type.isArray() && !MetaUtil.isJavaLangObject(type)) { // Use a field write barrier since it's not an array store - writeBarrier = graph.add(new FieldWriteBarrier(object)); + 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 { + FieldWriteBarrier writeBarrier = graph.add(new FieldWriteBarrier(object)); + graph.addAfterFixed(write, writeBarrier); + } } else { // This may be an array store so use an array write barrier - writeBarrier = graph.add(new ArrayWriteBarrier(object, location)); + 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 { + ArrayWriteBarrier writeBarrier = graph.add(new ArrayWriteBarrier(object, location)); + graph.addAfterFixed(write, writeBarrier); + } } - graph.addAfterFixed(write, writeBarrier); } } else if (n instanceof LoadHubNode) { LoadHubNode loadHub = (LoadHubNode) n; @@ -729,6 +780,14 @@ 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 TLABAllocateNode) { newObjectSnippets.lower((TLABAllocateNode) n, tool); } else if (n instanceof InitializeObjectNode) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ArrayWriteBarrier.java Mon Mar 25 22:38:05 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ArrayWriteBarrier.java Tue Mar 26 10:51:42 2013 +0100 @@ -22,12 +22,11 @@ */ package com.oracle.graal.hotspot.nodes; -import com.oracle.graal.api.meta.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; -public final class ArrayWriteBarrier extends WriteBarrier implements LIRLowerable { +public final class ArrayWriteBarrier extends WriteBarrier implements Lowerable { @Input private ValueNode object; @Input private LocationNode location; @@ -45,9 +44,7 @@ this.location = location; } - @Override - public void generate(LIRGeneratorTool gen) { - Value addr = location().generateLea(gen, object()); - generateBarrier(addr, gen); + public void lower(LoweringTool generator) { + generator.getRuntime().lower(this, generator); } }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/FieldWriteBarrier.java Mon Mar 25 22:38:05 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/FieldWriteBarrier.java Tue Mar 26 10:51:42 2013 +0100 @@ -22,11 +22,10 @@ */ package com.oracle.graal.hotspot.nodes; -import com.oracle.graal.api.meta.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; -public final class FieldWriteBarrier extends WriteBarrier implements LIRLowerable { +public final class FieldWriteBarrier extends WriteBarrier implements Lowerable { @Input private ValueNode object; @@ -38,10 +37,7 @@ this.object = object; } - @Override - public void generate(LIRGeneratorTool generator) { - Value obj = generator.newVariable(generator.target().wordKind); - generator.emitMove(obj, generator.operand(object())); - generateBarrier(obj, generator); + public void lower(LoweringTool generator) { + generator.getRuntime().lower(this, generator); } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/FixedValueAnchorNode.java Tue Mar 26 10:51:42 2013 +0100 @@ -0,0 +1,56 @@ +/* + * 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 FixedValueAnchorNode extends FixedWithNextNode implements LIRLowerable { + + @Input private ValueNode object; + + public ValueNode object() { + return object; + } + + public FixedValueAnchorNode(ValueNode object) { + super(StampFactory.forNodeIntrinsic()); + this.object = object; + + } + + @Override + public boolean inferStamp() { + return updateStamp(object.stamp()); + } + + @NodeIntrinsic + public static native <T> T getObject(Object object); + + @Override + public void generate(LIRGeneratorTool generator) { + generator.setResult(this, generator.operand(object)); + } + +}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/InitializeArrayNode.java Mon Mar 25 22:38:05 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/InitializeArrayNode.java Tue Mar 26 10:51:42 2013 +0100 @@ -23,6 +23,7 @@ package com.oracle.graal.hotspot.nodes; import com.oracle.graal.api.meta.*; +import com.oracle.graal.hotspot.replacements.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -72,7 +73,9 @@ } public boolean fillContents() { - return fillContents; + // We fill contents when G1 GC is used since we want to record + // the original field values prior to stores + return HotSpotSnippetUtils.useG1GC() ? true : fillContents; } public boolean locked() {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/InitializeObjectNode.java Mon Mar 25 22:38:05 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/InitializeObjectNode.java Tue Mar 26 10:51:42 2013 +0100 @@ -23,6 +23,7 @@ package com.oracle.graal.hotspot.nodes; import com.oracle.graal.api.meta.*; +import com.oracle.graal.hotspot.replacements.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -56,7 +57,7 @@ } public boolean fillContents() { - return fillContents; + return HotSpotSnippetUtils.useG1GC() ? true : fillContents; } public boolean locked() {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrier.java Mon Mar 25 22:38:05 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrier.java Tue Mar 26 10:51:42 2013 +0100 @@ -22,10 +22,7 @@ */ package com.oracle.graal.hotspot.nodes; -import com.oracle.graal.api.meta.*; -import com.oracle.graal.hotspot.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; public abstract class WriteBarrier extends FixedWithNextNode { @@ -34,17 +31,4 @@ super(StampFactory.forVoid()); } - protected void generateBarrier(Value adr, LIRGeneratorTool gen) { - HotSpotVMConfig config = HotSpotGraalRuntime.getInstance().getConfig(); - Value base = gen.emitUShr(adr, Constant.forInt(config.cardtableShift)); - - long startAddress = config.cardtableStartAddress; - int displacement = 0; - if (((int) startAddress) == startAddress) { - displacement = (int) startAddress; - } else { - base = gen.emitAdd(base, Constant.forLong(config.cardtableStartAddress)); - } - gen.emitStore(Kind.Boolean, base, displacement, Value.ILLEGAL, 0, Constant.FALSE, false); - } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrierPost.java Tue Mar 26 10:51:42 2013 +0100 @@ -0,0 +1,64 @@ +/* + * 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 WriteBarrierPost extends FixedWithNextNode implements Lowerable { + + @Input private ValueNode object; + @Input private ValueNode value; + @Input private LocationNode location; + private final boolean precise; + + public ValueNode getObject() { + return object; + } + + public ValueNode getValue() { + return value; + } + + public LocationNode getLocation() { + return location; + } + + public boolean usePrecise() { + return precise; + } + + 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; + } + + public void lower(LoweringTool generator) { + generator.getRuntime().lower(this, generator); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrierPostStubCall.java Tue Mar 26 10:51:42 2013 +0100 @@ -0,0 +1,56 @@ +/* + * 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.api.code.*; +import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor; +import com.oracle.graal.compiler.gen.*; +import com.oracle.graal.compiler.target.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.type.*; +import com.oracle.graal.word.*; + +/** + * Node implementing a call to HotSpot's {@code graal_monitorenter} stub. + */ +public class WriteBarrierPostStubCall extends FixedWithNextNode implements LIRGenLowerable { + + @Input private ValueNode object; + @Input private ValueNode card; + public static final Descriptor WBPOSTCALL = new Descriptor("wbpostcall", true, void.class, Object.class, Word.class); + + public WriteBarrierPostStubCall(ValueNode object, ValueNode card) { + super(StampFactory.forVoid()); + this.object = object; + this.card = card; + } + + @Override + public void generate(LIRGenerator gen) { + RuntimeCallTarget stub = gen.getRuntime().lookupRuntimeCall(WriteBarrierPostStubCall.WBPOSTCALL); + gen.emitCall(stub, stub.getCallingConvention(), false, gen.operand(object), gen.operand(card)); + } + + @NodeIntrinsic + public static native void call(Object hub, Word card); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrierPre.java Tue Mar 26 10:51:42 2013 +0100 @@ -0,0 +1,65 @@ +/* + * 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 WriteBarrierPre extends FixedWithNextNode implements Lowerable { + + @Input private ValueNode object; + @Input private LocationNode location; + @Input private ValueNode expectedObject; + private final boolean doLoad; + + public ValueNode getObject() { + return object; + } + + public ValueNode getExpectedObject() { + return expectedObject; + } + + public boolean doLoad() { + return doLoad; + } + + public LocationNode getLocation() { + return location; + } + + 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; + } + + public void lower(LoweringTool generator) { + generator.getRuntime().lower(this, generator); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrierPreStubCall.java Tue Mar 26 10:51:42 2013 +0100 @@ -0,0 +1,53 @@ +/* + * 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.api.code.*; +import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor; +import com.oracle.graal.compiler.gen.*; +import com.oracle.graal.compiler.target.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.type.*; + +/** + * Node implementing a call to HotSpot's {@code graal_monitorenter} stub. + */ +public class WriteBarrierPreStubCall extends FixedWithNextNode implements LIRGenLowerable { + + @Input private ValueNode object; + public static final Descriptor WBPRECALL = new Descriptor("wbprecall", true, void.class, Object.class); + + public WriteBarrierPreStubCall(ValueNode object) { + super(StampFactory.forVoid()); + this.object = object; + } + + @Override + public void generate(LIRGenerator gen) { + RuntimeCallTarget stub = gen.getRuntime().lookupRuntimeCall(WriteBarrierPreStubCall.WBPRECALL); + gen.emitCall(stub, stub.getCallingConvention(), false, gen.operand(object)); + } + + @NodeIntrinsic + public static native void call(Object hub); +}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotSnippetUtils.java Mon Mar 25 22:38:05 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotSnippetUtils.java Tue Mar 26 10:51:42 2013 +0100 @@ -53,6 +53,11 @@ } @Fold + public static boolean useTLAB() { + return config().useTLAB; + } + + @Fold public static boolean verifyOops() { return config().verifyOops; } @@ -281,6 +286,36 @@ } @Fold + public static int g1CardQueueIndexOffset() { + return config().g1CardQueueIndexOffset; + } + + @Fold + public static int g1CardQueueBufferOffset() { + return config().g1CardQueueBufferOffset; + } + + @Fold + public static int logOfHRGrainBytes() { + return config().logOfHRGrainBytes; + } + + @Fold + public static int g1SATBQueueMarkingOffset() { + return config().g1SATBQueueMarkingOffset; + } + + @Fold + public static int g1SATBQueueIndexOffset() { + return config().g1SATBQueueIndexOffset; + } + + @Fold + public static int g1SATBQueueBufferOffset() { + return config().g1SATBQueueBufferOffset; + } + + @Fold public static int superCheckOffsetOffset() { return config().superCheckOffsetOffset; } @@ -312,6 +347,11 @@ } @Fold + public static boolean useG1GC() { + return config().useG1GC; + } + + @Fold static int uninitializedIdentityHashCodeValue() { return config().uninitializedIdentityHashCodeValue; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java Tue Mar 26 10:51:42 2013 +0100 @@ -0,0 +1,210 @@ +/* + * 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.replacements; + +import static com.oracle.graal.hotspot.replacements.HotSpotSnippetUtils.*; +import static com.oracle.graal.replacements.SnippetTemplate.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.hotspot.nodes.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.replacements.*; +import com.oracle.graal.replacements.Snippet.ConstantParameter; +import com.oracle.graal.replacements.Snippet.Parameter; +import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates; +import com.oracle.graal.replacements.SnippetTemplate.Arguments; +import com.oracle.graal.replacements.SnippetTemplate.Key; +import com.oracle.graal.word.*; + +public class WriteBarrierSnippets implements Snippets { + + @Snippet + public static void g1PreWriteBarrier(@Parameter("object") Object obj, @Parameter("expectedObject") Object expobj, @Parameter("location") Object location, + @ConstantParameter("doLoad") boolean doLoad) { + Word thread = thread(); + Object object = FixedValueAnchorNode.getObject(obj); + Object expectedObject = FixedValueAnchorNode.getObject(expobj); + 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); + } + if (previousOop.notEqual(Word.zero())) { + if (indexValue.notEqual(Word.zero())) { + Word nextIndex = indexValue.subtract(HotSpotSnippetUtils.wordSize()); + Word logAddress = bufferAddress.add(nextIndex); + logAddress.writeWord(0, previousOop); + 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) { + Word thread = thread(); + Object object = FixedValueAnchorNode.getObject(obj); + Object wrObject = FixedValueAnchorNode.getObject(value); + Word oop = (Word) Word.fromObject(object); + Word field; + if (usePrecise) { + field = (Word) Word.fromArray(object, location); + } else { + field = oop; + } + Word writtenValue = (Word) Word.fromObject(wrObject); + Word bufferAddress = thread.readWord(HotSpotSnippetUtils.g1CardQueueBufferOffset()); + Word indexAddress = thread.add(HotSpotSnippetUtils.g1CardQueueIndexOffset()); + Word indexValue = thread.readWord(HotSpotSnippetUtils.g1CardQueueIndexOffset()); + Word xorResult = (field.xor(writtenValue)).unsignedShiftRight(HotSpotSnippetUtils.logOfHRGrainBytes()); + + // Card Table + Word cardBase = field.unsignedShiftRight(cardTableShift()); + long startAddress = cardTableStart(); + int displacement = 0; + if (((int) startAddress) == startAddress) { + displacement = (int) startAddress; + } else { + 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); + if (cardByte != (byte) 0) { + cardAddress.writeByte(0, (byte) 0); // smash zero into card + if (indexValue.notEqual(Word.zero())) { + Word nextIndex = indexValue.subtract(HotSpotSnippetUtils.wordSize()); + Word logAddress = bufferAddress.add(nextIndex); + logAddress.writeWord(0, cardAddress); + indexAddress.writeWord(0, nextIndex); + } else { + WriteBarrierPostStubCall.call(object, cardAddress); + } + } + } + } + } + + @Snippet + public static void serialFieldWriteBarrier(@Parameter("object") Object obj) { + 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; + } else { + base = base.add(Word.unsigned(cardTableStart())); + } + base.writeWord(displacement, Word.zero()); + } + + @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; + if (((int) startAddress) == startAddress) { + displacement = (int) startAddress; + } else { + base = base.add(Word.unsigned(cardTableStart())); + } + base.writeWord(displacement, Word.zero()); + } + + public static class Templates extends AbstractTemplates<WriteBarrierSnippets> { + + private final ResolvedJavaMethod serialFieldWriteBarrier; + private final ResolvedJavaMethod serialArrayWriteBarrier; + private final ResolvedJavaMethod g1PreWriteBarrier; + private final ResolvedJavaMethod g1PostWriteBarrier; + + 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); + } + + public void lower(ArrayWriteBarrier arrayWriteBarrier, @SuppressWarnings("unused") LoweringTool tool) { + ResolvedJavaMethod method = serialArrayWriteBarrier; + Key key = new Key(method); + Arguments arguments = new Arguments(); + arguments.add("object", arrayWriteBarrier.object()); + arguments.add("location", arrayWriteBarrier.location()); + 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); + Arguments arguments = new Arguments(); + arguments.add("object", fieldWriteBarrier.object()); + 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; + Key key = new Key(method); + key.add("doLoad", writeBarrierPre.doLoad()); + Arguments arguments = new Arguments(); + arguments.add("object", writeBarrierPre.getObject()); + arguments.add("expectedObject", writeBarrierPre.getExpectedObject()); + arguments.add("location", writeBarrierPre.getLocation()); + SnippetTemplate template = cache.get(key, assumptions); + template.instantiate(runtime, writeBarrierPre, DEFAULT_REPLACER, arguments); + } + + public void lower(WriteBarrierPost writeBarrierPost, @SuppressWarnings("unused") LoweringTool tool) { + ResolvedJavaMethod method = g1PostWriteBarrier; + Key key = new Key(method); + key.add("usePrecise", writeBarrierPost.usePrecise()); + Arguments arguments = new Arguments(); + arguments.add("object", writeBarrierPost.getObject()); + arguments.add("location", writeBarrierPost.getLocation()); + arguments.add("value", writeBarrierPost.getValue()); + SnippetTemplate template = cache.get(key, assumptions); + template.instantiate(runtime, writeBarrierPost, DEFAULT_REPLACER, arguments); + } + + } +}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java Mon Mar 25 22:38:05 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java Tue Mar 26 10:51:42 2013 +0100 @@ -92,7 +92,12 @@ * operation was unsuccessful */ static Word refillAllocate(Word intArrayHub, int sizeInBytes, boolean log) { - + if (useG1GC()) { + return Word.zero(); + } + if (!useTLAB()) { + return edenAllocate(Word.unsigned(sizeInBytes), log); + } Word intArrayMarkWord = Word.unsigned(tlabIntArrayMarkWord()); int alignmentReserveInBytes = tlabAlignmentReserveInHeapWords() * wordSize();
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Mon Mar 25 22:38:05 2013 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Tue Mar 26 10:51:42 2013 +0100 @@ -745,7 +745,8 @@ private JavaMethod lookupMethod(int cpi, int opcode) { eagerResolvingForSnippets(cpi, opcode); JavaMethod result = constantPool.lookupMethod(cpi, opcode); - assert !graphBuilderConfig.unresolvedIsError() || ((result instanceof ResolvedJavaMethod) && ((ResolvedJavaMethod) result).getDeclaringClass().isInitialized()) : result; + // assert !graphBuilderConfig.unresolvedIsError() || ((result instanceof ResolvedJavaMethod) +// && ((ResolvedJavaMethod) result).getDeclaringClass().isInitialized()) : result; return result; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ComputeAddressNode.java Tue Mar 26 10:51:42 2013 +0100 @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.nodes.extended; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; + +public class ComputeAddressNode extends FloatingNode implements LIRLowerable { + + @Input private ValueNode object; + @Input private ValueNode location; + + public ValueNode getObject() { + return object; + } + + public LocationNode getLocation() { + return (LocationNode) location; + } + + public ComputeAddressNode(ValueNode object, ValueNode location, Stamp stamp) { + super(stamp); + this.object = object; + this.location = location; + } + + @Override + public void generate(LIRGeneratorTool gen) { + Value addr = getLocation().generateLea(gen, getObject()); + gen.setResult(this, addr); + } +}
--- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/Word.java Mon Mar 25 22:38:05 2013 +0100 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/Word.java Tue Mar 26 10:51:42 2013 +0100 @@ -63,6 +63,7 @@ FROM_UNSIGNED, FROM_SIGNED, FROM_OBJECT, + FROM_ARRAY, TO_OBJECT, TO_RAW_VALUE, } @@ -146,6 +147,9 @@ @Operation(opcode = Opcode.FROM_OBJECT) public static native Pointer fromObject(Object val); + @Operation(opcode = Opcode.FROM_ARRAY) + public static native Pointer fromArray(Object oop, Object location); + @Override @Operation(opcode = Opcode.TO_OBJECT) public native Object toObject();
--- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java Mon Mar 25 22:38:05 2013 +0100 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java Tue Mar 26 10:51:42 2013 +0100 @@ -176,6 +176,11 @@ replace(invoke, graph.unique(new UnsafeCastNode(arguments.get(0), StampFactory.forKind(wordKind)))); break; + case FROM_ARRAY: + assert arguments.size() == 2; + replace(invoke, graph.unique(new ComputeAddressNode(arguments.get(0), arguments.get(1), StampFactory.forKind(wordKind)))); + break; + case TO_OBJECT: assert arguments.size() == 1; replace(invoke, graph.unique(new UnsafeCastNode(arguments.get(0), invoke.node().stamp())));
--- a/mx/commands.py Mon Mar 25 22:38:05 2013 +0100 +++ b/mx/commands.py Tue Mar 26 10:51:42 2013 +0100 @@ -1127,6 +1127,15 @@ vm = _vm; sanitycheck.getSPECjbb2013(benchArgs).bench(vm, opts=vmArgs) +def specjbb2005(args): + """runs the composite SPECjbb2005 benchmark + + All options begining with - will be passed to the vm""" + benchArgs = [a for a in args if a[0] != '-'] + vmArgs = [a for a in args if a[0] == '-'] + vm = _vm; + sanitycheck.getSPECjbb2005(benchArgs).bench(vm, opts=vmArgs) + def hsdis(args, copyToDir=None): """download the hsdis library @@ -1232,6 +1241,7 @@ 'scaladacapo': [scaladacapo, '[[n] benchmark] [VM options|@Scala DaCapo options]'], 'specjvm2008': [specjvm2008, '[VM options|specjvm2008 options (-v, -ikv, -ict, -wt, -it)]'], 'specjbb2013': [specjbb2013, '[VM options]'], + 'specjbb2005': [specjbb2005, '[VM options]'], #'example': [example, '[-v] example names...'], 'gate' : [gate, '[-options]'], 'gv' : [gv, ''],
--- a/mx/sanitycheck.py Mon Mar 25 22:38:05 2013 +0100 +++ b/mx/sanitycheck.py Tue Mar 26 10:51:42 2013 +0100 @@ -27,6 +27,8 @@ import re, mx, commands, os, sys, StringIO, subprocess from os.path import isfile, join, exists +gc='UseSerialGC' + dacapoSanityWarmup = { 'avrora': [0, 0, 3, 6, 13], 'batik': [0, 0, 5, 5, 20], @@ -107,7 +109,7 @@ success = re.compile(r"^Valid run, Score is [0-9]+$", re.MULTILINE) matcher = ValuesMatcher(score, {'group' : 'SPECjbb2005', 'name' : 'score', 'score' : '<score>'}) classpath = ['jbb.jar', 'check.jar'] - return Test("SPECjbb2005", ['spec.jbb.JBBmain', '-propfile', 'SPECjbb.props'] + benchArgs, [success], [error], [matcher], vmOpts=['-Xms3g', '-XX:+UseSerialGC', '-XX:-UseCompressedOops', '-cp', os.pathsep.join(classpath)], defaultCwd=specjbb2005) + return Test("SPECjbb2005", ['spec.jbb.JBBmain', '-propfile', 'SPECjbb.props'] + benchArgs, [success], [error], [matcher], vmOpts=['-Xms3g', '-XX:+'+gc, '-XX:-UseCompressedOops', '-cp', os.pathsep.join(classpath)], defaultCwd=specjbb2005) def getSPECjbb2013(benchArgs = []): @@ -144,7 +146,7 @@ if skipCheck: opts += ['-ict'] - return Test("SPECjvm2008", ['-jar', 'SPECjvm2008.jar'] + opts + benchArgs, [success], [error], [matcher], vmOpts=['-Xms3g', '-XX:+UseSerialGC', '-XX:-UseCompressedOops'], defaultCwd=specjvm2008) + return Test("SPECjvm2008", ['-jar', 'SPECjvm2008.jar'] + opts + benchArgs, [success], [error], [matcher], vmOpts=['-Xms3g', '-XX:+'+gc, '-XX:-UseCompressedOops'], defaultCwd=specjvm2008) def getDacapos(level=SanityCheckLevel.Normal, gateBuildLevel=None, dacapoArgs=[]): checks = [] @@ -176,7 +178,7 @@ dacapoMatcher = ValuesMatcher(dacapoTime, {'group' : 'DaCapo', 'name' : '<benchmark>', 'score' : '<time>'}) dacapoMatcher1 = ValuesMatcher(dacapoTime1, {'group' : 'DaCapo-1stRun', 'name' : '<benchmark>', 'score' : '<time>'}) - return Test("DaCapo-" + name, ['-jar', dacapo, name, '-n', str(n), ] + dacapoArgs, [dacapoSuccess], [dacapoFail], [dacapoMatcher, dacapoMatcher1], ['-Xms2g', '-XX:+UseSerialGC', '-XX:-UseCompressedOops']) + return Test("DaCapo-" + name, ['-jar', dacapo, name, '-n', str(n), ] + dacapoArgs, [dacapoSuccess], [dacapoFail], [dacapoMatcher, dacapoMatcher1], ['-Xms2g', '-XX:+'+gc, '-XX:-UseCompressedOops']) def getScalaDacapos(level=SanityCheckLevel.Normal, gateBuildLevel=None, dacapoArgs=[]): checks = [] @@ -206,7 +208,7 @@ dacapoMatcher = ValuesMatcher(dacapoTime, {'group' : "Scala-DaCapo", 'name' : '<benchmark>', 'score' : '<time>'}) - return Test("Scala-DaCapo-" + name, ['-jar', dacapo, name, '-n', str(n), ] + dacapoArgs, [dacapoSuccess], [dacapoFail], [dacapoMatcher], ['-Xms2g', '-XX:+UseSerialGC', '-XX:-UseCompressedOops']) + return Test("Scala-DaCapo-" + name, ['-jar', dacapo, name, '-n', str(n), ] + dacapoArgs, [dacapoSuccess], [dacapoFail], [dacapoMatcher], ['-Xms2g', '-XX:+'+gc, '-XX:-UseCompressedOops']) def getBootstraps(): time = re.compile(r"Bootstrapping Graal\.+ in (?P<time>[0-9]+) ms")
--- a/src/cpu/x86/vm/graalRuntime_x86.cpp Mon Mar 25 22:38:05 2013 +0100 +++ b/src/cpu/x86/vm/graalRuntime_x86.cpp Tue Mar 26 10:51:42 2013 +0100 @@ -1100,7 +1100,45 @@ } __ ret(0); break; - } + } + case wb_pre_call_id: { + Register obj = j_rarg0; + { + GraalStubFrame f(sasm, "graal_wb_pre_call", dont_gc_arguments); + OopMap* map = save_live_registers(sasm, 2, save_fpu_registers); + + // note: really a leaf routine but must setup last java sp + // => use call_RT for now (speed can be improved by + // doing last java sp setup manually) + int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, wb_pre_call), obj); + + oop_maps = new OopMapSet(); + oop_maps->add_gc_map(call_offset, map); + restore_live_registers(sasm); + } + __ ret(0); + break; + } + case wb_post_call_id: { + Register obj = j_rarg0; + Register caddr = j_rarg1; + { + GraalStubFrame f(sasm, "graal_wb_post_call", dont_gc_arguments); + OopMap* map = save_live_registers(sasm, 2, save_fpu_registers); + + // note: really a leaf routine but must setup last java sp + // => use call_RT for now (speed can be improved by + // doing last java sp setup manually) + int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, wb_post_call), obj, caddr); + + oop_maps = new OopMapSet(); + oop_maps->add_gc_map(call_offset, map); + restore_live_registers(sasm); + } + __ ret(0); + break; + } + case identity_hash_code_id: { Register obj = j_rarg0; // Incoming
--- a/src/share/vm/code/nmethod.cpp Mon Mar 25 22:38:05 2013 +0100 +++ b/src/share/vm/code/nmethod.cpp Tue Mar 26 10:51:42 2013 +0100 @@ -2481,6 +2481,7 @@ MutexLocker ml_verify (CompiledIC_lock); ic = CompiledIC_at(this, call_site); } + PcDesc* pd = pc_desc_at(ic->end_of_call()); assert(pd != NULL, "PcDesc must exist"); for (ScopeDesc* sd = new ScopeDesc(this, pd->scope_decode_offset(),
--- a/src/share/vm/gc_implementation/g1/g1AllocRegion.hpp Mon Mar 25 22:38:05 2013 +0100 +++ b/src/share/vm/gc_implementation/g1/g1AllocRegion.hpp Tue Mar 26 10:51:42 2013 +0100 @@ -173,8 +173,17 @@ // Should be called when we want to release the active region which // is returned after it's been retired. HeapRegion* release(); +#ifdef GRAAL + HeapWord** top_addr() const { + return _alloc_region->top_addr(); + } -#if G1_ALLOC_REGION_TRACING + HeapWord** end_addr() const { + return _alloc_region->end_addr(); + } +#endif + + #if G1_ALLOC_REGION_TRACING void trace(const char* str, size_t word_size = 0, HeapWord* result = NULL); #else // G1_ALLOC_REGION_TRACING void trace(const char* str, size_t word_size = 0, HeapWord* result = NULL) { }
--- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Mon Mar 25 22:38:05 2013 +0100 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Tue Mar 26 10:51:42 2013 +0100 @@ -2397,6 +2397,16 @@ } #endif // !PRODUCT +#ifdef GRAAL +HeapWord** G1CollectedHeap::top_addr() const { + return _mutator_alloc_region.top_addr(); +} + +HeapWord** G1CollectedHeap::end_addr() const { + return _mutator_alloc_region.end_addr(); +} +#endif + void G1CollectedHeap::increment_old_marking_cycles_started() { assert(_old_marking_cycles_started == _old_marking_cycles_completed || _old_marking_cycles_started == _old_marking_cycles_completed + 1,
--- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Mon Mar 25 22:38:05 2013 +0100 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Tue Mar 26 10:51:42 2013 +0100 @@ -676,6 +676,12 @@ virtual void gc_prologue(bool full); virtual void gc_epilogue(bool full); + #ifdef GRAAL + HeapWord** top_addr() const; + HeapWord** end_addr() const; + + #endif + // We register a region with the fast "in collection set" test. We // simply set to true the array slot corresponding to this region. void register_region_with_in_cset_fast_test(HeapRegion* r) {
--- a/src/share/vm/graal/graalCompilerToVM.cpp Mon Mar 25 22:38:05 2013 +0100 +++ b/src/share/vm/graal/graalCompilerToVM.cpp Tue Mar 26 10:51:42 2013 +0100 @@ -37,6 +37,7 @@ #include "graal/graalJavaAccess.hpp" #include "graal/graalCodeInstaller.hpp" #include "graal/graalVMToCompiler.hpp" +#include "gc_implementation/g1/heapRegion.hpp" Method* getMethodFromHotSpotMethod(oop hotspot_method) { @@ -610,6 +611,7 @@ set_boolean("usePopCountInstruction", UsePopCountInstruction); set_boolean("useAESIntrinsics", UseAESIntrinsics); set_boolean("useTLAB", UseTLAB); + set_boolean("useG1GC", UseG1GC); set_int("codeEntryAlignment", CodeEntryAlignment); set_int("stackShadowPages", StackShadowPages); set_int("hubOffset", oopDesc::klass_offset_in_bytes()); @@ -705,6 +707,10 @@ set_int("layoutHelperHeaderSizeMask", Klass::_lh_header_size_mask); set_int("layoutHelperOffset", in_bytes(Klass::layout_helper_offset())); + + set_stub("wbPreCallStub", GraalRuntime::entry_for(GraalRuntime::wb_pre_call_id)); + set_stub("wbPostCallStub", GraalRuntime::entry_for(GraalRuntime::wb_post_call_id)); + set_stub("newInstanceStub", GraalRuntime::entry_for(GraalRuntime::new_instance_id)); set_stub("newArrayStub", GraalRuntime::entry_for(GraalRuntime::new_array_id)); set_stub("newMultiArrayStub", GraalRuntime::entry_for(GraalRuntime::new_multi_array_id)); @@ -757,12 +763,19 @@ set_int("deoptActionReinterpret", Deoptimization::Action_reinterpret); set_int("deoptActionMakeNotEntrant", Deoptimization::Action_make_not_entrant); set_int("deoptActionMakeNotCompilable", Deoptimization::Action_make_not_compilable); - + set_int("g1CardQueueIndexOffset", in_bytes(JavaThread::dirty_card_queue_offset() + PtrQueue::byte_offset_of_index())); + set_int("g1CardQueueBufferOffset", in_bytes(JavaThread::dirty_card_queue_offset() + PtrQueue::byte_offset_of_buf())); + set_int("logOfHRGrainBytes", HeapRegion::LogOfHRGrainBytes); + set_int("g1SATBQueueMarkingOffset", in_bytes(JavaThread::satb_mark_queue_offset() + PtrQueue::byte_offset_of_active())); + set_int("g1SATBQueueIndexOffset", in_bytes(JavaThread::satb_mark_queue_offset() + PtrQueue::byte_offset_of_index())); + set_int("g1SATBQueueBufferOffset", in_bytes(JavaThread::satb_mark_queue_offset() + PtrQueue::byte_offset_of_buf())); BarrierSet* bs = Universe::heap()->barrier_set(); switch (bs->kind()) { case BarrierSet::CardTableModRef: - case BarrierSet::CardTableExtension: { + case BarrierSet::CardTableExtension: + case BarrierSet::G1SATBCT: + case BarrierSet::G1SATBCTLogging:{ jlong base = (jlong)((CardTableModRefBS*)bs)->byte_map_base; assert(base != 0, "unexpected byte_map_base"); set_long("cardtableStartAddress", base); @@ -775,10 +788,6 @@ set_int("cardtableShift", 0); // No post barriers break; -#ifndef SERIALGC - case BarrierSet::G1SATBCT: - case BarrierSet::G1SATBCTLogging: -#endif // SERIALGC default: ShouldNotReachHere(); break;
--- a/src/share/vm/graal/graalRuntime.cpp Mon Mar 25 22:38:05 2013 +0100 +++ b/src/share/vm/graal/graalRuntime.cpp Tue Mar 26 10:51:42 2013 +0100 @@ -29,7 +29,7 @@ #include "prims/jvm.h" #include "runtime/biasedLocking.hpp" #include "runtime/interfaceSupport.hpp" - +#include "utilities/debug.hpp" // Implementation of GraalStubAssembler GraalStubAssembler::GraalStubAssembler(CodeBuffer* code, const char * name, int stub_id) : MacroAssembler(code) { @@ -136,7 +136,6 @@ case arithmetic_frem_id: case arithmetic_drem_id: break; - // All other stubs should have oopmaps default: assert(oop_maps != NULL, "must have an oopmap"); @@ -263,7 +262,8 @@ if (DeoptimizeALot) { deopt_caller(); } -JRT_END + JRT_END + JRT_ENTRY(void, GraalRuntime::new_multi_array(JavaThread* thread, Klass* klass, int rank, jint* dims)) @@ -481,6 +481,13 @@ } JRT_END +JRT_LEAF(void, GraalRuntime::wb_pre_call(JavaThread* thread, oopDesc* obj)) + thread->satb_mark_queue().enqueue(obj); +JRT_END + +JRT_LEAF(void, GraalRuntime::wb_post_call(JavaThread* thread, oopDesc* obj, void* card_addr)) + thread->dirty_card_queue().enqueue(card_addr); +JRT_END JRT_LEAF(void, GraalRuntime::monitorexit(JavaThread* thread, oopDesc* obj, BasicLock* lock)) assert(thread == JavaThread::current(), "threads must correspond"); @@ -550,7 +557,8 @@ report_vm_error(__FILE__, __LINE__, error_msg, detail_msg); JRT_END -JRT_ENTRY(void, GraalRuntime::log_printf(JavaThread* thread, oop format, jlong v1, jlong v2, jlong v3)) + +JRT_LEAF(void, GraalRuntime::log_printf(JavaThread* thread, oop format, jlong v1, jlong v2, jlong v3)) ResourceMark rm; assert(format != NULL && java_lang_String::is_instance(format), "must be"); char *buf = java_lang_String::as_utf8_string(format);
--- a/src/share/vm/graal/graalRuntime.hpp Mon Mar 25 22:38:05 2013 +0100 +++ b/src/share/vm/graal/graalRuntime.hpp Tue Mar 26 10:51:42 2013 +0100 @@ -101,7 +101,9 @@ stub(log_primitive) \ stub(identity_hash_code) \ stub(thread_is_interrupted) \ - last_entry(number_of_ids) + stub(wb_pre_call) \ + stub(wb_post_call) \ + last_entry(number_of_ids) #define DECLARE_STUB_ID(x) x ## _id , #define DECLARE_LAST_STUB_ID(x) x @@ -145,7 +147,9 @@ static void vm_error(JavaThread* thread, oop where, oop format, jlong value); static void log_printf(JavaThread* thread, oop format, jlong v1, jlong v2, jlong v3); static void log_primitive(JavaThread* thread, jchar typeChar, jlong value, jboolean newline); - + static void wb_pre_call(JavaThread* thread, oopDesc* obj); + static void wb_post_call(JavaThread* thread, oopDesc* obj, void* card); + static jint identity_hash_code(JavaThread* thread, oopDesc* objd); static jboolean thread_is_interrupted(JavaThread* thread, oopDesc* obj, jboolean clear_interrupte);
--- a/src/share/vm/runtime/arguments.cpp Mon Mar 25 22:38:05 2013 +0100 +++ b/src/share/vm/runtime/arguments.cpp Tue Mar 26 10:51:42 2013 +0100 @@ -2097,18 +2097,17 @@ FLAG_SET_CMDLINE(bool, UseCompressedKlassPointers, false); } if (UseG1GC) { - if (IgnoreUnrecognizedVMOptions) { - warning("UseG1GC is disabled, because it is not supported by Graal"); - FLAG_SET_CMDLINE(bool, UseG1GC, false); + if (IgnoreUnrecognizedVMOptions) { + warning("UseG1GC is still experimental in Graal, use SerialGC instead "); + FLAG_SET_CMDLINE(bool, UseG1GC, true); + } else { + warning("UseG1GC is still experimental in Graal, use SerialGC instead "); + status = true; + } } else { - jio_fprintf(defaultStream::error_stream(), - "G1 is not supported in Graal at the moment\n"); - status = false; + // This prevents the flag being set to true by set_ergonomics_flags() + FLAG_SET_CMDLINE(bool, UseG1GC, false); } - } else { - // This prevents the flag being set to true by set_ergonomics_flags() - FLAG_SET_CMDLINE(bool, UseG1GC, false); - } if (!ScavengeRootsInCode) { warning("forcing ScavengeRootsInCode non-zero because Graal is enabled");