changeset 6511:0b62a9d44c21

add infrastructure for creating locked objects
author Lukas Stadler <lukas.stadler@jku.at>
date Fri, 05 Oct 2012 09:12:55 +0200
parents fbcbb6ba16cd
children edea9ba7ac7b e4ae9932c292
files graal/com.oracle.graal.compiler.virtual/src/com/oracle/graal/compiler/phases/ea/PartialEscapeAnalysisPhase.java graal/com.oracle.graal.compiler.virtual/src/com/oracle/graal/nodes/virtual/MaterializeObjectNode.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/InitializeArrayNode.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/InitializeObjectNode.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/NewObjectSnippets.java graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewArrayNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewObjectArrayNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewPrimitiveArrayNode.java
diffstat 10 files changed, 101 insertions(+), 33 deletions(-) [+]
line wrap: on
line diff
--- 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 @@
         }
     }
 }
+
--- 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<ValueNode> 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);
--- 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);
 }
--- 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);
--- 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);
--- 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)));
--- 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 <code>true</code> if the elements of the array will be initialized.
+     */
     public boolean fillContents() {
         return fillContents;
     }
 
     /**
+     * @return <code>true</code> 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) {
--- 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 <code>true</code> if the fields of the new object will be initialized.
+     */
     public boolean fillContents() {
         return fillContents;
     }
 
+    /**
+     * @return <code>true</code> if the new object will be locked immediately.
+     */
+    public boolean locked() {
+        return locked;
+    }
+
     @Override
     public void lower(LoweringTool tool) {
         tool.getRuntime().lower(this, tool);
--- 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);
     }
 }
--- 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);
     }
 }