# HG changeset patch # User Lukas Stadler # Date 1349421175 -7200 # Node ID 0b62a9d44c21412fe151e802ca5708cec678e45e # Parent fbcbb6ba16cd7256e33a2934957c4751192a696b add infrastructure for creating locked objects diff -r fbcbb6ba16cd -r 0b62a9d44c21 graal/com.oracle.graal.compiler.virtual/src/com/oracle/graal/compiler/phases/ea/PartialEscapeAnalysisPhase.java --- a/graal/com.oracle.graal.compiler.virtual/src/com/oracle/graal/compiler/phases/ea/PartialEscapeAnalysisPhase.java Fri Oct 05 09:01:20 2012 +0200 +++ b/graal/com.oracle.graal.compiler.virtual/src/com/oracle/graal/compiler/phases/ea/PartialEscapeAnalysisPhase.java Fri Oct 05 09:12:55 2012 +0200 @@ -248,7 +248,7 @@ throw new BailoutException("object materialized with lock"); } - MaterializeObjectNode materialize = graph.add(new MaterializeObjectNode(virtual)); + MaterializeObjectNode materialize = graph.add(new MaterializeObjectNode(virtual, false)); materialize.setProbability(fixed.probability()); ValueNode[] fieldState = obj.fieldState; metricMaterializations.increment(); @@ -1144,3 +1144,4 @@ } } } + diff -r fbcbb6ba16cd -r 0b62a9d44c21 graal/com.oracle.graal.compiler.virtual/src/com/oracle/graal/nodes/virtual/MaterializeObjectNode.java --- a/graal/com.oracle.graal.compiler.virtual/src/com/oracle/graal/nodes/virtual/MaterializeObjectNode.java Fri Oct 05 09:01:20 2012 +0200 +++ b/graal/com.oracle.graal.compiler.virtual/src/com/oracle/graal/nodes/virtual/MaterializeObjectNode.java Fri Oct 05 09:12:55 2012 +0200 @@ -34,10 +34,12 @@ @Input private final NodeInputList values; @Input private final VirtualObjectNode virtualObject; + private final boolean locked; - public MaterializeObjectNode(VirtualObjectNode virtualObject) { + public MaterializeObjectNode(VirtualObjectNode virtualObject, boolean locked) { super(StampFactory.exactNonNull(virtualObject.type())); this.virtualObject = virtualObject; + this.locked = locked; this.values = new NodeInputList<>(this, virtualObject.entryCount()); } @@ -51,7 +53,7 @@ if (virtualObject instanceof VirtualInstanceNode) { VirtualInstanceNode virtual = (VirtualInstanceNode) virtualObject; - NewInstanceNode newInstance = graph.add(new NewInstanceNode(virtual.type(), false)); + NewInstanceNode newInstance = graph.add(new NewInstanceNode(virtual.type(), false, locked)); this.replaceAtUsages(newInstance); graph.addAfterFixed(this, newInstance); @@ -70,9 +72,9 @@ ResolvedJavaType element = virtual.componentType(); NewArrayNode newArray; if (element.kind() == Kind.Object) { - newArray = graph.add(new NewObjectArrayNode(element, ConstantNode.forInt(virtual.entryCount(), graph), false)); + newArray = graph.add(new NewObjectArrayNode(element, ConstantNode.forInt(virtual.entryCount(), graph), false, locked)); } else { - newArray = graph.add(new NewPrimitiveArrayNode(element, ConstantNode.forInt(virtual.entryCount(), graph), false)); + newArray = graph.add(new NewPrimitiveArrayNode(element, ConstantNode.forInt(virtual.entryCount(), graph), false, locked)); } this.replaceAtUsages(newArray); graph.addAfterFixed(this, newArray); diff -r fbcbb6ba16cd -r 0b62a9d44c21 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/InitializeArrayNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/InitializeArrayNode.java Fri Oct 05 09:01:20 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/InitializeArrayNode.java Fri Oct 05 09:12:55 2012 +0200 @@ -40,14 +40,16 @@ @Input private final ValueNode size; private final ResolvedJavaType type; private final boolean fillContents; + private final boolean locked; - public InitializeArrayNode(ValueNode memory, ValueNode length, ValueNode size, ResolvedJavaType type, boolean fillContents) { + public InitializeArrayNode(ValueNode memory, ValueNode length, ValueNode size, ResolvedJavaType type, boolean fillContents, boolean locked) { super(StampFactory.exactNonNull(type)); this.memory = memory; this.type = type; this.length = length; this.size = size; this.fillContents = fillContents; + this.locked = locked; } public ValueNode memory() { @@ -71,11 +73,15 @@ return fillContents; } + public boolean locked() { + return locked; + } + @Override public void lower(LoweringTool tool) { tool.getRuntime().lower(this, tool); } @NodeIntrinsic - public static native Object initialize(Object memory, int length, int size, @ConstantNodeParameter ResolvedJavaType type, @ConstantNodeParameter boolean fillContents); + public static native Object initialize(Object memory, int length, int size, @ConstantNodeParameter ResolvedJavaType type, @ConstantNodeParameter boolean fillContents, @ConstantNodeParameter boolean locked); } diff -r fbcbb6ba16cd -r 0b62a9d44c21 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/InitializeObjectNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/InitializeObjectNode.java Fri Oct 05 09:01:20 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/InitializeObjectNode.java Fri Oct 05 09:12:55 2012 +0200 @@ -38,12 +38,14 @@ @Input private final ValueNode memory; private final ResolvedJavaType type; private final boolean fillContents; + private final boolean locked; - public InitializeObjectNode(ValueNode memory, ResolvedJavaType type, boolean fillContents) { + public InitializeObjectNode(ValueNode memory, ResolvedJavaType type, boolean fillContents, boolean locked) { super(StampFactory.exactNonNull(type)); this.memory = memory; this.type = type; this.fillContents = fillContents; + this.locked = locked; } public ValueNode memory() { @@ -58,6 +60,10 @@ return fillContents; } + public boolean locked() { + return locked; + } + @Override public void lower(LoweringTool tool) { tool.getRuntime().lower(this, tool); diff -r fbcbb6ba16cd -r 0b62a9d44c21 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/NewObjectSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/NewObjectSnippets.java Fri Oct 05 09:01:20 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/NewObjectSnippets.java Fri Oct 05 09:12:55 2012 +0200 @@ -74,13 +74,18 @@ @Parameter("hub") Object hub, @Parameter("prototypeMarkWord") Word prototypeMarkWord, @ConstantParameter("size") int size, - @ConstantParameter("fillContents") boolean fillContents) { + @ConstantParameter("fillContents") boolean fillContents, + @ConstantParameter("locked") boolean locked) { if (memory == Word.zero()) { new_stub.inc(); return NewInstanceStubCall.call(hub); } - formatObject(hub, size, memory, prototypeMarkWord, fillContents); + if (locked) { + formatObject(hub, size, memory, thread().or(biasedLockPattern()), fillContents); + } else { + formatObject(hub, size, memory, prototypeMarkWord, fillContents); + } Object instance = memory.toObject(); return castFromHub(verifyOop(instance), hub); } @@ -93,8 +98,13 @@ @Parameter("size") int size, @Parameter("prototypeMarkWord") Word prototypeMarkWord, @ConstantParameter("headerSize") int headerSize, - @ConstantParameter("fillContents") boolean fillContents) { - return initializeArray(memory, hub, length, size, prototypeMarkWord, headerSize, true, fillContents); + @ConstantParameter("fillContents") boolean fillContents, + @ConstantParameter("locked") boolean locked) { + if (locked) { + return initializeArray(memory, hub, length, size, thread().or(biasedLockPattern()), headerSize, true, fillContents); + } else { + return initializeArray(memory, hub, length, size, prototypeMarkWord, headerSize, true, fillContents); + } } @Snippet @@ -105,8 +115,13 @@ @Parameter("size") int size, @Parameter("prototypeMarkWord") Word prototypeMarkWord, @ConstantParameter("headerSize") int headerSize, - @ConstantParameter("fillContents") boolean fillContents) { - return initializeArray(memory, hub, length, size, prototypeMarkWord, headerSize, false, fillContents); + @ConstantParameter("fillContents") boolean fillContents, + @ConstantParameter("locked") boolean locked) { + if (locked) { + return initializeArray(memory, hub, length, size, thread().or(biasedLockPattern()), headerSize, false, fillContents); + } else { + return initializeArray(memory, hub, length, size, prototypeMarkWord, headerSize, false, fillContents); + } } private static Object initializeArray(Word memory, Object hub, int length, int size, Word prototypeMarkWord, int headerSize, boolean isObjectArray, boolean fillContents) { @@ -147,7 +162,7 @@ } int size = getArraySize(length, alignment, headerSize, log2ElementSize); Word memory = TLABAllocateNode.allocateVariableSize(size, wordKind); - return InitializeArrayNode.initialize(memory, length, size, type, true); + return InitializeArrayNode.initialize(memory, length, size, type, true, false); } public static int getArraySize(int length, int alignment, int headerSize, int log2ElementSize) { @@ -232,9 +247,9 @@ this.target = target; this.useTLAB = useTLAB; allocate = snippet("allocate", int.class); - initializeObject = snippet("initializeObject", Word.class, Object.class, Word.class, int.class, boolean.class); - initializeObjectArray = snippet("initializeObjectArray", Word.class, Object.class, int.class, int.class, Word.class, int.class, boolean.class); - initializePrimitiveArray = snippet("initializePrimitiveArray", Word.class, Object.class, int.class, int.class, Word.class, int.class, boolean.class); + initializeObject = snippet("initializeObject", Word.class, Object.class, Word.class, int.class, boolean.class, boolean.class); + initializeObjectArray = snippet("initializeObjectArray", Word.class, Object.class, int.class, int.class, Word.class, int.class, boolean.class, boolean.class); + initializePrimitiveArray = snippet("initializePrimitiveArray", Word.class, Object.class, int.class, int.class, Word.class, int.class, boolean.class, boolean.class); allocateArrayAndInitialize = snippet("allocateArrayAndInitialize", int.class, int.class, int.class, int.class, ResolvedJavaType.class, Kind.class); newmultiarray = snippet("newmultiarray", Object.class, int.class, int[].class); } @@ -260,7 +275,7 @@ graph.addBeforeFixed(newInstanceNode, tlabAllocateNode); memory = tlabAllocateNode; } - InitializeObjectNode initializeNode = graph.add(new InitializeObjectNode(memory, type, newInstanceNode.fillContents())); + InitializeObjectNode initializeNode = graph.add(new InitializeObjectNode(memory, type, newInstanceNode.fillContents(), newInstanceNode.locked())); graph.replaceFixedWithFixed(newInstanceNode, initializeNode); } @@ -284,7 +299,7 @@ // value for 'size' doesn't matter as it isn't used since a stub call will be made anyway // for both allocation and initialization - it just needs to be non-null ConstantNode size = ConstantNode.forInt(-1, graph); - InitializeArrayNode initializeNode = graph.add(new InitializeArrayNode(zero, lengthNode, size, arrayType, newArrayNode.fillContents())); + InitializeArrayNode initializeNode = graph.add(new InitializeArrayNode(zero, lengthNode, size, arrayType, newArrayNode.fillContents(), newArrayNode.locked())); graph.replaceFixedWithFixed(newArrayNode, initializeNode); } else if (length != null && belowThan(length, MAX_ARRAY_FAST_PATH_ALLOCATION_LENGTH)) { // Calculate aligned size @@ -292,7 +307,7 @@ ConstantNode sizeNode = ConstantNode.forInt(size, graph); tlabAllocateNode = graph.add(new TLABAllocateNode(sizeNode, target.wordKind)); graph.addBeforeFixed(newArrayNode, tlabAllocateNode); - InitializeArrayNode initializeNode = graph.add(new InitializeArrayNode(tlabAllocateNode, lengthNode, sizeNode, arrayType, newArrayNode.fillContents())); + InitializeArrayNode initializeNode = graph.add(new InitializeArrayNode(tlabAllocateNode, lengthNode, sizeNode, arrayType, newArrayNode.fillContents(), newArrayNode.locked())); graph.replaceFixedWithFixed(newArrayNode, initializeNode); } else { Key key = new Key(allocateArrayAndInitialize). @@ -328,7 +343,7 @@ int size = type.instanceSize(); assert (size % wordSize()) == 0; assert size >= 0; - Key key = new Key(initializeObject).add("size", size).add("fillContents", initializeNode.fillContents()); + Key key = new Key(initializeObject).add("size", size).add("fillContents", initializeNode.fillContents()).add("locked", initializeNode.locked()); ValueNode memory = initializeNode.memory(); Arguments arguments = arguments("memory", memory).add("hub", hub).add("prototypeMarkWord", type.prototypeMarkWord()); SnippetTemplate template = cache.get(key); @@ -345,7 +360,7 @@ HotSpotKlassOop hub = type.klassOop(); Kind elementKind = elementType.kind(); final int headerSize = elementKind.getArrayBaseOffset(); - Key key = new Key(elementKind.isObject() ? initializeObjectArray : initializePrimitiveArray).add("headerSize", headerSize).add("fillContents", initializeNode.fillContents()); + Key key = new Key(elementKind.isObject() ? initializeObjectArray : initializePrimitiveArray).add("headerSize", headerSize).add("fillContents", initializeNode.fillContents()).add("locked", initializeNode.locked()); ValueNode memory = initializeNode.memory(); Arguments arguments = arguments("memory", memory).add("hub", hub).add("prototypeMarkWord", type.prototypeMarkWord()).add("size", initializeNode.size()).add("length", initializeNode.length()); SnippetTemplate template = cache.get(key); diff -r fbcbb6ba16cd -r 0b62a9d44c21 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 Fri Oct 05 09:01:20 2012 +0200 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Fri Oct 05 09:12:55 2012 +0200 @@ -662,7 +662,7 @@ void genNewInstance(int cpi) { JavaType type = lookupType(cpi, NEW); if (type instanceof ResolvedJavaType && ((ResolvedJavaType) type).isInitialized()) { - NewInstanceNode n = currentGraph.add(new NewInstanceNode((ResolvedJavaType) type, true)); + NewInstanceNode n = currentGraph.add(new NewInstanceNode((ResolvedJavaType) type, true, false)); frameState.apush(append(n)); } else { append(currentGraph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.Unresolved, graphId))); @@ -695,7 +695,7 @@ private void genNewPrimitiveArray(int typeCode) { Kind kind = arrayTypeCodeToKind(typeCode); ResolvedJavaType elementType = runtime.getResolvedJavaType(kind); - NewPrimitiveArrayNode nta = currentGraph.add(new NewPrimitiveArrayNode(elementType, frameState.ipop(), true)); + NewPrimitiveArrayNode nta = currentGraph.add(new NewPrimitiveArrayNode(elementType, frameState.ipop(), true, false)); frameState.apush(append(nta)); } @@ -703,7 +703,7 @@ JavaType type = lookupType(cpi, ANEWARRAY); ValueNode length = frameState.ipop(); if (type instanceof ResolvedJavaType) { - NewArrayNode n = currentGraph.add(new NewObjectArrayNode((ResolvedJavaType) type, length, true)); + NewArrayNode n = currentGraph.add(new NewObjectArrayNode((ResolvedJavaType) type, length, true, false)); frameState.apush(append(n)); } else { append(currentGraph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.Unresolved, graphId))); diff -r fbcbb6ba16cd -r 0b62a9d44c21 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewArrayNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewArrayNode.java Fri Oct 05 09:01:20 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewArrayNode.java Fri Oct 05 09:12:55 2012 +0200 @@ -38,6 +38,7 @@ private final boolean fillContents; public static final int MaximumEscapeAnalysisArrayLength = 32; + private final boolean locked; @Override public ValueNode length() { @@ -47,20 +48,34 @@ /** * Constructs a new NewArrayNode. * - * @param length the node that produces the length for this allocation + * @param elementType the the type of the elements of the newly created array (not the type of the array itself). + * @param length the node that produces the length for this allocation. + * @param fillContents determines whether the array elements should be initialized to zero/null. + * @param locked determines whether the array should be locked immediately. */ - protected NewArrayNode(ResolvedJavaType elementType, ValueNode length, boolean fillContents) { + protected NewArrayNode(ResolvedJavaType elementType, ValueNode length, boolean fillContents, boolean locked) { super(StampFactory.exactNonNull(elementType.arrayOf())); this.length = length; this.elementType = elementType; this.fillContents = fillContents; + this.locked = locked; } + /** + * @return true if the elements of the array will be initialized. + */ public boolean fillContents() { return fillContents; } /** + * @return true if the array will be locked immediately. + */ + public boolean locked() { + return locked; + } + + /** * The list of node which produce input for this instruction. */ public ValueNode dimension(int index) { diff -r fbcbb6ba16cd -r 0b62a9d44c21 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java Fri Oct 05 09:01:20 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java Fri Oct 05 09:12:55 2012 +0200 @@ -39,16 +39,20 @@ private final ResolvedJavaType instanceClass; private final boolean fillContents; + private final boolean locked; /** * Constructs a NewInstanceNode. * * @param type the class being allocated + * @param fillContents determines whether the new object's fields should be initialized to zero/null. + * @param locked determines whether the new object should be locked immediately. */ - public NewInstanceNode(ResolvedJavaType type, boolean fillContents) { + public NewInstanceNode(ResolvedJavaType type, boolean fillContents, boolean locked) { super(StampFactory.exactNonNull(type)); this.instanceClass = type; this.fillContents = fillContents; + this.locked = locked; } /** @@ -60,10 +64,20 @@ return instanceClass; } + /** + * @return true if the fields of the new object will be initialized. + */ public boolean fillContents() { return fillContents; } + /** + * @return true if the new object will be locked immediately. + */ + public boolean locked() { + return locked; + } + @Override public void lower(LoweringTool tool) { tool.getRuntime().lower(this, tool); diff -r fbcbb6ba16cd -r 0b62a9d44c21 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewObjectArrayNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewObjectArrayNode.java Fri Oct 05 09:01:20 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewObjectArrayNode.java Fri Oct 05 09:12:55 2012 +0200 @@ -36,8 +36,10 @@ * Constructs a new NewObjectArrayNode. * @param elementClass the class of elements in this array * @param length the node producing the length of the array + * @param fillContents determines whether the array elements should be initialized to null. + * @param locked determines whether the array should be locked immediately. */ - public NewObjectArrayNode(ResolvedJavaType elementClass, ValueNode length, boolean fillContents) { - super(elementClass, length, fillContents); + public NewObjectArrayNode(ResolvedJavaType elementClass, ValueNode length, boolean fillContents, boolean locked) { + super(elementClass, length, fillContents, locked); } } diff -r fbcbb6ba16cd -r 0b62a9d44c21 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewPrimitiveArrayNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewPrimitiveArrayNode.java Fri Oct 05 09:01:20 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewPrimitiveArrayNode.java Fri Oct 05 09:12:55 2012 +0200 @@ -32,7 +32,14 @@ @NodeInfo(nameTemplate = "NewArray {p#elementType}") public final class NewPrimitiveArrayNode extends NewArrayNode implements Node.IterableNodeType { - public NewPrimitiveArrayNode(ResolvedJavaType elementType, ValueNode length, boolean fillContents) { - super(elementType, length, fillContents); + /** + * Constructs a new NewPrimitiveArrayNode. + * @param elementType the type of elements in this array + * @param length the node producing the length of the array + * @param fillContents determines whether the array elements should be initialized to zero. + * @param locked determines whether the array should be locked immediately. + */ + public NewPrimitiveArrayNode(ResolvedJavaType elementType, ValueNode length, boolean fillContents, boolean locked) { + super(elementType, length, fillContents, locked); } }