changeset 10035:055430b5abb9

Merge
author Christos Kotselidis <christos.kotselidis@oracle.com>
date Thu, 13 Jun 2013 18:48:57 +0200
parents 6cbb7fb49de5 (current diff) 85f926430ae6 (diff)
children 91b9c3f0100a
files
diffstat 17 files changed, 343 insertions(+), 43 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Thu Jun 13 12:52:39 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Thu Jun 13 18:48:57 2013 +0200
@@ -358,7 +358,7 @@
         test(method, expect, Collections.<DeoptimizationReason> emptySet(), receiver, args);
     }
 
-    protected void test(Method method, Result expect, Set<DeoptimizationReason> shouldNotDeopt, Object receiver, Object... args) {
+    protected Result executeActualCheckDeopt(Method method, Set<DeoptimizationReason> shouldNotDeopt, Object receiver, Object... args) {
         Map<DeoptimizationReason, Integer> deoptCounts = new EnumMap<>(DeoptimizationReason.class);
         ProfilingInfo profile = runtime.lookupJavaMethod(method).getProfilingInfo();
         for (DeoptimizationReason reason : shouldNotDeopt) {
@@ -368,7 +368,10 @@
         for (DeoptimizationReason reason : shouldNotDeopt) {
             Assert.assertEquals((int) deoptCounts.get(reason), profile.getDeoptimizationCount(reason));
         }
+        return actual;
+    }
 
+    protected void assertEquals(Result expect, Result actual) {
         if (expect.exception != null) {
             Assert.assertTrue("expected " + expect.exception, actual.exception != null);
             Assert.assertEquals(expect.exception.getClass(), actual.exception.getClass());
@@ -382,6 +385,11 @@
         }
     }
 
+    protected void test(Method method, Result expect, Set<DeoptimizationReason> shouldNotDeopt, Object receiver, Object... args) {
+        Result actual = executeActualCheckDeopt(method, shouldNotDeopt, receiver, args);
+        assertEquals(expect, actual);
+    }
+
     private Map<ResolvedJavaMethod, InstalledCode> cache = new HashMap<>();
 
     /**
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java	Thu Jun 13 12:52:39 2013 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java	Thu Jun 13 18:48:57 2013 +0200
@@ -37,37 +37,37 @@
         CanonicalizerPhase canonicalizer = new CanonicalizerPhase(!AOTCompilation.getValue());
 
         if (FullUnroll.getValue()) {
-            addPhase(new LoopFullUnrollPhase(!AOTCompilation.getValue()));
+            appendPhase(new LoopFullUnrollPhase(!AOTCompilation.getValue()));
         }
 
         if (OptTailDuplication.getValue()) {
-            addPhase(new TailDuplicationPhase());
+            appendPhase(new TailDuplicationPhase());
         }
 
         if (PartialEscapeAnalysis.getValue()) {
-            addPhase(new PartialEscapePhase(true, canonicalizer));
+            appendPhase(new PartialEscapePhase(true, canonicalizer));
         }
 
         if (OptConvertDeoptsToGuards.getValue()) {
-            addPhase(new ConvertDeoptimizeToGuardPhase());
+            appendPhase(new ConvertDeoptimizeToGuardPhase());
         }
 
-        addPhase(new LockEliminationPhase());
+        appendPhase(new LockEliminationPhase());
 
         if (OptLoopTransform.getValue()) {
-            addPhase(new LoopTransformHighPhase());
-            addPhase(new LoopTransformLowPhase());
+            appendPhase(new LoopTransformHighPhase());
+            appendPhase(new LoopTransformLowPhase());
         }
-        addPhase(new RemoveValueProxyPhase());
+        appendPhase(new RemoveValueProxyPhase());
 
         if (CullFrameStates.getValue()) {
-            addPhase(new CullFrameStatesPhase());
+            appendPhase(new CullFrameStatesPhase());
         }
 
         if (OptCanonicalizer.getValue()) {
-            addPhase(canonicalizer);
+            appendPhase(canonicalizer);
         }
 
-        addPhase(new LoweringPhase(LoweringType.BEFORE_GUARDS));
+        appendPhase(new LoweringPhase(LoweringType.BEFORE_GUARDS));
     }
 }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LowTier.java	Thu Jun 13 12:52:39 2013 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LowTier.java	Thu Jun 13 18:48:57 2013 +0200
@@ -30,12 +30,12 @@
 public class LowTier extends PhaseSuite<LowTierContext> {
 
     public LowTier() {
-        addPhase(new LoweringPhase(LoweringType.AFTER_GUARDS));
+        appendPhase(new LoweringPhase(LoweringType.AFTER_GUARDS));
 
-        addPhase(new FrameStateAssignmentPhase());
+        appendPhase(new FrameStateAssignmentPhase());
 
-        addPhase(new ExpandLogicPhase());
+        appendPhase(new ExpandLogicPhase());
 
-        addPhase(new DeadCodeEliminationPhase());
+        appendPhase(new DeadCodeEliminationPhase());
     }
 }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/MidTier.java	Thu Jun 13 12:52:39 2013 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/MidTier.java	Thu Jun 13 18:48:57 2013 +0200
@@ -35,50 +35,50 @@
         CanonicalizerPhase canonicalizer = new CanonicalizerPhase(!AOTCompilation.getValue());
 
         if (OptPushThroughPi.getValue()) {
-            addPhase(new PushThroughPiPhase());
+            appendPhase(new PushThroughPiPhase());
             if (OptCanonicalizer.getValue()) {
-                addPhase(canonicalizer);
+                appendPhase(canonicalizer);
             }
         }
 
         if (OptFloatingReads.getValue()) {
             IncrementalCanonicalizerPhase<MidTierContext> incCanonicalizer = new IncrementalCanonicalizerPhase<>();
-            incCanonicalizer.addPhase(new FloatingReadPhase());
-            addPhase(incCanonicalizer);
+            incCanonicalizer.appendPhase(new FloatingReadPhase());
+            appendPhase(incCanonicalizer);
             if (OptReadElimination.getValue()) {
-                addPhase(new ReadEliminationPhase());
+                appendPhase(new ReadEliminationPhase());
             }
         }
-        addPhase(new RemoveValueProxyPhase());
+        appendPhase(new RemoveValueProxyPhase());
 
         if (OptCanonicalizer.getValue()) {
-            addPhase(canonicalizer);
+            appendPhase(canonicalizer);
         }
 
         if (OptEliminatePartiallyRedundantGuards.getValue()) {
-            addPhase(new EliminatePartiallyRedundantGuardsPhase(false, true));
+            appendPhase(new EliminatePartiallyRedundantGuardsPhase(false, true));
         }
 
         if (ConditionalElimination.getValue() && OptCanonicalizer.getValue()) {
-            addPhase(new IterativeConditionalEliminationPhase());
+            appendPhase(new IterativeConditionalEliminationPhase());
         }
 
         if (OptEliminatePartiallyRedundantGuards.getValue()) {
-            addPhase(new EliminatePartiallyRedundantGuardsPhase(true, true));
+            appendPhase(new EliminatePartiallyRedundantGuardsPhase(true, true));
         }
 
         if (OptCanonicalizer.getValue()) {
-            addPhase(canonicalizer);
+            appendPhase(canonicalizer);
         }
 
-        addPhase(new LoopSafepointEliminationPhase());
+        appendPhase(new LoopSafepointEliminationPhase());
 
-        addPhase(new SafepointInsertionPhase());
+        appendPhase(new SafepointInsertionPhase());
 
-        addPhase(new GuardLoweringPhase());
+        appendPhase(new GuardLoweringPhase());
 
         if (OptCanonicalizer.getValue()) {
-            addPhase(canonicalizer);
+            appendPhase(canonicalizer);
         }
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Thu Jun 13 12:52:39 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Thu Jun 13 18:48:57 2013 +0200
@@ -329,6 +329,11 @@
     public int klassOffset;
 
     /**
+     * The offset of the injected array klass field in a {@link Class}.
+     */
+    public int arrayKlassOffset;
+
+    /**
      * The offset of the injected graal_mirror field in a {@link Class}.
      */
     public int graalMirrorInClassOffset;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Thu Jun 13 12:52:39 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Thu Jun 13 18:48:57 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);
@@ -1070,15 +1074,15 @@
 
         if (AOTCompilation.getValue()) {
             // lowering introduces class constants, therefore it must be after lowering
-            ret.getHighTier().addPhase(new LoadJavaMirrorWithKlassPhase());
+            ret.getHighTier().appendPhase(new LoadJavaMirrorWithKlassPhase());
             if (VerifyPhases.getValue()) {
-                ret.getHighTier().addPhase(new AheadOfTimeVerifcationPhase());
+                ret.getHighTier().appendPhase(new AheadOfTimeVerifcationPhase());
             }
         }
 
-        ret.getMidTier().addPhase(new WriteBarrierAdditionPhase());
+        ret.getMidTier().appendPhase(new WriteBarrierAdditionPhase());
         if (VerifyPhases.getValue()) {
-            ret.getMidTier().addPhase(new WriteBarrierVerificationPhase());
+            ret.getMidTier().appendPhase(new WriteBarrierVerificationPhase());
         }
 
         return ret;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java	Thu Jun 13 12:52:39 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java	Thu Jun 13 18:48:57 2013 +0200
@@ -521,6 +521,11 @@
     }
 
     @Fold
+    public static int arrayKlassOffset() {
+        return config().arrayKlassOffset;
+    }
+
+    @Fold
     public static int classMirrorOffset() {
         return config().classMirrorOffset;
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java	Thu Jun 13 12:52:39 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java	Thu Jun 13 18:48:57 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.Unresolved);
+        }
+
+        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	Thu Jun 13 18:48:57 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);
+    }
+}
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java	Thu Jun 13 12:52:39 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java	Thu Jun 13 18:48:57 2013 +0200
@@ -156,7 +156,7 @@
             int mark = graph.getMark();
 
             IncrementalCanonicalizerPhase<PhaseContext> canonicalizer = new IncrementalCanonicalizerPhase<>();
-            canonicalizer.addPhase(round);
+            canonicalizer.appendPhase(round);
             canonicalizer.apply(graph, context);
 
             if (!round.deferred && !containsLowerable(graph.getNewNodes(mark))) {
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/PhaseSuite.java	Thu Jun 13 12:52:39 2013 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/PhaseSuite.java	Thu Jun 13 18:48:57 2013 +0200
@@ -34,7 +34,17 @@
         this.phases = new ArrayList<>();
     }
 
-    public final void addPhase(BasePhase<? super C> phase) {
+    /**
+     * Add a new phase at the beginning of this suite.
+     */
+    public final void prependPhase(BasePhase<? super C> phase) {
+        phases.add(0, phase);
+    }
+
+    /**
+     * Add a new phase at the end of this suite.
+     */
+    public final void appendPhase(BasePhase<? super C> phase) {
         phases.add(phase);
     }
 
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ComputeInliningRelevanceClosure.java	Thu Jun 13 12:52:39 2013 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ComputeInliningRelevanceClosure.java	Thu Jun 13 18:48:57 2013 +0200
@@ -55,14 +55,14 @@
 
         public ComputeInliningRelevanceIterator(StructuredGraph graph) {
             super(graph);
-            this.scopes = computeLowestPathProbabilities();
+            this.scopes = computeScopesAndProbabilities();
         }
 
         @Override
         protected void initializeScope() {
             Scope scope = scopes.get(currentScopeStart);
             parentRelevance = getParentScopeRelevance(scope);
-            currentProbability = scope.minPathProbability;
+            currentProbability = scope.probability;
         }
 
         private double getParentScopeRelevance(Scope scope) {
@@ -72,7 +72,7 @@
                 for (AbstractEndNode end : ((LoopBeginNode) scope.start).forwardEnds()) {
                     parentProbability += nodeProbabilities.get(end);
                 }
-                return parentProbability / scope.parent.minPathProbability;
+                return parentProbability / scope.parent.probability;
             } else {
                 assert scope.parent == null;
                 return 1.0;
@@ -89,11 +89,11 @@
             assert !Double.isNaN(relevance);
         }
 
-        private HashMap<FixedNode, Scope> computeLowestPathProbabilities() {
+        private HashMap<FixedNode, Scope> computeScopesAndProbabilities() {
             HashMap<FixedNode, Scope> result = new HashMap<>();
 
             for (Scope scope : computeScopes()) {
-                scope.minPathProbability = Math.max(EPSILON, nodeProbabilities.get(scope.start));
+                scope.probability = Math.max(EPSILON, nodeProbabilities.get(scope.start));
                 result.put(scope.start, scope);
             }
 
@@ -132,7 +132,7 @@
 
         public final FixedNode start;
         public final Scope parent;
-        public double minPathProbability;
+        public double probability;
 
         public Scope(FixedNode start, Scope parent) {
             this.start = start;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/DynamicNewArrayTest.java	Thu Jun 13 18:48:57 2013 +0200
@@ -0,0 +1,92 @@
+/*
+ * 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.test;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import org.junit.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.test.*;
+
+/**
+ * Tests the implementation of Array.createInstance.
+ */
+public class DynamicNewArrayTest extends GraalCompilerTest {
+
+    private class Element {
+    }
+
+    @Test
+    public void test1() {
+        test("test1snippet");
+    }
+
+    @Test
+    public void test2() {
+        test("test2snippet");
+    }
+
+    @Test
+    public void test3() {
+        test("dynamic", Long.class, 7);
+    }
+
+    @Test
+    public void test4() {
+        test("dynamic", Boolean.class, -7);
+    }
+
+    @Test
+    public void test5() {
+        test("dynamic", byte.class, 7);
+    }
+
+    @Test
+    public void test6() {
+        test("dynamic", null, 5);
+    }
+
+    @Test
+    public void test7() {
+        Method method = getMethod("dynamic");
+        Result actual1 = executeActual(method, null, Element.class, 7);
+        Result actual2 = executeActualCheckDeopt(method, Collections.<DeoptimizationReason> singleton(DeoptimizationReason.Unresolved), null, Element.class, 7);
+        Result expected = executeExpected(method, null, Element.class, 7);
+        assertEquals(actual1, expected);
+        assertEquals(actual2, expected);
+    }
+
+    public static Object test1snippet() {
+        return Array.newInstance(Integer.class, 7);
+    }
+
+    public static Object test2snippet() {
+        return Array.newInstance(char.class, 7);
+    }
+
+    public static Object dynamic(Class<?> elementType, int length) {
+        return Array.newInstance(elementType, length);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ArraySubstitutions.java	Thu Jun 13 18:48:57 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	Thu Jun 13 12:52:39 2013 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraalMethodSubstitutions.java	Thu Jun 13 18:48:57 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);
--- a/src/share/vm/graal/graalCompilerToVM.cpp	Thu Jun 13 12:52:39 2013 +0200
+++ b/src/share/vm/graal/graalCompilerToVM.cpp	Thu Jun 13 18:48:57 2013 +0200
@@ -726,6 +726,7 @@
   set_int("klassModifierFlagsOffset", in_bytes(Klass::modifier_flags_offset()));
   set_int("klassAccessFlagsOffset", in_bytes(Klass::access_flags_offset()));
   set_int("klassOffset", java_lang_Class::klass_offset_in_bytes());
+  set_int("arrayKlassOffset", java_lang_Class::array_klass_offset_in_bytes());
   set_int("graalMirrorInClassOffset", java_lang_Class::graal_mirror_offset_in_bytes());
   set_int("klassLayoutHelperOffset", in_bytes(Klass::layout_helper_offset()));
   set_int("klassSuperKlassOffset", in_bytes(Klass::super_offset()));
--- a/src/share/vm/runtime/compilationPolicy.cpp	Thu Jun 13 12:52:39 2013 +0200
+++ b/src/share/vm/runtime/compilationPolicy.cpp	Thu Jun 13 18:48:57 2013 +0200
@@ -422,6 +422,11 @@
 
   if (is_compilation_enabled() && can_be_compiled(m)) {
     nmethod* nm = m->code();
+#ifdef GRAALVM
+    if (m->queued_for_compilation()) {
+      delay_compilation(m());
+    } else
+#endif
     if (nm == NULL ) {
       CompileBroker::compile_method(m, InvocationEntryBci, comp_level, m, hot_count, comment, thread);
     }