changeset 10027:e561e0a6f727

DynamicNewArrayNode
author Roland Schatz <roland.schatz@oracle.com>
date Wed, 12 Jun 2013 16:29:12 +0200
parents 2beeb916aa31
children 3a7a8666df94
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/DynamicNewArrayNode.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ArraySubstitutions.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraalMethodSubstitutions.java
diffstat 5 files changed, 174 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Wed Jun 12 16:28:43 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Wed Jun 12 16:29:12 2013 +0200
@@ -768,6 +768,10 @@
             if (tool.getLoweringType() == LoweringType.AFTER_GUARDS) {
                 newObjectSnippets.lower((NewArrayNode) n);
             }
+        } else if (n instanceof DynamicNewArrayNode) {
+            if (tool.getLoweringType() == LoweringType.AFTER_GUARDS) {
+                newObjectSnippets.lower((DynamicNewArrayNode) n);
+            }
         } else if (n instanceof MonitorEnterNode) {
             if (tool.getLoweringType() == LoweringType.AFTER_GUARDS) {
                 monitorSnippets.lower((MonitorEnterNode) n, tool);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java	Wed Jun 12 16:28:43 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java	Wed Jun 12 16:29:12 2013 +0200
@@ -121,6 +121,33 @@
         return unsafeArrayCast(verifyOop(result), length, StampFactory.forNodeIntrinsic(), anchorNode);
     }
 
+    @Snippet
+    public static Object allocateArrayDynamic(Class<?> elementType, int length, @ConstantParameter boolean fillContents) {
+        Word hub = loadWordFromObject(elementType, arrayKlassOffset());
+        if (hub.equal(Word.zero())) {
+            // the array class is not yet loaded
+            DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
+        }
+
+        int layoutHelper = readLayoutHelper(hub);
+        //@formatter:off
+        // For arrays, layout helper is a negative number, containing four
+        // distinct bytes, as follows:
+        //    MSB:[tag, hsz, ebt, log2(esz)]:LSB
+        // where:
+        //    tag is 0x80 if the elements are oops, 0xC0 if non-oops
+        //    hsz is array header size in bytes (i.e., offset of first element)
+        //    ebt is the BasicType of the elements
+        //    esz is the element size in bytes
+        //@formatter:on
+
+        int headerSize = (layoutHelper >> 16) & 0xFF;
+        int log2ElementSize = layoutHelper & 0xFF;
+        Word prototypeMarkWord = hub.readWord(prototypeMarkWordOffset(), PROTOTYPE_MARK_WORD_LOCATION);
+
+        return allocateArray(hub, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents);
+    }
+
     /**
      * Computes the size of the memory chunk allocated for an array. This size accounts for the
      * array header size, boy size and any padding after the last element to satisfy object
@@ -201,6 +228,7 @@
 
         private final SnippetInfo allocateInstance = snippet(NewObjectSnippets.class, "allocateInstance");
         private final SnippetInfo allocateArray = snippet(NewObjectSnippets.class, "allocateArray");
+        private final SnippetInfo allocateArrayDynamic = snippet(NewObjectSnippets.class, "allocateArrayDynamic");
         private final SnippetInfo newmultiarray = snippet(NewObjectSnippets.class, "newmultiarray");
 
         public Templates(CodeCacheProvider runtime, Replacements replacements, TargetDescription target) {
@@ -253,6 +281,16 @@
             template.instantiate(runtime, newArrayNode, DEFAULT_REPLACER, args);
         }
 
+        public void lower(DynamicNewArrayNode newArrayNode) {
+            Arguments args = new Arguments(allocateArrayDynamic);
+            args.add("elementType", newArrayNode.getElementType());
+            args.add("length", newArrayNode.length());
+            args.addConst("fillContents", newArrayNode.fillContents());
+
+            SnippetTemplate template = template(args);
+            template.instantiate(runtime, newArrayNode, DEFAULT_REPLACER, args);
+        }
+
         public void lower(NewMultiArrayNode newmultiarrayNode) {
             StructuredGraph graph = newmultiarrayNode.graph();
             int rank = newmultiarrayNode.dimensionCount();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/DynamicNewArrayNode.java	Wed Jun 12 16:29:12 2013 +0200
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.nodes.java;
+
+import java.lang.reflect.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
+
+/**
+ * The {@code DynamicNewArrayNode} is used for allocation of arrays when the type is not a
+ * compile-time constant.
+ */
+public class DynamicNewArrayNode extends FixedWithNextNode implements Canonicalizable, Lowerable, ArrayLengthProvider {
+
+    @Input private ValueNode elementType;
+    @Input private ValueNode length;
+    private final boolean fillContents;
+
+    public DynamicNewArrayNode(ValueNode elementType, ValueNode length) {
+        this(elementType, length, true);
+    }
+
+    public DynamicNewArrayNode(ValueNode elementType, ValueNode length, boolean fillContents) {
+        super(StampFactory.objectNonNull());
+        this.length = length;
+        this.elementType = elementType;
+        this.fillContents = fillContents;
+    }
+
+    public ValueNode getElementType() {
+        return elementType;
+    }
+
+    @Override
+    public ValueNode length() {
+        return length;
+    }
+
+    public boolean fillContents() {
+        return fillContents;
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (elementType.isConstant()) {
+            Class<?> elementClass = (Class<?>) elementType.asConstant().asObject();
+            if (elementClass != null && !(elementClass.equals(void.class))) {
+                ResolvedJavaType javaType = tool.runtime().lookupJavaType(elementClass);
+                return graph().add(new NewArrayNode(javaType, length, fillContents));
+            }
+        }
+        return this;
+    }
+
+    @Override
+    public void lower(LoweringTool tool, LoweringType loweringType) {
+        tool.getRuntime().lower(this, tool);
+    }
+
+    @NodeIntrinsic
+    public static Object newArray(Class<?> componentType, int length) {
+        return Array.newInstance(componentType, length);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ArraySubstitutions.java	Wed Jun 12 16:29:12 2013 +0200
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.replacements;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.replacements.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.java.*;
+
+/**
+ * Substitutions for {@link java.lang.reflect.Array} methods.
+ */
+@ClassSubstitution(java.lang.reflect.Array.class)
+public class ArraySubstitutions {
+
+    @MethodSubstitution
+    public static Object newArray(Class<?> componentType, int length) throws NegativeArraySizeException {
+        if (componentType == null) {
+            DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.NullCheckException);
+        }
+        return DynamicNewArrayNode.newArray(componentType, length);
+    }
+}
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraalMethodSubstitutions.java	Wed Jun 12 16:28:43 2013 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraalMethodSubstitutions.java	Wed Jun 12 16:29:12 2013 +0200
@@ -41,6 +41,7 @@
         }
 
         if (Intrinsify.getValue()) {
+            replacements.registerSubstitutions(ArraySubstitutions.class);
             replacements.registerSubstitutions(MathSubstitutionsX86.class);
             replacements.registerSubstitutions(DoubleSubstitutions.class);
             replacements.registerSubstitutions(FloatSubstitutions.class);