changeset 5760:87e8baf5447c

added snippets for lowering array creation and initialization (in NewObjectSnippets) made it possible to use node intrinsics with arguments that may only be constant when a snippet template is created rename: NewTypeArrayNode -> NewPrimitiveArrayNode removed HotSpotVMConfig.getArrayOffset() - Kind.arrayBaseOffset() is used instead renamed field prototypeHeader to initialMarkWord in HotSpotResolvedJavaType rename: NewInstanceSnippets -> NewObjectSnippets renamed node intrinsics in DirectObjectStoreNode to include the type of the value being stored (to avoid accidental misuse) extended WordTypeRewriterPhase such that ObjectEqualsNodes are replaced with IntegerEqualsNodes when the values being compared are words (which allows '==' and '!=' to be used between Word values in Java source code)
author Doug Simon <doug.simon@oracle.com>
date Tue, 03 Jul 2012 23:49:01 +0200
parents 12706c5b39bc
children 856a54bae703
files graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/JavaType.java graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaUtil.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalOptions.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaType.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotXirGenerator.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CastFromHub.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/InitializeNode.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/InitializeObjectNode.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewArrayStubCall.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewInstanceStubCall.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/TLABAllocateNode.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VerifyOopStubCall.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ArrayCopySnippets.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/CheckCastSnippets.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/DirectObjectStoreNode.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/NewInstanceSnippets.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/NewObjectSnippets.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/AMD64NewInstanceStubCallOp.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/AMD64VerifyOopStubCallOp.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/AMD64NewArrayStubCallOp.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/AMD64NewInstanceStubCallOp.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/AMD64VerifyOopStubCallOp.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/NewPrimitiveArrayNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewTypeArrayNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Snippet.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetInstaller.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetIntrinsificationPhase.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetTemplate.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetVerificationPhase.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/WordTypeRewriterPhase.java graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/NewArrayTest.java src/share/vm/graal/graalCompiler.cpp src/share/vm/graal/graalCompilerToVM.cpp src/share/vm/graal/graalJavaAccess.hpp
diffstat 41 files changed, 1347 insertions(+), 549 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/JavaType.java	Tue Jul 03 18:02:03 2012 +0200
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/JavaType.java	Tue Jul 03 23:49:01 2012 +0200
@@ -65,7 +65,9 @@
 
     /**
      * For array types, gets the type of the components.
-     * @return the component type of this array type
+     * This will be null if this is not an array type.
+     *
+     * @return the component type of this type if it is an array type otherwise null
      */
     JavaType componentType();
 
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaUtil.java	Tue Jul 03 18:02:03 2012 +0200
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaUtil.java	Tue Jul 03 23:49:01 2012 +0200
@@ -25,6 +25,7 @@
 import static java.lang.reflect.Modifier.*;
 
 import java.lang.annotation.*;
+import java.lang.reflect.*;
 import java.util.*;
 
 import com.oracle.graal.api.meta.JavaTypeProfile.ProfiledType;
@@ -308,6 +309,27 @@
 
 
     /**
+     * Gets the annotations of a particular type for the formal parameters of a given method.
+     *
+     * @param annotationClass the Class object corresponding to the annotation type
+     * @param method the method for which a parameter annotations are being requested
+     * @return the annotation of type {@code annotationClass} (if any) for each formal parameter present
+     */
+    public static <T extends Annotation> T[] getParameterAnnotations(Class<T> annotationClass, ResolvedJavaMethod method) {
+        Annotation[][] parameterAnnotations = method.getParameterAnnotations();
+        @SuppressWarnings("unchecked")
+        T[] result = (T[]) Array.newInstance(annotationClass, parameterAnnotations.length);
+        for (int i = 0; i < parameterAnnotations.length; i++) {
+            for (Annotation a : parameterAnnotations[i]) {
+                if (a.annotationType() == annotationClass) {
+                    result[i] = annotationClass.cast(a);
+                }
+            }
+        }
+        return result;
+    }
+
+    /**
      * Gets the annotation of a particular type for a formal parameter of a given method.
      *
      * @param annotationClass the Class object corresponding to the annotation type
@@ -328,7 +350,6 @@
         return null;
     }
 
-
     /**
      * Convenient shortcut for calling {@link #appendLocation(StringBuilder, ResolvedJavaMethod, int)} without having to supply a
      * a {@link StringBuilder} instance and convert the result to a string.
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalOptions.java	Tue Jul 03 18:02:03 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalOptions.java	Tue Jul 03 23:49:01 2012 +0200
@@ -264,6 +264,7 @@
      */
     public static String HIRLowerCheckcast = "";
     public static String HIRLowerNewInstance = "";
+    public static String HIRLowerNewArray = "";
 
     static {
         // turn detailed assertions on when the general assertions are on (misusing the assert keyword for this)
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Tue Jul 03 18:02:03 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Tue Jul 03 23:49:01 2012 +0200
@@ -31,9 +31,9 @@
 import java.util.Map.Entry;
 
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.code.CompilationResult.*;
+import com.oracle.graal.api.code.CompilationResult.Mark;
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.api.meta.JavaType.*;
+import com.oracle.graal.api.meta.JavaType.Representation;
 import com.oracle.graal.compiler.*;
 import com.oracle.graal.compiler.util.*;
 import com.oracle.graal.debug.*;
@@ -590,7 +590,7 @@
     }
 
     @Override
-    public void visitNewTypeArray(NewTypeArrayNode x) {
+    public void visitNewPrimitiveArray(NewPrimitiveArrayNode x) {
         XirArgument length = toXirArgument(x.length());
         XirSnippet snippet = xir.genNewArray(site(x), length, x.elementType().kind(), null, null);
         emitXir(snippet, x, state(), true);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Tue Jul 03 18:02:03 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Tue Jul 03 23:49:01 2012 +0200
@@ -22,8 +22,6 @@
  */
 package com.oracle.graal.hotspot;
 
-import com.oracle.graal.api.meta.*;
-
 /**
  * Used to communicate configuration details, runtime offsets, etc. to graal upon compileMethod.
  */
@@ -46,19 +44,66 @@
     // offsets, ...
     public int vmPageSize;
     public int stackShadowPages;
+
+    /**
+     * The offset of the mark word in an object's header.
+     */
+    public int markOffset;
+
+    /**
+     * The offset of the hub/klassOop word in an object's header.
+     */
     public int hubOffset;
+
+    /**
+     * The offset of an the array length in an array's header.
+     */
+    public int arrayLengthOffset;
+
+    /**
+     * The offset of the _super_check_offset field in a Klass.
+     */
     public int superCheckOffsetOffset;
+
+    /**
+     * The offset of the _secondary_super_cache field in a Klass.
+     */
     public int secondarySuperCacheOffset;
+
+    /**
+     * The offset of the _secondary_supers field in a Klass.
+     */
     public int secondarySupersOffset;
-    public int arrayLengthOffset;
+
+    /**
+     * The offset of the _init_state field in an instanceKlass.
+     */
     public int klassStateOffset;
+
+    /**
+     * The value of instanceKlass::fully_initialized.
+     */
     public int klassStateFullyInitialized;
-    public int[] arrayOffsets;
+
+    /**
+     * The value of objArrayKlass::element_klass_offset().
+     */
     public int arrayClassElementOffset;
+
+    /**
+     * The value of JavaThread::tlab_top_offset().
+     */
     public int threadTlabTopOffset;
+
+    /**
+     * The value of JavaThread::tlab_end_offset().
+     */
     public int threadTlabEndOffset;
+
     public int threadObjectOffset;
+
     public int instanceHeaderPrototypeOffset;
+
     public int threadExceptionOopOffset;
     public int threadExceptionPcOffset;
     public int threadMultiNewArrayStorageOffset;
@@ -110,8 +155,4 @@
         assert codeEntryAlignment > 0;
         assert stackShadowPages > 0;
     }
-
-    public int getArrayOffset(Kind kind) {
-        return arrayOffsets[kind.ordinal()];
-    }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaType.java	Tue Jul 03 18:02:03 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaType.java	Tue Jul 03 23:49:01 2012 +0200
@@ -54,7 +54,11 @@
     private ConstantPool constantPool;
     private boolean isInitialized;
     private ResolvedJavaType arrayOfType;
-    private long prototypeHeader;
+
+    /**
+     * Initial value for the mark word in a new object of this type.
+     */
+    private long initialMarkWord;
 
     private HotSpotResolvedJavaType() {
         throw new GraalInternalError(HotSpotResolvedJavaType.class + " should only be created from C++ code");
@@ -285,7 +289,7 @@
         return superCheckOffset;
     }
 
-    public long prototypeHeader() {
-        return prototypeHeader;
+    public long initialMarkWord() {
+        return initialMarkWord;
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Tue Jul 03 18:02:03 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Tue Jul 03 23:49:01 2012 +0200
@@ -28,10 +28,13 @@
 import java.util.*;
 
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.code.CompilationResult.*;
-import com.oracle.graal.api.code.CodeUtil.*;
+import com.oracle.graal.api.code.CodeUtil.RefMapFormatter;
+import com.oracle.graal.api.code.CompilationResult.Call;
+import com.oracle.graal.api.code.CompilationResult.DataPatch;
+import com.oracle.graal.api.code.CompilationResult.Mark;
+import com.oracle.graal.api.code.CompilationResult.Safepoint;
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.api.meta.JavaType.*;
+import com.oracle.graal.api.meta.JavaType.Representation;
 import com.oracle.graal.compiler.*;
 import com.oracle.graal.compiler.target.*;
 import com.oracle.graal.graph.*;
@@ -57,7 +60,7 @@
     private final HotSpotRegisterConfig globalStubRegConfig;
     private final HotSpotGraalRuntime compiler;
     private CheckCastSnippets.Templates checkcastSnippets;
-    private NewInstanceSnippets.Templates newInstanceSnippets;
+    private NewObjectSnippets.Templates newObjectSnippets;
 
     public HotSpotRuntime(HotSpotVMConfig config, HotSpotGraalRuntime compiler) {
         this.config = config;
@@ -73,9 +76,9 @@
         installer.install(UnsafeSnippets.class);
         installer.install(ArrayCopySnippets.class);
         installer.install(CheckCastSnippets.class);
-        installer.install(NewInstanceSnippets.class);
+        installer.install(NewObjectSnippets.class);
         checkcastSnippets = new CheckCastSnippets.Templates(this);
-        newInstanceSnippets = new NewInstanceSnippets.Templates(this, config.useTLAB);
+        newObjectSnippets = new NewObjectSnippets.Templates(this, compiler.getTarget(), config.useTLAB);
     }
 
 
@@ -373,12 +376,18 @@
             }
         } else if (n instanceof NewInstanceNode) {
             if (shouldLower(graph, GraalOptions.HIRLowerNewInstance)) {
-                newInstanceSnippets.lower((NewInstanceNode) n, tool);
+                newObjectSnippets.lower((NewInstanceNode) n, tool);
+            }
+        } else if (n instanceof NewArrayNode) {
+            if (shouldLower(graph, GraalOptions.HIRLowerNewArray)) {
+                newObjectSnippets.lower((NewArrayNode) n, tool);
             }
         } else if (n instanceof TLABAllocateNode) {
-            newInstanceSnippets.lower((TLABAllocateNode) n, tool);
-        } else if (n instanceof InitializeNode) {
-            newInstanceSnippets.lower((InitializeNode) n, tool);
+            newObjectSnippets.lower((TLABAllocateNode) n, tool);
+        } else if (n instanceof InitializeObjectNode) {
+            newObjectSnippets.lower((InitializeObjectNode) n, tool);
+        } else if (n instanceof InitializeArrayNode) {
+            newObjectSnippets.lower((InitializeArrayNode) n, tool);
         } else {
             assert false : "Node implementing Lowerable not handled: " + n;
         }
@@ -395,8 +404,8 @@
         return false;
     }
 
-    private IndexedLocationNode createArrayLocation(Graph graph, Kind elementKind, ValueNode index) {
-        return IndexedLocationNode.create(LocationNode.getArrayLocation(elementKind), elementKind, config.getArrayOffset(elementKind), index, graph, true);
+    private static IndexedLocationNode createArrayLocation(Graph graph, Kind elementKind, ValueNode index) {
+        return IndexedLocationNode.create(LocationNode.getArrayLocation(elementKind), elementKind, elementKind.arrayBaseOffset(), index, graph, true);
     }
 
     private SafeReadNode safeReadArrayLength(ValueNode array, long leafGraphId) {
@@ -528,6 +537,7 @@
 
     @Override
     public int convertDeoptAction(DeoptimizationAction action) {
+        // This must be kept in sync with the DeoptAction enum defined in deoptimization.hpp
         switch(action) {
             case None: return 0;
             case RecompileIfTooManyDeopts: return 1;
@@ -540,6 +550,7 @@
 
     @Override
     public int convertDeoptReason(DeoptimizationReason reason) {
+        // This must be kept in sync with the DeoptReason enum defined in deoptimization.hpp
         switch(reason) {
             case None: return 0;
             case NullCheckException: return 1;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotXirGenerator.java	Tue Jul 03 18:02:03 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotXirGenerator.java	Tue Jul 03 23:49:01 2012 +0200
@@ -315,7 +315,7 @@
             asm.bindInline(resume);
 
             asm.pload(target.wordKind, temp1, hub, asm.i(config.instanceHeaderPrototypeOffset), false);
-            asm.pstore(target.wordKind, result, temp1, false);
+            asm.pstore(target.wordKind, result, asm.i(config.markOffset), temp1, false);
             asm.mov(temp1o, hub); // need a temporary register since Intel cannot store 64-bit constants to memory
             asm.pstore(Kind.Object, result, asm.i(config.hubOffset), temp1o, false);
 
@@ -378,7 +378,7 @@
 
             final int aligning = target.wordSize;
             final int arrayLengthOffset = target.wordSize * 2;
-            final int arrayElementOffset = config.getArrayOffset(kind);
+            final int arrayElementOffset = kind.arrayBaseOffset();
 
             // Calculate aligned size
             asm.mov(size, length);
@@ -401,7 +401,7 @@
 
             // Now the new object is in result, store mark word and klass
             asm.pload(target.wordKind, temp1, hub, asm.i(config.instanceHeaderPrototypeOffset), false);
-            asm.pstore(target.wordKind, result, temp1, false);
+            asm.pstore(target.wordKind, result, asm.i(config.markOffset), temp1, false);
             asm.mov(temp1o, hub); // need a temporary register since Intel cannot store 64-bit constants to memory
             asm.pstore(Kind.Object, result, asm.i(config.hubOffset), temp1o, false);
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CastFromHub.java	Tue Jul 03 18:02:03 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CastFromHub.java	Tue Jul 03 23:49:01 2012 +0200
@@ -32,7 +32,7 @@
 import com.oracle.graal.nodes.type.*;
 
 /**
- * This node is used by the {@link NewInstanceSnippets} to give a formatted new instance its exact type.
+ * This node is used by the {@link NewObjectSnippets} to give a formatted new instance or object its exact type.
  */
 public final class CastFromHub extends FloatingNode implements Canonicalizable {
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/InitializeArrayNode.java	Tue Jul 03 23:49:01 2012 +0200
@@ -0,0 +1,77 @@
+/*
+ * 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.meta.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
+
+/**
+ * Initializes the header and body of an uninitialized array cell.
+ * This node calls out to a stub to do both the allocation and formatting
+ * if the memory address it is given is zero/null (e.g. due to
+ * {@linkplain TLABAllocateNode TLAB allocation} failing).
+ */
+public final class InitializeArrayNode extends FixedWithNextNode implements Lowerable {
+
+    @Input private final ValueNode memory;
+    @Input private final ValueNode length;
+    @Input private final ValueNode size;
+    private final ResolvedJavaType type;
+
+    public InitializeArrayNode(ValueNode memory, ValueNode length, ValueNode size, ResolvedJavaType type) {
+        super(StampFactory.exactNonNull(type));
+        this.memory = memory;
+        this.type = type;
+        this.length = length;
+        this.size = size;
+    }
+
+    public ValueNode memory() {
+        return memory;
+    }
+
+    public ValueNode length() {
+        return length;
+    }
+
+    public ValueNode size() {
+        return size;
+    }
+
+    public ResolvedJavaType type() {
+        return type;
+    }
+
+    @Override
+    public void lower(LoweringTool tool) {
+        tool.getRuntime().lower(this, tool);
+    }
+
+    @SuppressWarnings("unused")
+    @NodeIntrinsic
+    public static Object initialize(Object memory, int length, int size, @ConstantNodeParameter ResolvedJavaType type) {
+        throw new UnsupportedOperationException();
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/InitializeNode.java	Tue Jul 03 18:02:03 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-/*
- * 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.meta.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.type.*;
-
-/**
- * Initializes the header and body of an uninitialized object cell.
- * This node calls out to a stub to do both the allocation and formatting
- * if the memory address it is given is zero/null (e.g. due to
- * {@linkplain TLABAllocateNode TLAB allocation} failing).
- */
-public final class InitializeNode extends FixedWithNextNode implements Lowerable {
-
-    @Input private final ValueNode memory;
-    private final ResolvedJavaType type;
-
-    public InitializeNode(ValueNode memory, ResolvedJavaType type) {
-        super(StampFactory.exactNonNull(type));
-        this.memory = memory;
-        this.type = type;
-    }
-
-    public ValueNode memory() {
-        return memory;
-    }
-
-    public ResolvedJavaType type() {
-        return type;
-    }
-
-    @Override
-    public void lower(LoweringTool tool) {
-        tool.getRuntime().lower(this, tool);
-    }
-
-    @SuppressWarnings("unused")
-    @NodeIntrinsic
-    public static Object initialize(Object memory, @ConstantNodeParameter ResolvedJavaType type) {
-        throw new UnsupportedOperationException();
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/InitializeObjectNode.java	Tue Jul 03 23:49:01 2012 +0200
@@ -0,0 +1,59 @@
+/*
+ * 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.meta.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
+
+/**
+ * Initializes the header and body of an uninitialized object cell.
+ * This node calls out to a stub to do both the allocation and formatting
+ * if the memory address it is given is zero/null (e.g. due to
+ * {@linkplain TLABAllocateNode TLAB allocation} failing).
+ */
+public final class InitializeObjectNode extends FixedWithNextNode implements Lowerable {
+
+    @Input private final ValueNode memory;
+    private final ResolvedJavaType type;
+
+    public InitializeObjectNode(ValueNode memory, ResolvedJavaType type) {
+        super(StampFactory.exactNonNull(type));
+        this.memory = memory;
+        this.type = type;
+    }
+
+    public ValueNode memory() {
+        return memory;
+    }
+
+    public ResolvedJavaType type() {
+        return type;
+    }
+
+    @Override
+    public void lower(LoweringTool tool) {
+        tool.getRuntime().lower(this, tool);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewArrayStubCall.java	Tue Jul 03 23:49:01 2012 +0200
@@ -0,0 +1,85 @@
+/*
+ * 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 static com.oracle.graal.hotspot.target.amd64.AMD64NewArrayStubCallOp.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.gen.*;
+import com.oracle.graal.compiler.target.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.target.amd64.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.type.*;
+
+/**
+ * Node implementing a call to HotSpot's {@code new_[object|type]_array} stub.
+ *
+ * @see AMD64NewArrayStubCallOp
+ */
+public class NewArrayStubCall extends FixedWithNextNode implements LIRGenLowerable {
+
+    private static final Stamp defaultStamp = StampFactory.objectNonNull();
+
+    @Input private final ValueNode hub;
+    @Input private final ValueNode length;
+    private final boolean isObjectArray;
+
+    public NewArrayStubCall(boolean isObjectArray, ValueNode hub, ValueNode length) {
+        super(defaultStamp);
+        this.isObjectArray = isObjectArray;
+        this.hub = hub;
+        this.length = length;
+    }
+
+    @Override
+    public boolean inferStamp() {
+        if (stamp() == defaultStamp && hub.isConstant()) {
+            HotSpotKlassOop klassOop = (HotSpotKlassOop) this.hub.asConstant().asObject();
+            updateStamp(StampFactory.exactNonNull(klassOop.type));
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public void generate(LIRGenerator gen) {
+        RegisterValue hubFixed = HUB.asValue(Kind.Object);
+        RegisterValue lengthFixed = LENGTH.asValue(Kind.Int);
+        RegisterValue resultFixed = RESULT.asValue(Kind.Object);
+        gen.emitMove(gen.operand(length), lengthFixed);
+        gen.emitMove(gen.operand(hub), hubFixed);
+        LIRFrameState info = gen.state();
+        gen.append(new AMD64NewArrayStubCallOp(isObjectArray, resultFixed, hubFixed, lengthFixed, info));
+        Variable result = gen.emitMove(resultFixed);
+        gen.setResult(this, result);
+    }
+
+    @SuppressWarnings("unused")
+    @NodeIntrinsic
+    public static Object call(@ConstantNodeParameter boolean isObjectArray, Object hub, int length) {
+        throw new UnsupportedOperationException();
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewInstanceStubCall.java	Tue Jul 03 18:02:03 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewInstanceStubCall.java	Tue Jul 03 23:49:01 2012 +0200
@@ -22,15 +22,17 @@
  */
 package com.oracle.graal.hotspot.nodes;
 
+import static com.oracle.graal.hotspot.target.amd64.AMD64NewInstanceStubCallOp.*;
+
+import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.gen.*;
 import com.oracle.graal.compiler.target.*;
 import com.oracle.graal.hotspot.*;
-import com.oracle.graal.hotspot.target.*;
+import com.oracle.graal.hotspot.target.amd64.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.type.*;
-import com.oracle.max.asm.target.amd64.*;
 
 /**
  * Node implementing a call to HotSpot's {@code new_instance} stub.
@@ -60,11 +62,12 @@
 
     @Override
     public void generate(LIRGenerator gen) {
-        Variable result = gen.newVariable(Kind.Object);
-        gen.emitMove(gen.operand(hub), AMD64.rdx.asValue(Kind.Object));
+        RegisterValue hubFixed = HUB.asValue(Kind.Object);
+        RegisterValue resultFixed = RESULT.asValue(Kind.Object);
+        gen.emitMove(gen.operand(hub), hubFixed);
         LIRFrameState info = gen.state();
-        AMD64NewInstanceStubCallOp op = new AMD64NewInstanceStubCallOp(result, AMD64.rdx.asValue(Kind.Object), info);
-        gen.append(op);
+        gen.append(new AMD64NewInstanceStubCallOp(resultFixed, hubFixed, info));
+        Variable result = gen.emitMove(resultFixed);
         gen.setResult(this, result);
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/TLABAllocateNode.java	Tue Jul 03 18:02:03 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/TLABAllocateNode.java	Tue Jul 03 23:49:01 2012 +0200
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.hotspot.nodes;
 
+import java.util.*;
+
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
@@ -35,27 +37,61 @@
 public final class TLABAllocateNode extends FixedWithNextNode implements Lowerable {
 
     private final int size;
+    @Input private ValueNode sizeNode;
 
     public TLABAllocateNode(int size, Kind wordKind) {
         super(StampFactory.forWord(wordKind, true));
         this.size = size;
+        this.sizeNode = null;
+    }
+
+    public TLABAllocateNode(Kind wordKind, ValueNode size) {
+        super(StampFactory.forWord(wordKind, true));
+        this.size = -1;
+        this.sizeNode = size;
     }
 
-    public int size() {
+    public boolean isSizeConstant() {
+        return sizeNode == null;
+    }
+
+    public int constantSize() {
+        assert isSizeConstant();
         return size;
     }
 
+    public ValueNode variableSize() {
+        assert !isSizeConstant();
+        return sizeNode;
+    }
+
     @Override
     public void lower(LoweringTool tool) {
         tool.getRuntime().lower(this, tool);
     }
 
+    @Override
+    public Map<Object, Object> getDebugProperties() {
+        Map<Object, Object> debugProperties = super.getDebugProperties();
+        debugProperties.put("size", String.valueOf(size));
+        return debugProperties;
+    }
+
     /**
      * @return null if allocation fails
      */
     @SuppressWarnings("unused")
     @NodeIntrinsic
-    public static Word allocate(@ConstantNodeParameter int size, @ConstantNodeParameter Kind wordKind) {
+    public static Word allocateConstantSize(@ConstantNodeParameter int size, @ConstantNodeParameter Kind wordKind) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * @return null if allocation fails
+     */
+    @SuppressWarnings("unused")
+    @NodeIntrinsic
+    public static Word allocateVariableSize(@ConstantNodeParameter Kind wordKind, int size) {
         throw new UnsupportedOperationException();
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VerifyOopStubCall.java	Tue Jul 03 18:02:03 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VerifyOopStubCall.java	Tue Jul 03 23:49:01 2012 +0200
@@ -22,9 +22,13 @@
  */
 package com.oracle.graal.hotspot.nodes;
 
+import static com.oracle.graal.hotspot.target.amd64.AMD64VerifyOopStubCallOp.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.gen.*;
 import com.oracle.graal.compiler.target.*;
-import com.oracle.graal.hotspot.target.*;
+import com.oracle.graal.hotspot.target.amd64.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.type.*;
@@ -45,9 +49,10 @@
 
     @Override
     public void generate(LIRGenerator gen) {
+        RegisterValue objectFixed = OBJECT.asValue(Kind.Object);
+        gen.emitMove(gen.operand(object), objectFixed);
         LIRFrameState info = gen.state();
-        AMD64VerifyOopStubCallOp op = new AMD64VerifyOopStubCallOp(gen.operand(object), info);
-        gen.append(op);
+        gen.append(new AMD64VerifyOopStubCallOp(gen.operand(object), info));
     }
 
     @SuppressWarnings("unused")
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ArrayCopySnippets.java	Tue Jul 03 18:02:03 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ArrayCopySnippets.java	Tue Jul 03 23:49:01 2012 +0200
@@ -312,12 +312,12 @@
         if (src == dest && srcPos < destPos) { // bad aliased case
             for (long i = (length - 1) * scale; i >= 0; i -= scale) {
                 Object a = UnsafeLoadNode.load(src, header, i + (long) srcPos * scale, Kind.Object);
-                DirectObjectStoreNode.store(dest, header, i + (long) destPos * scale, a);
+                DirectObjectStoreNode.storeObject(dest, header, i + (long) destPos * scale, a);
             }
         } else {
             for (long i = 0; i < length * scale; i += scale) {
                 Object a = UnsafeLoadNode.load(src, header, i + (long) srcPos * scale, Kind.Object);
-                DirectObjectStoreNode.store(dest, header, i + (long) destPos * scale, a);
+                DirectObjectStoreNode.storeObject(dest, header, i + (long) destPos * scale, a);
             }
         }
         if (length > 0) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/CheckCastSnippets.java	Tue Jul 03 18:02:03 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/CheckCastSnippets.java	Tue Jul 03 23:49:01 2012 +0200
@@ -174,7 +174,7 @@
 
         for (int i = 0; i < secondarySupers.length; i++) {
             if (t == loadNonNullObjectElement(secondarySupers, i)) {
-                DirectObjectStoreNode.store(s, secondarySuperCacheOffset(), 0, t);
+                DirectObjectStoreNode.storeObject(s, secondarySuperCacheOffset(), 0, t);
                 secondariesHit.inc();
                 return true;
             }
@@ -214,7 +214,7 @@
         Object[] secondarySupers = UnsafeCastNode.cast(UnsafeLoadNode.loadObject(s, 0, secondarySupersOffset(), true), Object[].class);
         for (int i = 0; i < secondarySupers.length; i++) {
             if (t == loadNonNullObjectElement(secondarySupers, i)) {
-                DirectObjectStoreNode.store(s, secondarySuperCacheOffset(), 0, t);
+                DirectObjectStoreNode.storeObject(s, secondarySuperCacheOffset(), 0, t);
                 secondariesHit.inc();
                 return true;
             }
@@ -264,7 +264,7 @@
          */
         void inc() {
             if (ENABLED) {
-                DirectObjectStoreNode.store(this, countOffset(), 0, count + 1);
+                DirectObjectStoreNode.storeLong(this, countOffset(), 0, count + 1);
             }
         }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/DirectObjectStoreNode.java	Tue Jul 03 18:02:03 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/DirectObjectStoreNode.java	Tue Jul 03 23:49:01 2012 +0200
@@ -26,6 +26,7 @@
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
+import com.oracle.graal.snippets.*;
 
 /**
  * A special purpose store node that differs from {@link UnsafeStoreNode} in that
@@ -47,13 +48,25 @@
 
     @SuppressWarnings("unused")
     @NodeIntrinsic
-    public static void store(Object obj, @ConstantNodeParameter int displacement, long offset, Object value) {
+    public static void storeObject(Object obj, @ConstantNodeParameter int displacement, long offset, Object value) {
         throw new UnsupportedOperationException();
     }
 
     @SuppressWarnings("unused")
     @NodeIntrinsic
-    public static void store(Object obj, @ConstantNodeParameter int displacement, long offset, long value) {
+    public static void storeLong(Object obj, @ConstantNodeParameter int displacement, long offset, long value) {
+        throw new UnsupportedOperationException();
+    }
+
+    @SuppressWarnings("unused")
+    @NodeIntrinsic
+    public static void storeWord(Object obj, @ConstantNodeParameter int displacement, long offset, Word value) {
+        throw new UnsupportedOperationException();
+    }
+
+    @SuppressWarnings("unused")
+    @NodeIntrinsic
+    public static void storeInt(Object obj, @ConstantNodeParameter int displacement, long offset, int value) {
         throw new UnsupportedOperationException();
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/NewInstanceSnippets.java	Tue Jul 03 18:02:03 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,229 +0,0 @@
-/*
- * 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.snippets;
-
-import static com.oracle.graal.hotspot.nodes.CastFromHub.*;
-import static com.oracle.graal.hotspot.nodes.RegisterNode.*;
-import static com.oracle.graal.hotspot.snippets.DirectObjectStoreNode.*;
-import static com.oracle.graal.nodes.extended.UnsafeLoadNode.*;
-import static com.oracle.graal.snippets.SnippetTemplate.Arguments.*;
-import static com.oracle.graal.snippets.nodes.ExplodeLoopNode.*;
-import static com.oracle.max.asm.target.amd64.AMD64.*;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.debug.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.hotspot.*;
-import com.oracle.graal.hotspot.meta.*;
-import com.oracle.graal.hotspot.nodes.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.java.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.snippets.*;
-import com.oracle.graal.snippets.Snippet.ConstantParameter;
-import com.oracle.graal.snippets.Snippet.Fold;
-import com.oracle.graal.snippets.Snippet.Parameter;
-import com.oracle.graal.snippets.SnippetTemplate.Arguments;
-import com.oracle.graal.snippets.SnippetTemplate.Cache;
-import com.oracle.graal.snippets.SnippetTemplate.Key;
-
-/**
- * Snippets used for implementing NEW.
- */
-public class NewInstanceSnippets implements SnippetsInterface {
-
-    @Snippet
-    public static Word allocate(@ConstantParameter("size") int size) {
-        Word thread = asWord(register(r15, wordKind()));
-        Word top = loadWord(thread, threadTlabTopOffset());
-        Word end = loadWord(thread, threadTlabEndOffset());
-        Word newTop = top.plus(size);
-        if (newTop.belowOrEqual(end)) {
-            store(thread, 0, threadTlabTopOffset(), newTop);
-            return top;
-        }
-        return Word.zero();
-    }
-
-    @Snippet
-    public static Object initialize(
-                    @Parameter("memory") Word memory,
-                    @Parameter("hub") Object hub,
-                    @Parameter("prototypeHeader") Word headerPrototype,
-                    @ConstantParameter("size") int size) {
-
-        if (memory == Word.zero()) {
-            return NewInstanceStubCall.call(hub);
-        }
-        formatObject(hub, size, memory, headerPrototype);
-        Object instance = memory.toObject();
-        return castFromHub(verifyOop(instance), hub);
-    }
-
-    private static Object verifyOop(Object object) {
-        if (verifyOops()) {
-            VerifyOopStubCall.call(object);
-        }
-        return object;
-    }
-
-    private static Word asWord(Object object) {
-        return Word.fromObject(object);
-    }
-
-    private static Word loadWord(Word address, int offset) {
-        Object value = loadObject(address, 0, offset, true);
-        return asWord(value);
-    }
-
-    /**
-     * Maximum size of an object whose body is initialized by a sequence of
-     * zero-stores to its fields. Larger objects have their bodies initialized
-     * in a loop.
-     */
-    private static final int MAX_UNROLLED_OBJECT_INITIALIZATION_SIZE = 10 * wordSize();
-
-    /**
-     * Formats some allocated memory with an object header zeroes out the rest.
-     */
-    private static void formatObject(Object hub, int size, Word memory, Word headerPrototype) {
-        store(memory, 0, 0, headerPrototype);
-        store(memory, 0, hubOffset(), hub);
-        if (size <= MAX_UNROLLED_OBJECT_INITIALIZATION_SIZE) {
-            explodeLoop();
-            for (int offset = 2 * wordSize(); offset < size; offset += wordSize()) {
-                store(memory, 0, offset, 0);
-            }
-        } else {
-            for (int offset = 2 * wordSize(); offset < size; offset += wordSize()) {
-                store(memory, 0, offset, 0);
-            }
-        }
-    }
-
-    @Fold
-    private static boolean verifyOops() {
-        return HotSpotGraalRuntime.getInstance().getConfig().verifyOops;
-    }
-
-    @Fold
-    private static int threadTlabTopOffset() {
-        return HotSpotGraalRuntime.getInstance().getConfig().threadTlabTopOffset;
-    }
-
-    @Fold
-    private static int threadTlabEndOffset() {
-        return HotSpotGraalRuntime.getInstance().getConfig().threadTlabEndOffset;
-    }
-
-    @Fold
-    private static Kind wordKind() {
-        return HotSpotGraalRuntime.getInstance().getTarget().wordKind;
-    }
-
-    @Fold
-    private static int wordSize() {
-        return HotSpotGraalRuntime.getInstance().getTarget().wordSize;
-    }
-
-    @Fold
-    private static int hubOffset() {
-        return HotSpotGraalRuntime.getInstance().getConfig().hubOffset;
-    }
-
-    public static class Templates {
-
-        private final Cache cache;
-        private final ResolvedJavaMethod allocate;
-        private final ResolvedJavaMethod initialize;
-        private final CodeCacheProvider runtime;
-        private final boolean useTLAB;
-
-        public Templates(CodeCacheProvider runtime, boolean useTLAB) {
-            this.runtime = runtime;
-            this.cache = new Cache(runtime);
-            this.useTLAB = useTLAB;
-            try {
-                allocate = runtime.getResolvedJavaMethod(NewInstanceSnippets.class.getDeclaredMethod("allocate", int.class));
-                initialize = runtime.getResolvedJavaMethod(NewInstanceSnippets.class.getDeclaredMethod("initialize", Word.class, Object.class, Word.class, int.class));
-            } catch (NoSuchMethodException e) {
-                throw new GraalInternalError(e);
-            }
-        }
-
-        /**
-         * Lowers a {@link NewInstanceNode}.
-         */
-        @SuppressWarnings("unused")
-        public void lower(NewInstanceNode newInstanceNode, LoweringTool tool) {
-            StructuredGraph graph = (StructuredGraph) newInstanceNode.graph();
-            HotSpotResolvedJavaType type = (HotSpotResolvedJavaType) newInstanceNode.instanceClass();
-            HotSpotKlassOop hub = type.klassOop();
-            int size = type.instanceSize();
-            assert (size % wordSize()) == 0;
-            assert size >= 0;
-
-            ValueNode memory;
-            if (!useTLAB) {
-                memory = ConstantNode.forObject(null, runtime, graph);
-            } else {
-                TLABAllocateNode tlabAllocateNode = graph.add(new TLABAllocateNode(size, wordKind()));
-                graph.addBeforeFixed(newInstanceNode, tlabAllocateNode);
-                memory = tlabAllocateNode;
-            }
-            InitializeNode initializeNode = graph.add(new InitializeNode(memory, type));
-            graph.replaceFixedWithFixed(newInstanceNode, initializeNode);
-        }
-
-        @SuppressWarnings("unused")
-        public void lower(TLABAllocateNode tlabAllocateNode, LoweringTool tool) {
-            StructuredGraph graph = (StructuredGraph) tlabAllocateNode.graph();
-            int size = tlabAllocateNode.size();
-            assert (size % wordSize()) == 0;
-            assert size >= 0;
-            Key key = new Key(allocate).add("size", size);
-            Arguments arguments = new Arguments();
-            SnippetTemplate template = cache.get(key);
-            Debug.log("Lowering fastAllocate in %s: node=%s, template=%s, arguments=%s", graph, tlabAllocateNode, template, arguments);
-            template.instantiate(runtime, tlabAllocateNode, tlabAllocateNode, arguments);
-        }
-
-        @SuppressWarnings("unused")
-        public void lower(InitializeNode initializeNode, LoweringTool tool) {
-            StructuredGraph graph = (StructuredGraph) initializeNode.graph();
-            HotSpotResolvedJavaType type = (HotSpotResolvedJavaType) initializeNode.type();
-            HotSpotKlassOop hub = type.klassOop();
-            int size = type.instanceSize();
-            assert (size % wordSize()) == 0;
-            assert size >= 0;
-            Key key = new Key(initialize).add("size", size);
-            ValueNode memory = initializeNode.memory();
-            //assert memory instanceof AllocateNode || memory instanceof ConstantNode : memory;
-            Arguments arguments = arguments("memory", memory).add("hub", hub).add("prototypeHeader", type.prototypeHeader());
-            SnippetTemplate template = cache.get(key);
-            Debug.log("Lowering initialize in %s: node=%s, template=%s, arguments=%s", graph, initializeNode, template, arguments);
-            template.instantiate(runtime, initializeNode, initializeNode, arguments);
-        }
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/NewObjectSnippets.java	Tue Jul 03 23:49:01 2012 +0200
@@ -0,0 +1,383 @@
+/*
+ * 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.snippets;
+
+import static com.oracle.graal.hotspot.nodes.CastFromHub.*;
+import static com.oracle.graal.hotspot.nodes.RegisterNode.*;
+import static com.oracle.graal.hotspot.snippets.DirectObjectStoreNode.*;
+import static com.oracle.graal.nodes.extended.UnsafeLoadNode.*;
+import static com.oracle.graal.snippets.SnippetTemplate.Arguments.*;
+import static com.oracle.graal.snippets.nodes.ExplodeLoopNode.*;
+import static com.oracle.max.asm.target.amd64.AMD64.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.hotspot.nodes.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.java.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.snippets.*;
+import com.oracle.graal.snippets.Snippet.ConstantParameter;
+import com.oracle.graal.snippets.Snippet.Fold;
+import com.oracle.graal.snippets.Snippet.Parameter;
+import com.oracle.graal.snippets.SnippetTemplate.Arguments;
+import com.oracle.graal.snippets.SnippetTemplate.Cache;
+import com.oracle.graal.snippets.SnippetTemplate.Key;
+import com.oracle.max.criutils.*;
+
+/**
+ * Snippets used for implementing NEW, ANEWARRAY and NEWARRAY.
+ */
+public class NewObjectSnippets implements SnippetsInterface {
+
+    @Snippet
+    public static Word allocate(@Parameter("size") int size) {
+        Word thread = asWord(register(r15, wordKind()));
+        Word top = loadWord(thread, threadTlabTopOffset());
+        Word end = loadWord(thread, threadTlabEndOffset());
+        Word newTop = top.plus(size);
+        if (newTop.belowOrEqual(end)) {
+            storeObject(thread, 0, threadTlabTopOffset(), newTop);
+            return top;
+        }
+        return Word.zero();
+    }
+
+    @Snippet
+    public static Object initializeObject(
+                    @Parameter("memory") Word memory,
+                    @Parameter("hub") Object hub,
+                    @Parameter("initialMarkWord") Word initialMarkWord,
+                    @ConstantParameter("size") int size) {
+
+        if (memory == Word.zero()) {
+            return NewInstanceStubCall.call(hub);
+        }
+        formatObject(hub, size, memory, initialMarkWord);
+        Object instance = memory.toObject();
+        return castFromHub(verifyOop(instance), hub);
+    }
+
+    @Snippet
+    public static Object initializeObjectArray(
+                    @Parameter("memory") Word memory,
+                    @Parameter("hub") Object hub,
+                    @Parameter("length") int length,
+                    @Parameter("size") int size,
+                    @Parameter("initialMarkWord") Word initialMarkWord,
+                    @ConstantParameter("headerSize") int headerSize) {
+        return initializeArray(memory, hub, length, size, initialMarkWord, headerSize, true);
+    }
+
+    @Snippet
+    public static Object initializePrimitiveArray(
+                    @Parameter("memory") Word memory,
+                    @Parameter("hub") Object hub,
+                    @Parameter("length") int length,
+                    @Parameter("size") int size,
+                    @Parameter("initialMarkWord") Word initialMarkWord,
+                    @ConstantParameter("headerSize") int headerSize) {
+        return initializeArray(memory, hub, length, size, initialMarkWord, headerSize, false);
+    }
+
+    private static Object initializeArray(Word memory, Object hub, int length, int size, Word initialMarkWord, int headerSize, boolean isObjectArray) {
+        if (memory == Word.zero()) {
+            return NewArrayStubCall.call(isObjectArray, hub, length);
+        }
+        formatArray(hub, size, length, headerSize, memory, initialMarkWord);
+        Object instance = memory.toObject();
+        return castFromHub(verifyOop(instance), hub);
+    }
+
+    /**
+     * Maximum array length for which fast path allocation is used.
+     */
+    private static final int MAX_ARRAY_FAST_PATH_ALLOCATION_LENGTH = 0x00FFFFFF;
+
+    @Snippet
+    public static Object allocateArrayAndInitialize(
+                    @Parameter("length") int length,
+                    @ConstantParameter("alignment") int alignment,
+                    @ConstantParameter("headerSize") int headerSize,
+                    @ConstantParameter("log2ElementSize") int log2ElementSize,
+                    @ConstantParameter("type") ResolvedJavaType type,
+                    @ConstantParameter("wordKind") Kind wordKind) {
+        if (UnsignedMath.aboveOrEqual(length, MAX_ARRAY_FAST_PATH_ALLOCATION_LENGTH)) {
+            // This handles both negative array sizes and very large array sizes
+            DeoptimizeNode.deopt(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.RuntimeConstraint);
+        }
+        int size = getArraySize(length, alignment, headerSize, log2ElementSize);
+        Word memory = TLABAllocateNode.allocateVariableSize(wordKind, size);
+        return InitializeArrayNode.initialize(memory, length, size, type);
+    }
+
+    public static int getArraySize(int length, int alignment, int headerSize, int log2ElementSize) {
+        int size = (length << log2ElementSize) + headerSize + (alignment - 1);
+        int mask = ~(alignment - 1);
+        return size & mask;
+    }
+
+    private static Object verifyOop(Object object) {
+        if (verifyOops()) {
+            VerifyOopStubCall.call(object);
+        }
+        return object;
+    }
+
+    private static Word asWord(Object object) {
+        return Word.fromObject(object);
+    }
+
+    private static Word loadWord(Word address, int offset) {
+        Object value = loadObject(address, 0, offset, true);
+        return asWord(value);
+    }
+
+    /**
+     * Maximum size of an object whose body is initialized by a sequence of
+     * zero-stores to its fields. Larger objects have their bodies initialized
+     * in a loop.
+     */
+    private static final int MAX_UNROLLED_OBJECT_ZEROING_SIZE = 10 * wordSize();
+
+    /**
+     * Formats some allocated memory with an object header zeroes out the rest.
+     */
+    private static void formatObject(Object hub, int size, Word memory, Word headerPrototype) {
+        storeObject(memory, 0, markOffset(), headerPrototype);
+        storeObject(memory, 0, hubOffset(), hub);
+        if (size <= MAX_UNROLLED_OBJECT_ZEROING_SIZE) {
+            explodeLoop();
+            for (int offset = 2 * wordSize(); offset < size; offset += wordSize()) {
+                storeWord(memory, 0, offset, Word.zero());
+            }
+        } else {
+            for (int offset = 2 * wordSize(); offset < size; offset += wordSize()) {
+                storeWord(memory, 0, offset, Word.zero());
+            }
+        }
+    }
+
+    /**
+     * Formats some allocated memory with an object header zeroes out the rest.
+     */
+    private static void formatArray(Object hub, int size, int length, int headerSize, Word memory, Word headerPrototype) {
+        storeObject(memory, 0, markOffset(), headerPrototype);
+        storeObject(memory, 0, hubOffset(), hub);
+        storeInt(memory, 0, arrayLengthOffset(), length);
+        for (int offset = headerSize; offset < size; offset += wordSize()) {
+            storeWord(memory, 0, offset, Word.zero());
+        }
+    }
+
+    public static class Templates {
+
+        private final Cache cache;
+        private final ResolvedJavaMethod allocate;
+        private final ResolvedJavaMethod initializeObject;
+        private final ResolvedJavaMethod initializeObjectArray;
+        private final ResolvedJavaMethod initializePrimitiveArray;
+        private final ResolvedJavaMethod allocateArrayAndInitialize;
+        private final TargetDescription target;
+        private final CodeCacheProvider runtime;
+        private final boolean useTLAB;
+
+        public Templates(CodeCacheProvider runtime, TargetDescription target, boolean useTLAB) {
+            this.runtime = runtime;
+            this.target = target;
+            this.cache = new Cache(runtime);
+            this.useTLAB = useTLAB;
+            try {
+                allocate = runtime.getResolvedJavaMethod(NewObjectSnippets.class.getDeclaredMethod("allocate", int.class));
+                initializeObject = runtime.getResolvedJavaMethod(NewObjectSnippets.class.getDeclaredMethod("initializeObject", Word.class, Object.class, Word.class, int.class));
+                initializeObjectArray = runtime.getResolvedJavaMethod(NewObjectSnippets.class.getDeclaredMethod("initializeObjectArray", Word.class, Object.class, int.class, int.class, Word.class, int.class));
+                initializePrimitiveArray = runtime.getResolvedJavaMethod(NewObjectSnippets.class.getDeclaredMethod("initializePrimitiveArray", Word.class, Object.class, int.class, int.class, Word.class, int.class));
+                allocateArrayAndInitialize = runtime.getResolvedJavaMethod(NewObjectSnippets.class.getDeclaredMethod("allocateArrayAndInitialize", int.class, int.class, int.class, int.class, ResolvedJavaType.class, Kind.class));
+            } catch (NoSuchMethodException e) {
+                throw new GraalInternalError(e);
+            }
+        }
+
+        /**
+         * Lowers a {@link NewInstanceNode}.
+         */
+        @SuppressWarnings("unused")
+        public void lower(NewInstanceNode newInstanceNode, LoweringTool tool) {
+            StructuredGraph graph = (StructuredGraph) newInstanceNode.graph();
+            HotSpotResolvedJavaType type = (HotSpotResolvedJavaType) newInstanceNode.instanceClass();
+            HotSpotKlassOop hub = type.klassOop();
+            int size = type.instanceSize();
+            assert (size % wordSize()) == 0;
+            assert size >= 0;
+
+            ValueNode memory;
+            if (!useTLAB) {
+                memory = ConstantNode.forConstant(new Constant(target.wordKind, 0L), runtime, graph);
+            } else {
+                TLABAllocateNode tlabAllocateNode = graph.add(new TLABAllocateNode(size, wordKind()));
+                graph.addBeforeFixed(newInstanceNode, tlabAllocateNode);
+                memory = tlabAllocateNode;
+            }
+            InitializeObjectNode initializeNode = graph.add(new InitializeObjectNode(memory, type));
+            graph.replaceFixedWithFixed(newInstanceNode, initializeNode);
+        }
+
+        /**
+         * Lowers a {@link NewArrayNode}.
+         */
+        @SuppressWarnings("unused")
+        public void lower(NewArrayNode newArrayNode, LoweringTool tool) {
+            StructuredGraph graph = (StructuredGraph) newArrayNode.graph();
+            ValueNode lengthNode = newArrayNode.length();
+            TLABAllocateNode tlabAllocateNode;
+            ResolvedJavaType elementType = newArrayNode.elementType();
+            ResolvedJavaType arrayType = elementType.arrayOf();
+            Kind elementKind = elementType.kind();
+            final int alignment = target.wordSize;
+            final int headerSize = elementKind.arrayBaseOffset();
+            final Integer length = lengthNode.isConstant() ? Integer.valueOf(lengthNode.asConstant().asInt()) : null;
+            int log2ElementSize = CodeUtil.log2(target.sizeInBytes(elementKind));
+            if (!useTLAB) {
+                ConstantNode zero = ConstantNode.forConstant(new Constant(target.wordKind, 0L), runtime, graph);
+                // 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));
+                graph.replaceFixedWithFixed(newArrayNode, initializeNode);
+            } else if (length != null && UnsignedMath.belowThan(length, MAX_ARRAY_FAST_PATH_ALLOCATION_LENGTH)) {
+                // Calculate aligned size
+                int size = getArraySize(length, alignment, headerSize, log2ElementSize);
+                ConstantNode sizeNode = ConstantNode.forInt(size, graph);
+                tlabAllocateNode = graph.add(new TLABAllocateNode(size, target.wordKind));
+                graph.addBeforeFixed(newArrayNode, tlabAllocateNode);
+                InitializeArrayNode initializeNode = graph.add(new InitializeArrayNode(tlabAllocateNode, lengthNode, sizeNode, arrayType));
+                graph.replaceFixedWithFixed(newArrayNode, initializeNode);
+            } else {
+                Key key = new Key(allocateArrayAndInitialize).
+                                add("alignment", alignment).
+                                add("headerSize", headerSize).
+                                add("log2ElementSize", log2ElementSize).
+                                add("wordKind", target.wordKind).
+                                add("type", arrayType);
+                Arguments arguments = new Arguments().add("length", lengthNode);
+                SnippetTemplate template = cache.get(key);
+                Debug.log("Lowering allocateArrayAndInitialize in %s: node=%s, template=%s, arguments=%s", graph, newArrayNode, template, arguments);
+                template.instantiate(runtime, newArrayNode, newArrayNode, arguments);
+            }
+        }
+
+        @SuppressWarnings("unused")
+        public void lower(TLABAllocateNode tlabAllocateNode, LoweringTool tool) {
+            StructuredGraph graph = (StructuredGraph) tlabAllocateNode.graph();
+            ValueNode size;
+            if (tlabAllocateNode.isSizeConstant()) {
+                size = ConstantNode.forInt(tlabAllocateNode.constantSize(), graph);
+            } else {
+                size = tlabAllocateNode.variableSize();
+            }
+            Key key = new Key(allocate);
+            Arguments arguments = arguments("size", size);
+            SnippetTemplate template = cache.get(key);
+            Debug.log("Lowering fastAllocate in %s: node=%s, template=%s, arguments=%s", graph, tlabAllocateNode, template, arguments);
+            template.instantiate(runtime, tlabAllocateNode, tlabAllocateNode, arguments);
+        }
+
+        @SuppressWarnings("unused")
+        public void lower(InitializeObjectNode initializeNode, LoweringTool tool) {
+            StructuredGraph graph = (StructuredGraph) initializeNode.graph();
+            HotSpotResolvedJavaType type = (HotSpotResolvedJavaType) initializeNode.type();
+            assert !type.isArrayClass();
+            HotSpotKlassOop hub = type.klassOop();
+            int size = type.instanceSize();
+            assert (size % wordSize()) == 0;
+            assert size >= 0;
+            Key key = new Key(initializeObject).add("size", size);
+            ValueNode memory = initializeNode.memory();
+            Arguments arguments = arguments("memory", memory).add("hub", hub).add("initialMarkWord", type.initialMarkWord());
+            SnippetTemplate template = cache.get(key);
+            Debug.log("Lowering initializeObject in %s: node=%s, template=%s, arguments=%s", graph, initializeNode, template, arguments);
+            template.instantiate(runtime, initializeNode, initializeNode, arguments);
+        }
+
+        @SuppressWarnings("unused")
+        public void lower(InitializeArrayNode initializeNode, LoweringTool tool) {
+            StructuredGraph graph = (StructuredGraph) initializeNode.graph();
+            HotSpotResolvedJavaType type = (HotSpotResolvedJavaType) initializeNode.type();
+            ResolvedJavaType elementType = type.componentType();
+            assert elementType != null;
+            HotSpotKlassOop hub = type.klassOop();
+            Kind elementKind = elementType.kind();
+            final int headerSize = elementKind.arrayBaseOffset();
+            Key key = new Key(elementKind.isObject() ? initializeObjectArray : initializePrimitiveArray).add("headerSize", headerSize);
+            ValueNode memory = initializeNode.memory();
+            Arguments arguments = arguments("memory", memory).add("hub", hub).add("initialMarkWord", type.initialMarkWord()).add("size", initializeNode.size()).add("length", initializeNode.length());
+            SnippetTemplate template = cache.get(key);
+            Debug.log("Lowering initializeObjectArray in %s: node=%s, template=%s, arguments=%s", graph, initializeNode, template, arguments);
+            template.instantiate(runtime, initializeNode, initializeNode, arguments);
+        }
+    }
+
+    @Fold
+    private static boolean verifyOops() {
+        return HotSpotGraalRuntime.getInstance().getConfig().verifyOops;
+    }
+
+    @Fold
+    private static int threadTlabTopOffset() {
+        return HotSpotGraalRuntime.getInstance().getConfig().threadTlabTopOffset;
+    }
+
+    @Fold
+    private static int threadTlabEndOffset() {
+        return HotSpotGraalRuntime.getInstance().getConfig().threadTlabEndOffset;
+    }
+
+    @Fold
+    private static Kind wordKind() {
+        return HotSpotGraalRuntime.getInstance().getTarget().wordKind;
+    }
+
+    @Fold
+    private static int wordSize() {
+        return HotSpotGraalRuntime.getInstance().getTarget().wordSize;
+    }
+
+    @Fold
+    private static int markOffset() {
+        return HotSpotGraalRuntime.getInstance().getConfig().markOffset;
+    }
+
+    @Fold
+    private static int hubOffset() {
+        return HotSpotGraalRuntime.getInstance().getConfig().hubOffset;
+    }
+
+    @Fold
+    private static int arrayLengthOffset() {
+        return HotSpotGraalRuntime.getInstance().getConfig().arrayLengthOffset;
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/AMD64NewInstanceStubCallOp.java	Tue Jul 03 18:02:03 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/*
- * 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.target;
-
-import static com.oracle.graal.api.code.ValueUtil.*;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.hotspot.*;
-import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.amd64.*;
-import com.oracle.graal.lir.asm.*;
-import com.oracle.max.asm.target.amd64.*;
-import com.oracle.graal.lir.LIRInstruction.Opcode;
-
-/**
- * LIR instruction for calling HotSpot's {@code new_instance} stub. This stub is declared in c1_Runtime1.hpp
- * and implemented in Runtime1::generate_code_for() which is located in c1_Runtime1_x86.cpp.
- */
-@Opcode("NEW_INSTANCE")
-public class AMD64NewInstanceStubCallOp extends AMD64LIRInstruction {
-    @Def protected Value result;
-    @Use protected Value hub;
-    @Temp protected Value temp;
-    @State protected LIRFrameState state;
-
-    public AMD64NewInstanceStubCallOp(Value result, Value hub, LIRFrameState state) {
-        this.result = result;
-        this.hub = hub;
-        this.temp = AMD64.rax.asValue(Kind.Object);
-        this.state = state;
-    }
-
-    @Override
-    public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-        // rdx: (in) hub
-        // rax: (out) result
-        AMD64Call.directCall(tasm, masm, HotSpotGraalRuntime.getInstance().getConfig().newInstanceStub, state);
-        if (asRegister(result) != AMD64.rax) {
-            masm.movq(asRegister(result), AMD64.rax);
-        }
-    }
-
-    @Override
-    protected void verify() {
-        super.verify();
-        assert asRegister(hub) == AMD64.rdx;
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/AMD64VerifyOopStubCallOp.java	Tue Jul 03 18:02:03 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-/*
- * 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.target;
-
-import static com.oracle.graal.api.code.ValueUtil.*;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.hotspot.*;
-import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.LIRInstruction.Opcode;
-import com.oracle.graal.lir.amd64.*;
-import com.oracle.graal.lir.asm.*;
-import com.oracle.max.asm.target.amd64.*;
-
-/**
- * A call to HotSpot's object pointer verification stub.
- */
-@Opcode("VERIFY_OOP")
-public class AMD64VerifyOopStubCallOp extends AMD64LIRInstruction {
-    @Use protected Value object;
-    @State protected LIRFrameState state;
-
-    public AMD64VerifyOopStubCallOp(Value object, LIRFrameState state) {
-        this.object = object;
-        this.state = state;
-    }
-
-    @Override
-    public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-        // r13: (in) object
-        if (asRegister(object) != AMD64.r13) {
-            masm.push(AMD64.r13);
-            masm.movq(AMD64.r13, asRegister(object));
-        }
-        AMD64Call.directCall(tasm, masm, HotSpotGraalRuntime.getInstance().getConfig().verifyOopStub, state);
-        if (asRegister(object) != AMD64.r13) {
-            masm.pop(AMD64.r13);
-        }
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/AMD64NewArrayStubCallOp.java	Tue Jul 03 23:49:01 2012 +0200
@@ -0,0 +1,98 @@
+/*
+ * 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.target.amd64;
+
+import static com.oracle.graal.api.code.ValueUtil.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.LIRInstruction.Opcode;
+import com.oracle.graal.lir.amd64.*;
+import com.oracle.graal.lir.asm.*;
+import com.oracle.max.asm.target.amd64.*;
+
+/**
+ * LIR instruction for calling HotSpot's {@code new_[object|type]_array} stub. This stub is declared in c1_Runtime1.hpp
+ * and implemented in Runtime1::generate_code_for() which is located in c1_Runtime1_x86.cpp.
+ */
+@Opcode("NEW_ARRAY")
+public class AMD64NewArrayStubCallOp extends AMD64LIRInstruction {
+
+    /**
+     * The stub places the result in RAX.
+     */
+    public static final Register RESULT = AMD64.rax;
+
+    /**
+     * The stub expects the hub in RDX.
+     */
+    public static final Register HUB = AMD64.rdx;
+
+    /**
+     * The stub expects the length in RBX.
+     */
+    public static final Register LENGTH = AMD64.rbx;
+
+    /**
+     * The stub uses RCX, RSI, and RDI as temps.
+     */
+    public static final Register[] TEMPS = {AMD64.rcx, AMD64.rdi, AMD64.rsi};
+
+    private final boolean isObjectArray;
+
+    @Def protected Value result;
+    @Use protected Value hub;
+    @Use protected Value length;
+    @Temp protected Value[] temps;
+
+    @State protected LIRFrameState state;
+
+    public AMD64NewArrayStubCallOp(boolean isObjectArray, Value result, Value hub, Value length, LIRFrameState state) {
+        this.isObjectArray = isObjectArray;
+        this.result = result;
+        this.hub = hub;
+        this.length = length;
+        this.temps = new Value[TEMPS.length];
+        for (int i = 0; i < temps.length; i++) {
+            temps[i] = TEMPS[i].asValue(Kind.Long);
+        }
+        this.state = state;
+    }
+
+    @Override
+    public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+        HotSpotVMConfig config = HotSpotGraalRuntime.getInstance().getConfig();
+        long stub = isObjectArray ? config.newObjectArrayStub : config.newTypeArrayStub;
+        AMD64Call.directCall(tasm, masm, stub, state);
+    }
+
+    @Override
+    protected void verify() {
+        super.verify();
+        assert asRegister(hub) == HUB : "stub expects hub in " + HUB;
+        assert asRegister(length) == LENGTH : "stub expect length in " + LENGTH;
+        assert asRegister(result) == RESULT : "stub places result in " + RESULT;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/AMD64NewInstanceStubCallOp.java	Tue Jul 03 23:49:01 2012 +0200
@@ -0,0 +1,74 @@
+/*
+ * 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.target.amd64;
+
+import static com.oracle.graal.api.code.ValueUtil.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.LIRInstruction.Opcode;
+import com.oracle.graal.lir.amd64.*;
+import com.oracle.graal.lir.asm.*;
+import com.oracle.max.asm.target.amd64.*;
+
+/**
+ * LIR instruction for calling HotSpot's {@code new_instance} stub. This stub is declared in c1_Runtime1.hpp
+ * and implemented in Runtime1::generate_code_for() which is located in c1_Runtime1_x86.cpp.
+ */
+@Opcode("NEW_INSTANCE")
+public class AMD64NewInstanceStubCallOp extends AMD64LIRInstruction {
+
+    /**
+     * The stub expects the hub in RDX.
+     */
+    public static final Register HUB = AMD64.rdx;
+
+    /**
+     * The stub places the result in RAX.
+     */
+    public static final Register RESULT = AMD64.rax;
+
+    @Def protected Value result;
+    @Use protected Value hub;
+    @State protected LIRFrameState state;
+
+    public AMD64NewInstanceStubCallOp(Value result, Value hub, LIRFrameState state) {
+        this.hub = hub;
+        this.result = result;
+        this.state = state;
+    }
+
+    @Override
+    public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+        AMD64Call.directCall(tasm, masm, HotSpotGraalRuntime.getInstance().getConfig().newInstanceStub, state);
+    }
+
+    @Override
+    protected void verify() {
+        super.verify();
+        assert asRegister(hub) == HUB : "expects hub in " + HUB;
+        assert asRegister(result) == RESULT : "expects result in " + RESULT;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/AMD64VerifyOopStubCallOp.java	Tue Jul 03 23:49:01 2012 +0200
@@ -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.target.amd64;
+
+import static com.oracle.graal.api.code.ValueUtil.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.LIRInstruction.Opcode;
+import com.oracle.graal.lir.amd64.*;
+import com.oracle.graal.lir.asm.*;
+import com.oracle.max.asm.target.amd64.*;
+
+/**
+ * A call to HotSpot's object pointer verification stub.
+ */
+@Opcode("VERIFY_OOP")
+public class AMD64VerifyOopStubCallOp extends AMD64LIRInstruction {
+
+    /**
+     * The stub expects the object pointer in R13.
+     */
+    public static final Register OBJECT = AMD64.r13;
+
+    @Use protected Value object;
+    @State protected LIRFrameState state;
+
+    public AMD64VerifyOopStubCallOp(Value object, LIRFrameState state) {
+        this.object = object;
+        this.state = state;
+    }
+
+    @Override
+    public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+        AMD64Call.directCall(tasm, masm, HotSpotGraalRuntime.getInstance().getConfig().verifyOopStub, state);
+    }
+
+    @Override
+    protected void verify() {
+        super.verify();
+        assert asRegister(object) == OBJECT : "expects object in " + OBJECT;
+    }
+}
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Tue Jul 03 18:02:03 2012 +0200
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Tue Jul 03 23:49:01 2012 +0200
@@ -30,8 +30,8 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.api.meta.JavaType.*;
-import com.oracle.graal.api.meta.JavaTypeProfile.*;
+import com.oracle.graal.api.meta.JavaType.Representation;
+import com.oracle.graal.api.meta.JavaTypeProfile.ProfiledType;
 import com.oracle.graal.bytecode.*;
 import com.oracle.graal.compiler.*;
 import com.oracle.graal.compiler.phases.*;
@@ -693,10 +693,10 @@
         // Checkstyle: resume
     }
 
-    private void genNewTypeArray(int typeCode) {
+    private void genNewPrimitiveArray(int typeCode) {
         Kind kind = arrayTypeCodeToKind(typeCode);
         ResolvedJavaType elementType = runtime.getResolvedJavaType(kind);
-        NewTypeArrayNode nta = currentGraph.add(new NewTypeArrayNode(frameState.ipop(), elementType));
+        NewPrimitiveArrayNode nta = currentGraph.add(new NewPrimitiveArrayNode(frameState.ipop(), elementType));
         frameState.apush(append(nta));
     }
 
@@ -1705,7 +1705,7 @@
             case INVOKESTATIC   : cpi = stream.readCPI(); genInvokeStatic(lookupMethod(cpi, opcode)); break;
             case INVOKEINTERFACE: cpi = stream.readCPI(); genInvokeInterface(lookupMethod(cpi, opcode)); break;
             case NEW            : genNewInstance(stream.readCPI()); break;
-            case NEWARRAY       : genNewTypeArray(stream.readLocalIndex()); break;
+            case NEWARRAY       : genNewPrimitiveArray(stream.readLocalIndex()); break;
             case ANEWARRAY      : genNewObjectArray(stream.readCPI()); break;
             case ARRAYLENGTH    : genArrayLength(); break;
             case ATHROW         : genThrow(); break;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewArrayNode.java	Tue Jul 03 18:02:03 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewArrayNode.java	Tue Jul 03 23:49:01 2012 +0200
@@ -36,7 +36,7 @@
 /**
  * The {@code NewArrayNode} class is the base of all instructions that allocate arrays.
  */
-public abstract class NewArrayNode extends FixedWithNextNode implements EscapeAnalyzable, TypeFeedbackProvider {
+public abstract class NewArrayNode extends FixedWithNextNode implements Lowerable, EscapeAnalyzable, TypeFeedbackProvider {
 
     @Input private ValueNode length;
 
@@ -86,6 +86,11 @@
         return ESCAPE;
     }
 
+    @Override
+    public void lower(LoweringTool tool) {
+        tool.getRuntime().lower(this, tool);
+    }
+
     private static final EscapeOp ESCAPE = new EscapeOp() {
 
         @Override
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewPrimitiveArrayNode.java	Tue Jul 03 23:49:01 2012 +0200
@@ -0,0 +1,51 @@
+/*
+ * 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.java;
+
+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 NewPrimitiveArrayNode} class definition.
+ */
+public final class NewPrimitiveArrayNode extends NewArrayNode implements LIRLowerable {
+
+    private final ResolvedJavaType elementType;
+
+    public NewPrimitiveArrayNode(ValueNode length, ResolvedJavaType elementType) {
+        super(StampFactory.exactNonNull(elementType.arrayOf()), length);
+        this.elementType = elementType;
+    }
+
+    @Override
+    public ResolvedJavaType elementType() {
+        return elementType;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        gen.visitNewPrimitiveArray(this);
+    }
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewTypeArrayNode.java	Tue Jul 03 18:02:03 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-/*
- * 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.java;
-
-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 NewTypeArrayNode} class definition.
- */
-public final class NewTypeArrayNode extends NewArrayNode implements LIRLowerable {
-
-    private final ResolvedJavaType elementType;
-
-    public NewTypeArrayNode(ValueNode length, ResolvedJavaType elementType) {
-        super(StampFactory.exactNonNull(elementType.arrayOf()), length);
-        this.elementType = elementType;
-    }
-
-    @Override
-    public ResolvedJavaType elementType() {
-        return elementType;
-    }
-
-    @Override
-    public void generate(LIRGeneratorTool gen) {
-        gen.visitNewTypeArray(this);
-    }
-}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java	Tue Jul 03 18:02:03 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java	Tue Jul 03 23:49:01 2012 +0200
@@ -112,7 +112,7 @@
     public abstract void visitMonitorEnter(MonitorEnterNode i);
     public abstract void visitMonitorExit(MonitorExitNode i);
     public abstract void visitNewInstance(NewInstanceNode i);
-    public abstract void visitNewTypeArray(NewTypeArrayNode i);
+    public abstract void visitNewPrimitiveArray(NewPrimitiveArrayNode i);
     public abstract void visitNewObjectArray(NewObjectArrayNode i);
     public abstract void visitNewMultiArray(NewMultiArrayNode i);
     public abstract void visitExceptionObject(ExceptionObjectNode i);
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Snippet.java	Tue Jul 03 18:02:03 2012 +0200
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Snippet.java	Tue Jul 03 23:49:01 2012 +0200
@@ -58,11 +58,26 @@
         boolean shouldInline(ResolvedJavaMethod method, ResolvedJavaMethod caller);
 
         /**
-         * The default inlining policy which inlines everything except for
-         * constructors of {@link Throwable} classes.
+         * The default inlining policy which inlines everything except for methods
+         * in any of the following categories.
+         * <ul>
+         * <li>{@linkplain Fold foldable} methods</li>
+         * <li>{@linkplain NodeIntrinsic node intrinsics}</li>
+         * <li>native methods</li>
+         * <li>constructors of {@link Throwable} classes</li>
+         * </ul>
          */
         InliningPolicy Default = new InliningPolicy() {
             public boolean shouldInline(ResolvedJavaMethod method, ResolvedJavaMethod caller) {
+                if (Modifier.isNative(method.accessFlags())) {
+                    return false;
+                }
+                if (method.getAnnotation(Fold.class) != null) {
+                    return false;
+                }
+                if (method.getAnnotation(NodeIntrinsic.class) != null) {
+                    return false;
+                }
                 if (Throwable.class.isAssignableFrom(method.holder().toJava())) {
                     if (method.name().equals("<init>")) {
                         return false;
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetInstaller.java	Tue Jul 03 18:02:03 2012 +0200
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetInstaller.java	Tue Jul 03 23:49:01 2012 +0200
@@ -137,6 +137,8 @@
     public StructuredGraph makeGraph(final ResolvedJavaMethod method, final InliningPolicy policy) {
         StructuredGraph graph = parseGraph(method, policy);
 
+        new SnippetIntrinsificationPhase(runtime, pool, SnippetTemplate.hasConstantParameter(method)).apply(graph);
+
         Debug.dump(graph, "%s: Final", method.name());
 
         return graph;
@@ -165,7 +167,7 @@
 
                 new SnippetVerificationPhase().apply(graph);
 
-                new SnippetIntrinsificationPhase(runtime, pool).apply(graph);
+                new SnippetIntrinsificationPhase(runtime, pool, true).apply(graph);
 
                 for (Invoke invoke : graph.getInvokes()) {
                     MethodCallTargetNode callTarget = invoke.callTarget();
@@ -181,7 +183,7 @@
                     }
                 }
 
-                new SnippetIntrinsificationPhase(runtime, pool).apply(graph);
+                new SnippetIntrinsificationPhase(runtime, pool, true).apply(graph);
 
                 new WordTypeRewriterPhase(target.wordKind, runtime.getResolvedJavaType(target.wordKind)).apply(graph);
 
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetIntrinsificationPhase.java	Tue Jul 03 18:02:03 2012 +0200
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetIntrinsificationPhase.java	Tue Jul 03 23:49:01 2012 +0200
@@ -41,16 +41,39 @@
 
     private final CodeCacheProvider runtime;
     private final BoxingMethodPool pool;
+    private final boolean intrinsificationOrFoldingCanBeDeferred;
 
-    public SnippetIntrinsificationPhase(CodeCacheProvider runtime, BoxingMethodPool pool) {
+    /**
+     * @param intrinsificationOrFoldingCanBeDeferred if true, then {@link NonConstantParameterError}s are not fatal
+     */
+    public SnippetIntrinsificationPhase(CodeCacheProvider runtime, BoxingMethodPool pool, boolean intrinsificationOrFoldingCanBeDeferred) {
         this.runtime = runtime;
         this.pool = pool;
+        this.intrinsificationOrFoldingCanBeDeferred = intrinsificationOrFoldingCanBeDeferred;
     }
 
     @Override
     protected void run(StructuredGraph graph) {
         for (Invoke i : graph.getInvokes()) {
-            tryIntrinsify(i);
+            try {
+                tryIntrinsify(i);
+            } catch (NonConstantParameterError t) {
+                if (!intrinsificationOrFoldingCanBeDeferred) {
+                    throw t;
+                }
+            }
+        }
+    }
+
+    /**
+     * Exception raised when an argument to a {@linkplain Fold foldable} or
+     * {@link NodeIntrinsic} method is not a constant.
+     */
+    @SuppressWarnings("serial")
+    public static class NonConstantParameterError extends Error {
+
+        public NonConstantParameterError(String message) {
+            super(message);
         }
     }
 
@@ -119,7 +142,9 @@
             }
             ValueNode argument = tryBoxingElimination(parameterIndex, target, arguments.get(i));
             if (folding || MetaUtil.getParameterAnnotation(ConstantNodeParameter.class, parameterIndex, target) != null) {
-                assert argument instanceof ConstantNode : "parameter " + parameterIndex + " must be a compile time constant for calling " + invoke.callTarget().targetMethod() + " at " + sourceLocation(invoke.node()) + ": " + argument;
+                if (!(argument instanceof ConstantNode)) {
+                    throw new NonConstantParameterError("parameter " + parameterIndex + " must be a compile time constant for calling " + invoke.callTarget().targetMethod() + " at " + sourceLocation(invoke.node()) + ": " + argument);
+                }
                 ConstantNode constantNode = (ConstantNode) argument;
                 Constant constant = constantNode.asConstant();
                 Object o = constant.boxedValue();
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetTemplate.java	Tue Jul 03 18:02:03 2012 +0200
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetTemplate.java	Tue Jul 03 23:49:01 2012 +0200
@@ -35,6 +35,7 @@
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.Node.Verbosity;
 import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.nodes.util.*;
@@ -175,6 +176,18 @@
     }
 
     /**
+     * Determines if any parameter of a given method is annotated with {@link ConstantParameter}.
+     */
+    public static boolean hasConstantParameter(ResolvedJavaMethod method) {
+        for (ConstantParameter p : MetaUtil.getParameterAnnotations(ConstantParameter.class, method)) {
+            if (p != null) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
      * Creates a snippet template.
      */
     public SnippetTemplate(CodeCacheProvider runtime, SnippetTemplate.Key key) {
@@ -182,7 +195,7 @@
         assert Modifier.isStatic(method.accessFlags()) : "snippet method must be static: " + method;
         Signature signature = method.signature();
 
-        // Copy snippet graph, replacing @Constant parameters with given arguments
+        // Copy snippet graph, replacing constant parameters with given arguments
         StructuredGraph snippetGraph = (StructuredGraph) method.compilerStorage().get(Graph.class);
         StructuredGraph snippetCopy = new StructuredGraph(snippetGraph.name, snippetGraph.method());
         IdentityHashMap<Node, Node> replacements = new IdentityHashMap<>();
@@ -201,7 +214,8 @@
                 replacements.put(snippetGraph.getLocal(i), ConstantNode.forConstant(Constant.forBoxed(kind, arg), runtime, snippetCopy));
             } else {
                 Parameter p = MetaUtil.getParameterAnnotation(Parameter.class, i, method);
-                assert p != null : method + ": parameter " + i + " must be annotated with either @Constant or @Parameter";
+                assert p != null : method + ": parameter " + i + " must be annotated with either @" + ConstantParameter.class.getSimpleName() +
+                                " or @" + Parameter.class.getSimpleName();
                 String name = p.value();
                 if (p.multiple()) {
                     Object multiple = key.get(name);
@@ -219,6 +233,9 @@
 
         Debug.dump(snippetCopy, "Before specialization");
         if (!replacements.isEmpty()) {
+            // Do deferred intrinsification of node intrinsics
+            new SnippetIntrinsificationPhase(runtime, new BoxingMethodPool(runtime), false).apply(snippetCopy);
+
             new CanonicalizerPhase(null, runtime, null, 0, null).apply(snippetCopy);
         }
 
@@ -386,6 +403,7 @@
                     replacements.put((LocalNode) parameter, (ValueNode) argument);
                 } else {
                     Kind kind = ((LocalNode) parameter).kind();
+                    assert argument != null || kind.isObject() : this + " cannot accept null for non-object parameter named " + name;
                     Constant constant = Constant.forBoxed(kind, argument);
                     replacements.put((LocalNode) parameter, ConstantNode.forConstant(constant, runtime, replaceeGraph));
                 }
@@ -478,10 +496,10 @@
             sep = ", ";
             if (value instanceof LocalNode) {
                 LocalNode local = (LocalNode) value;
-                buf.append(local.kind().name()).append(' ').append(name);
+                buf.append(local.kind().javaName).append(' ').append(name);
             } else {
                 LocalNode[] locals = (LocalNode[]) value;
-                String kind = locals.length == 0 ? "?" : locals[0].kind().name();
+                String kind = locals.length == 0 ? "?" : locals[0].kind().javaName;
                 buf.append(kind).append('[').append(locals.length).append("] ").append(name);
             }
         }
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetVerificationPhase.java	Tue Jul 03 18:02:03 2012 +0200
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetVerificationPhase.java	Tue Jul 03 23:49:01 2012 +0200
@@ -31,6 +31,7 @@
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.Node.NodeIntrinsic;
 import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.util.*;
 import com.oracle.graal.snippets.Word.*;
@@ -87,6 +88,11 @@
                             argc++;
                         }
                     }
+                } else if (usage instanceof ObjectEqualsNode) {
+                    ObjectEqualsNode compare = (ObjectEqualsNode) usage;
+                    if (compare.x() == node || compare.y() == node) {
+                        verify(isWord(compare.x()) == isWord(compare.y()), node, compare.usages().first(), "cannot mixed word and now-word type in use of '==' or '!='");
+                    }
                 } else if (usage instanceof ArrayLengthNode) {
                     verify(!isWord(node) || ((ArrayLengthNode) usage).array() != node, node, usage, "cannot get array length from word value");
                 } else if (usage instanceof PhiNode) {
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/WordTypeRewriterPhase.java	Tue Jul 03 18:02:03 2012 +0200
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/WordTypeRewriterPhase.java	Tue Jul 03 23:49:01 2012 +0200
@@ -68,6 +68,17 @@
             }
         }
 
+        // Replace ObjectEqualsNodes with IntegerEqualsNodes where the values being compared are words
+        for (ObjectEqualsNode objectEqualsNode : graph.getNodes().filter(ObjectEqualsNode.class).snapshot()) {
+            ValueNode x = objectEqualsNode.x();
+            ValueNode y = objectEqualsNode.y();
+            if (x.kind() == wordKind || y.kind() == wordKind) {
+                assert x.kind() == wordKind;
+                assert y.kind() == wordKind;
+                graph.replaceFloating(objectEqualsNode, graph.unique(new IntegerEqualsNode(x, y)));
+            }
+        }
+
         for (MethodCallTargetNode callTargetNode : graph.getNodes(MethodCallTargetNode.class).snapshot()) {
             ResolvedJavaMethod targetMethod = callTargetNode.targetMethod();
             Operation operation = targetMethod.getAnnotation(Word.Operation.class);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/NewArrayTest.java	Tue Jul 03 23:49:01 2012 +0200
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 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.compiler.tests;
+
+import org.junit.*;
+
+/**
+ * Tests the implementation of {@code [A]NEWARRAY}.
+ */
+public class NewArrayTest extends GraalCompilerTest {
+
+    @Override
+    protected void assertEquals(Object expected, Object actual) {
+        Assert.assertTrue(expected != null);
+        Assert.assertTrue(actual != null);
+        super.assertEquals(expected.getClass(), actual.getClass());
+        if (expected instanceof int[]) {
+            Assert.assertArrayEquals((int[]) expected, (int[]) actual);
+        } else if (expected instanceof byte[]) {
+            Assert.assertArrayEquals((byte[]) expected, (byte[]) actual);
+        } else if (expected instanceof char[]) {
+            Assert.assertArrayEquals((char[]) expected, (char[]) actual);
+        } else if (expected instanceof short[]) {
+            Assert.assertArrayEquals((short[]) expected, (short[]) actual);
+        } else if (expected instanceof float[]) {
+            Assert.assertArrayEquals((float[]) expected, (float[]) actual, 0.0f);
+        } else if (expected instanceof long[]) {
+            Assert.assertArrayEquals((long[]) expected, (long[]) actual);
+        } else if (expected instanceof double[]) {
+            Assert.assertArrayEquals((double[]) expected, (double[]) actual, 0.0d);
+        } else if (expected instanceof Object[]) {
+            Assert.assertArrayEquals((Object[]) expected, (Object[]) actual);
+        } else {
+            Assert.fail("non-array value encountered: " + expected);
+        }
+    }
+
+    @Test
+    public void test1() {
+        for (String type : new String[] {"Byte", "Char", "Short", "Int", "Float", "Long", "Double", "String"}) {
+            test("new" + type + "Array7");
+            test("new" + type + "ArrayMinus7");
+            test("new" + type + "Array", 7);
+            test("new" + type + "Array", -7);
+            test("new" + type + "Array", Integer.MAX_VALUE);
+            test("new" + type + "Array", Integer.MIN_VALUE);
+        }
+    }
+
+    public static Object newCharArray7() {
+        return new char[7];
+    }
+
+    public static Object newCharArrayMinus7() {
+        return new char[-7];
+    }
+
+    public static Object newCharArray(int length) {
+        return new char[length];
+    }
+
+    public static Object newShortArray7() {
+        return new short[7];
+    }
+
+    public static Object newShortArrayMinus7() {
+        return new short[-7];
+    }
+
+    public static Object newShortArray(int length) {
+        return new short[length];
+    }
+
+    public static Object newFloatArray7() {
+        return new float[7];
+    }
+
+    public static Object newFloatArrayMinus7() {
+        return new float[-7];
+    }
+
+    public static Object newFloatArray(int length) {
+        return new float[length];
+    }
+
+    public static Object newLongArray7() {
+        return new long[7];
+    }
+
+    public static Object newLongArrayMinus7() {
+        return new long[-7];
+    }
+
+    public static Object newLongArray(int length) {
+        return new long[length];
+    }
+
+    public static Object newDoubleArray7() {
+        return new double[7];
+    }
+
+    public static Object newDoubleArrayMinus7() {
+        return new double[-7];
+    }
+
+    public static Object newDoubleArray(int length) {
+        return new double[length];
+    }
+
+    public static Object newIntArray7() {
+        return new int[7];
+    }
+
+    public static Object newIntArrayMinus7() {
+        return new int[-7];
+    }
+
+    public static Object newIntArray(int length) {
+        return new int[length];
+    }
+
+    public static Object newByteArray7() {
+        return new byte[7];
+    }
+
+    public static Object newByteArrayMinus7() {
+        return new byte[-7];
+    }
+
+    public static Object newByteArray(int length) {
+        return new byte[length];
+    }
+
+    public static Object newStringArray7() {
+        return new String[7];
+    }
+
+    public static Object newStringArrayMinus7() {
+        return new String[-7];
+    }
+
+    public static Object newStringArray(int length) {
+        return new String[length];
+    }
+}
--- a/src/share/vm/graal/graalCompiler.cpp	Tue Jul 03 18:02:03 2012 +0200
+++ b/src/share/vm/graal/graalCompiler.cpp	Tue Jul 03 23:49:01 2012 +0200
@@ -273,7 +273,7 @@
   HotSpotResolvedJavaType::set_accessFlags(obj, klass->access_flags().as_int());
   HotSpotResolvedJavaType::set_isInterface(obj, klass->is_interface());
   HotSpotResolvedJavaType::set_superCheckOffset(obj, klass->super_check_offset());
-  HotSpotResolvedJavaType::set_prototypeHeader(obj, (jlong) klass->prototype_header());
+  HotSpotResolvedJavaType::set_initialMarkWord(obj, (jlong) klass->prototype_header());
   HotSpotResolvedJavaType::set_isInstanceClass(obj, klass->oop_is_instance());
 
   if (klass->oop_is_javaArray()) {
--- a/src/share/vm/graal/graalCompilerToVM.cpp	Tue Jul 03 18:02:03 2012 +0200
+++ b/src/share/vm/graal/graalCompilerToVM.cpp	Tue Jul 03 23:49:01 2012 +0200
@@ -790,6 +790,7 @@
   set_int(env, config, "vmPageSize", os::vm_page_size());
   set_int(env, config, "stackShadowPages", StackShadowPages);
   set_int(env, config, "hubOffset", oopDesc::klass_offset_in_bytes());
+  set_int(env, config, "markOffset", oopDesc::mark_offset_in_bytes());
   set_int(env, config, "superCheckOffsetOffset", in_bytes(Klass::super_check_offset_offset()));
   set_int(env, config, "secondarySuperCacheOffset", in_bytes(Klass::secondary_super_cache_offset()));
   set_int(env, config, "secondarySupersOffset", in_bytes(Klass::secondary_supers_offset()));
@@ -874,12 +875,6 @@
       break;
     }
 
-  jintArray arrayOffsets = env->NewIntArray(basicTypeCount);
-  for (int i=0; i<basicTypeCount; i++) {
-    jint offset = arrayOopDesc::base_offset_in_bytes(basicTypes[i]);
-    env->SetIntArrayRegion(arrayOffsets, i, 1, &offset);
-  }
-  set_int_array(env, config, "arrayOffsets", arrayOffsets);
   set_int(env, config, "arrayClassElementOffset", in_bytes(objArrayKlass::element_klass_offset()));
   return config;
 }
--- a/src/share/vm/graal/graalJavaAccess.hpp	Tue Jul 03 18:02:03 2012 +0200
+++ b/src/share/vm/graal/graalJavaAccess.hpp	Tue Jul 03 23:49:01 2012 +0200
@@ -52,7 +52,7 @@
     oop_field(HotSpotResolvedJavaType, javaMirror, "Ljava/lang/Class;")                     \
     oop_field(HotSpotResolvedJavaType, simpleName, "Ljava/lang/String;")                    \
     int_field(HotSpotResolvedJavaType, accessFlags)                                         \
-    long_field(HotSpotResolvedJavaType, prototypeHeader)                                    \
+    long_field(HotSpotResolvedJavaType, initialMarkWord)                                    \
     boolean_field(HotSpotResolvedJavaType, hasFinalizer)                                    \
     boolean_field(HotSpotResolvedJavaType, hasFinalizableSubclass)                          \
     int_field(HotSpotResolvedJavaType, superCheckOffset)                                    \