changeset 15840:e6f93283387a

Merge
author Christian Wimmer <christian.wimmer@oracle.com>
date Wed, 21 May 2014 10:08:39 -0700
parents 2838203d4231 (current diff) 9acad98567dc (diff)
children cb87019df5aa
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java
diffstat 16 files changed, 475 insertions(+), 438 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/AbstractObjectStamp.java	Wed May 21 10:08:39 2014 -0700
@@ -0,0 +1,282 @@
+/*
+ * Copyright (c) 2012, 2014, 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.common.type;
+
+import java.util.*;
+
+import com.oracle.graal.api.meta.*;
+
+public abstract class AbstractObjectStamp extends Stamp {
+
+    private final ResolvedJavaType type;
+    private final boolean exactType;
+    private final boolean nonNull;
+    private final boolean alwaysNull;
+
+    protected AbstractObjectStamp(ResolvedJavaType type, boolean exactType, boolean nonNull, boolean alwaysNull) {
+        this.type = type;
+        this.exactType = exactType;
+        this.nonNull = nonNull;
+        this.alwaysNull = alwaysNull;
+    }
+
+    protected abstract AbstractObjectStamp copyWith(ResolvedJavaType newType, boolean newExactType, boolean newNonNull, boolean newAlwaysNull);
+
+    @Override
+    public Stamp unrestricted() {
+        return copyWith(null, false, false, false);
+    }
+
+    @Override
+    public Stamp illegal() {
+        return copyWith(null, true, true, false);
+    }
+
+    @Override
+    public boolean isLegal() {
+        return !exactType || (type != null && (isConcreteType(type)));
+    }
+
+    @Override
+    public Kind getStackKind() {
+        return Kind.Object;
+    }
+
+    @Override
+    public ResolvedJavaType javaType(MetaAccessProvider metaAccess) {
+        if (type != null) {
+            return type;
+        }
+        return metaAccess.lookupJavaType(Object.class);
+    }
+
+    public boolean nonNull() {
+        return nonNull;
+    }
+
+    public boolean alwaysNull() {
+        return alwaysNull;
+    }
+
+    public ResolvedJavaType type() {
+        return type;
+    }
+
+    public boolean isExactType() {
+        return exactType;
+    }
+
+    protected void appendString(StringBuilder str) {
+        str.append(nonNull ? "!" : "").append(exactType ? "#" : "").append(' ').append(type == null ? "-" : type.getName()).append(alwaysNull ? " NULL" : "");
+    }
+
+    @Override
+    public Stamp meet(Stamp otherStamp) {
+        if (this == otherStamp) {
+            return this;
+        }
+        if (!isCompatible(otherStamp)) {
+            return StampFactory.illegal(Kind.Illegal);
+        }
+        AbstractObjectStamp other = (AbstractObjectStamp) otherStamp;
+        if (!isLegal()) {
+            return other;
+        } else if (!other.isLegal()) {
+            return this;
+        }
+        ResolvedJavaType meetType;
+        boolean meetExactType;
+        boolean meetNonNull;
+        boolean meetAlwaysNull;
+        if (other.alwaysNull) {
+            meetType = type();
+            meetExactType = exactType;
+            meetNonNull = false;
+            meetAlwaysNull = alwaysNull;
+        } else if (alwaysNull) {
+            meetType = other.type();
+            meetExactType = other.exactType;
+            meetNonNull = false;
+            meetAlwaysNull = other.alwaysNull;
+        } else {
+            meetType = meetTypes(type(), other.type());
+            meetExactType = exactType && other.exactType;
+            if (meetExactType && type != null && other.type != null) {
+                // meeting two valid exact types may result in a non-exact type
+                meetExactType = Objects.equals(meetType, type) && Objects.equals(meetType, other.type);
+            }
+            meetNonNull = nonNull && other.nonNull;
+            meetAlwaysNull = false;
+        }
+
+        if (Objects.equals(meetType, type) && meetExactType == exactType && meetNonNull == nonNull && meetAlwaysNull == alwaysNull) {
+            return this;
+        } else if (Objects.equals(meetType, other.type) && meetExactType == other.exactType && meetNonNull == other.nonNull && meetAlwaysNull == other.alwaysNull) {
+            return other;
+        } else {
+            return copyWith(meetType, meetExactType, meetNonNull, meetAlwaysNull);
+        }
+    }
+
+    @Override
+    public Stamp join(Stamp otherStamp) {
+        return join0(otherStamp, false);
+    }
+
+    /**
+     * Returns the stamp representing the type of this stamp after a cast to the type represented by
+     * the {@code to} stamp. While this is very similar to a {@link #join} operation, in the case
+     * where both types are not obviously related, the cast operation will prefer the type of the
+     * {@code to} stamp. This is necessary as long as ObjectStamps are not able to accurately
+     * represent intersection types.
+     *
+     * For example when joining the {@link RandomAccess} type with the {@link AbstractList} type,
+     * without intersection types, this would result in the most generic type ({@link Object} ). For
+     * this reason, in some cases a {@code castTo} operation is preferable in order to keep at least
+     * the {@link AbstractList} type.
+     *
+     * @param to the stamp this stamp should be casted to
+     * @return This stamp casted to the {@code to} stamp
+     */
+    public Stamp castTo(ObjectStamp to) {
+        return join0(to, true);
+    }
+
+    private Stamp join0(Stamp otherStamp, boolean castToOther) {
+        if (this == otherStamp) {
+            return this;
+        }
+        if (!isCompatible(otherStamp)) {
+            return StampFactory.illegal(Kind.Illegal);
+        }
+        AbstractObjectStamp other = (AbstractObjectStamp) otherStamp;
+        if (!isLegal()) {
+            return this;
+        } else if (!other.isLegal()) {
+            return other;
+        }
+
+        ResolvedJavaType joinType;
+        boolean joinAlwaysNull = alwaysNull || other.alwaysNull;
+        boolean joinNonNull = nonNull || other.nonNull;
+        boolean joinExactType = exactType || other.exactType;
+        if (Objects.equals(type, other.type)) {
+            joinType = type;
+        } else if (type == null && other.type == null) {
+            joinType = null;
+        } else if (type == null) {
+            joinType = other.type;
+        } else if (other.type == null) {
+            joinType = type;
+        } else {
+            // both types are != null and different
+            if (type.isAssignableFrom(other.type)) {
+                joinType = other.type;
+                if (exactType) {
+                    joinAlwaysNull = true;
+                }
+            } else if (other.type.isAssignableFrom(type)) {
+                joinType = type;
+                if (other.exactType) {
+                    joinAlwaysNull = true;
+                }
+            } else {
+                if (castToOther) {
+                    joinType = other.type;
+                    joinExactType = other.exactType;
+                } else {
+                    joinType = null;
+                }
+                if (joinExactType || (!type.isInterface() && !other.type.isInterface())) {
+                    joinAlwaysNull = true;
+                }
+            }
+        }
+        if (joinAlwaysNull) {
+            joinType = null;
+            joinExactType = false;
+        }
+        if (joinExactType && joinType == null) {
+            return StampFactory.illegal(Kind.Object);
+        }
+        if (joinAlwaysNull && joinNonNull) {
+            return StampFactory.illegal(Kind.Object);
+        } else if (joinExactType && !isConcreteType(joinType)) {
+            return StampFactory.illegal(Kind.Object);
+        }
+        if (Objects.equals(joinType, type) && joinExactType == exactType && joinNonNull == nonNull && joinAlwaysNull == alwaysNull) {
+            return this;
+        } else if (Objects.equals(joinType, other.type) && joinExactType == other.exactType && joinNonNull == other.nonNull && joinAlwaysNull == other.alwaysNull) {
+            return other;
+        } else {
+            return copyWith(joinType, joinExactType, joinNonNull, joinAlwaysNull);
+        }
+    }
+
+    public static boolean isConcreteType(ResolvedJavaType type) {
+        return !(type.isAbstract() && !type.isArray());
+    }
+
+    private static ResolvedJavaType meetTypes(ResolvedJavaType a, ResolvedJavaType b) {
+        if (Objects.equals(a, b)) {
+            return a;
+        } else if (a == null || b == null) {
+            return null;
+        } else {
+            return a.findLeastCommonAncestor(b);
+        }
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + (exactType ? 1231 : 1237);
+        result = prime * result + (nonNull ? 1231 : 1237);
+        result = prime * result + (alwaysNull ? 1231 : 1237);
+        result = prime * result + ((type == null) ? 0 : type.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null || getClass() != obj.getClass()) {
+            return false;
+        }
+        AbstractObjectStamp other = (AbstractObjectStamp) obj;
+        if (exactType != other.exactType || nonNull != other.nonNull || alwaysNull != other.alwaysNull) {
+            return false;
+        }
+        if (type == null) {
+            if (other.type != null) {
+                return false;
+            }
+        } else if (!type.equals(other.type)) {
+            return false;
+        }
+        return true;
+    }
+}
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/ObjectStamp.java	Tue May 20 19:06:41 2014 -0700
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/ObjectStamp.java	Wed May 21 10:08:39 2014 -0700
@@ -22,23 +22,18 @@
  */
 package com.oracle.graal.compiler.common.type;
 
-import java.util.*;
-
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.common.spi.*;
 
-public class ObjectStamp extends Stamp {
-
-    private final ResolvedJavaType type;
-    private final boolean exactType;
-    private final boolean nonNull;
-    private final boolean alwaysNull;
+public class ObjectStamp extends AbstractObjectStamp {
 
     public ObjectStamp(ResolvedJavaType type, boolean exactType, boolean nonNull, boolean alwaysNull) {
-        this.type = type;
-        this.exactType = exactType;
-        this.nonNull = nonNull;
-        this.alwaysNull = alwaysNull;
+        super(type, exactType, nonNull, alwaysNull);
+    }
+
+    @Override
+    protected AbstractObjectStamp copyWith(ResolvedJavaType type, boolean exactType, boolean nonNull, boolean alwaysNull) {
+        return new ObjectStamp(type, exactType, nonNull, alwaysNull);
     }
 
     @Override
@@ -47,111 +42,19 @@
     }
 
     @Override
-    public Stamp illegal() {
-        return new ObjectStamp(null, true, true, false);
-    }
-
-    @Override
-    public boolean isLegal() {
-        return !exactType || (type != null && (isConcreteType(type)));
-    }
-
-    @Override
-    public Kind getStackKind() {
-        return Kind.Object;
-    }
-
-    @Override
     public PlatformKind getPlatformKind(PlatformKindTool tool) {
         return tool.getObjectKind();
     }
 
     @Override
-    public ResolvedJavaType javaType(MetaAccessProvider metaAccess) {
-        if (type != null) {
-            return type;
-        }
-        return metaAccess.lookupJavaType(Object.class);
-    }
-
-    public boolean nonNull() {
-        return nonNull;
-    }
-
-    public boolean alwaysNull() {
-        return alwaysNull;
-    }
-
-    public ResolvedJavaType type() {
-        return type;
-    }
-
-    public boolean isExactType() {
-        return exactType;
-    }
-
-    @Override
     public String toString() {
         StringBuilder str = new StringBuilder();
         str.append('a');
-        str.append(nonNull ? "!" : "").append(exactType ? "#" : "").append(' ').append(type == null ? "-" : type.getName()).append(alwaysNull ? " NULL" : "");
+        appendString(str);
         return str.toString();
     }
 
     @Override
-    public Stamp meet(Stamp otherStamp) {
-        if (this == otherStamp) {
-            return this;
-        }
-        if (!(otherStamp instanceof ObjectStamp)) {
-            return StampFactory.illegal(Kind.Illegal);
-        }
-        ObjectStamp other = (ObjectStamp) otherStamp;
-        if (!isLegal()) {
-            return other;
-        } else if (!other.isLegal()) {
-            return this;
-        }
-        ResolvedJavaType meetType;
-        boolean meetExactType;
-        boolean meetNonNull;
-        boolean meetAlwaysNull;
-        if (other.alwaysNull) {
-            meetType = type();
-            meetExactType = exactType;
-            meetNonNull = false;
-            meetAlwaysNull = alwaysNull;
-        } else if (alwaysNull) {
-            meetType = other.type();
-            meetExactType = other.exactType;
-            meetNonNull = false;
-            meetAlwaysNull = other.alwaysNull;
-        } else {
-            meetType = meetTypes(type(), other.type());
-            meetExactType = exactType && other.exactType;
-            if (meetExactType && type != null && other.type != null) {
-                // meeting two valid exact types may result in a non-exact type
-                meetExactType = Objects.equals(meetType, type) && Objects.equals(meetType, other.type);
-            }
-            meetNonNull = nonNull && other.nonNull;
-            meetAlwaysNull = false;
-        }
-
-        if (Objects.equals(meetType, type) && meetExactType == exactType && meetNonNull == nonNull && meetAlwaysNull == alwaysNull) {
-            return this;
-        } else if (Objects.equals(meetType, other.type) && meetExactType == other.exactType && meetNonNull == other.nonNull && meetAlwaysNull == other.alwaysNull) {
-            return other;
-        } else {
-            return new ObjectStamp(meetType, meetExactType, meetNonNull, meetAlwaysNull);
-        }
-    }
-
-    @Override
-    public Stamp join(Stamp otherStamp) {
-        return join0(otherStamp, false);
-    }
-
-    @Override
     public boolean isCompatible(Stamp other) {
         if (this == other) {
             return true;
@@ -161,142 +64,4 @@
         }
         return false;
     }
-
-    /**
-     * Returns the stamp representing the type of this stamp after a cast to the type represented by
-     * the {@code to} stamp. While this is very similar to a {@link #join} operation, in the case
-     * where both types are not obviously related, the cast operation will prefer the type of the
-     * {@code to} stamp. This is necessary as long as ObjectStamps are not able to accurately
-     * represent intersection types.
-     *
-     * For example when joining the {@link RandomAccess} type with the {@link AbstractList} type,
-     * without intersection types, this would result in the most generic type ({@link Object} ). For
-     * this reason, in some cases a {@code castTo} operation is preferable in order to keep at least
-     * the {@link AbstractList} type.
-     *
-     * @param to the stamp this stamp should be casted to
-     * @return This stamp casted to the {@code to} stamp
-     */
-    public Stamp castTo(ObjectStamp to) {
-        return join0(to, true);
-    }
-
-    private Stamp join0(Stamp otherStamp, boolean castToOther) {
-        if (this == otherStamp) {
-            return this;
-        }
-        if (!(otherStamp instanceof ObjectStamp)) {
-            return StampFactory.illegal(Kind.Illegal);
-        }
-        ObjectStamp other = (ObjectStamp) otherStamp;
-        if (!isLegal()) {
-            return this;
-        } else if (!other.isLegal()) {
-            return other;
-        }
-
-        ResolvedJavaType joinType;
-        boolean joinAlwaysNull = alwaysNull || other.alwaysNull;
-        boolean joinNonNull = nonNull || other.nonNull;
-        boolean joinExactType = exactType || other.exactType;
-        if (Objects.equals(type, other.type)) {
-            joinType = type;
-        } else if (type == null && other.type == null) {
-            joinType = null;
-        } else if (type == null) {
-            joinType = other.type;
-        } else if (other.type == null) {
-            joinType = type;
-        } else {
-            // both types are != null and different
-            if (type.isAssignableFrom(other.type)) {
-                joinType = other.type;
-                if (exactType) {
-                    joinAlwaysNull = true;
-                }
-            } else if (other.type.isAssignableFrom(type)) {
-                joinType = type;
-                if (other.exactType) {
-                    joinAlwaysNull = true;
-                }
-            } else {
-                if (castToOther) {
-                    joinType = other.type;
-                    joinExactType = other.exactType;
-                } else {
-                    joinType = null;
-                }
-                if (joinExactType || (!type.isInterface() && !other.type.isInterface())) {
-                    joinAlwaysNull = true;
-                }
-            }
-        }
-        if (joinAlwaysNull) {
-            joinType = null;
-            joinExactType = false;
-        }
-        if (joinExactType && joinType == null) {
-            return StampFactory.illegal(Kind.Object);
-        }
-        if (joinAlwaysNull && joinNonNull) {
-            return StampFactory.illegal(Kind.Object);
-        } else if (joinExactType && !isConcreteType(joinType)) {
-            return StampFactory.illegal(Kind.Object);
-        }
-        if (Objects.equals(joinType, type) && joinExactType == exactType && joinNonNull == nonNull && joinAlwaysNull == alwaysNull) {
-            return this;
-        } else if (Objects.equals(joinType, other.type) && joinExactType == other.exactType && joinNonNull == other.nonNull && joinAlwaysNull == other.alwaysNull) {
-            return other;
-        } else {
-            return new ObjectStamp(joinType, joinExactType, joinNonNull, joinAlwaysNull);
-        }
-    }
-
-    public static boolean isConcreteType(ResolvedJavaType type) {
-        return !(type.isAbstract() && !type.isArray());
-    }
-
-    private static ResolvedJavaType meetTypes(ResolvedJavaType a, ResolvedJavaType b) {
-        if (Objects.equals(a, b)) {
-            return a;
-        } else if (a == null || b == null) {
-            return null;
-        } else {
-            return a.findLeastCommonAncestor(b);
-        }
-    }
-
-    @Override
-    public int hashCode() {
-        final int prime = 31;
-        int result = 1;
-        result = prime * result + (exactType ? 1231 : 1237);
-        result = prime * result + (nonNull ? 1231 : 1237);
-        result = prime * result + (alwaysNull ? 1231 : 1237);
-        result = prime * result + ((type == null) ? 0 : type.hashCode());
-        return result;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj == null || getClass() != obj.getClass()) {
-            return false;
-        }
-        ObjectStamp other = (ObjectStamp) obj;
-        if (exactType != other.exactType || nonNull != other.nonNull || alwaysNull != other.alwaysNull) {
-            return false;
-        }
-        if (type == null) {
-            if (other.type != null) {
-                return false;
-            }
-        } else if (!type.equals(other.type)) {
-            return false;
-        }
-        return true;
-    }
-
 }
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/StampFactory.java	Tue May 20 19:06:41 2014 -0700
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/StampFactory.java	Wed May 21 10:08:39 2014 -0700
@@ -200,7 +200,7 @@
             ResolvedJavaType type = value.isNull() ? null : metaAccess.lookupJavaType(value);
             return new ObjectStamp(type, value.isNonNull(), value.isNonNull(), value.isNull());
         } else {
-            throw new GraalInternalError(Kind.Object + " expected, actual kind: %s", value.getKind());
+            return forConstant(value);
         }
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java	Tue May 20 19:06:41 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java	Wed May 21 10:08:39 2014 -0700
@@ -35,13 +35,12 @@
 public interface CompilerToVM {
 
     /**
-     * Copies the original bytecode of a given method into a given byte array.
+     * Copies the original bytecode of a given method into a new byte array and returns it.
      *
      * @param metaspaceMethod the metaspace Method object
-     * @param code the array into which to copy the original bytecode
-     * @return the value of {@code code}
+     * @return a new byte array containing the original bytecode
      */
-    byte[] initializeBytecode(long metaspaceMethod, byte[] code);
+    byte[] initializeBytecode(long metaspaceMethod);
 
     int exceptionTableLength(long metaspaceMethod);
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java	Tue May 20 19:06:41 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java	Wed May 21 10:08:39 2014 -0700
@@ -43,7 +43,7 @@
     public native long getMetaspaceMethod(Class<?> holder, int slot);
 
     @Override
-    public native byte[] initializeBytecode(long metaspaceMethod, byte[] code);
+    public native byte[] initializeBytecode(long metaspaceMethod);
 
     @Override
     public native int exceptionTableLength(long metaspaceMethod);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java	Tue May 20 19:06:41 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java	Wed May 21 10:08:39 2014 -0700
@@ -277,7 +277,7 @@
 
             case Object:
                 if (compressible && runtime.getConfig().useCompressedOops) {
-                    return new NarrowOopStamp((ObjectStamp) stamp, runtime.getConfig().getOopEncoding());
+                    return NarrowOopStamp.compressed((ObjectStamp) stamp, runtime.getConfig().getOopEncoding());
                 }
         }
         return stamp;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java	Tue May 20 19:06:41 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java	Wed May 21 10:08:39 2014 -0700
@@ -196,7 +196,7 @@
             return null;
         }
         if (code == null && holder.isLinked()) {
-            code = runtime().getCompilerToVM().initializeBytecode(metaspaceMethod, new byte[getCodeSize()]);
+            code = runtime().getCompilerToVM().initializeBytecode(metaspaceMethod);
             assert code.length == getCodeSize() : "expected: " + getCodeSize() + ", actual: " + code.length;
         }
         return code;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CompressionNode.java	Tue May 20 19:06:41 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CompressionNode.java	Wed May 21 10:08:39 2014 -0700
@@ -71,7 +71,7 @@
             case Compress:
                 if (input instanceof ObjectStamp) {
                     // compressed oop
-                    return new NarrowOopStamp((ObjectStamp) input, encoding);
+                    return NarrowOopStamp.compressed((ObjectStamp) input, encoding);
                 } else if (input instanceof IntegerStamp) {
                     // compressed metaspace pointer
                     assert PrimitiveStamp.getBits(input) == 64;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/type/NarrowOopStamp.java	Tue May 20 19:06:41 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/type/NarrowOopStamp.java	Wed May 21 10:08:39 2014 -0700
@@ -27,7 +27,7 @@
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.hotspot.HotSpotVMConfig.CompressEncoding;
 
-public class NarrowOopStamp extends ObjectStamp {
+public class NarrowOopStamp extends AbstractObjectStamp {
 
     public static final PlatformKind NarrowOop = new PlatformKind() {
 
@@ -43,15 +43,20 @@
 
     private final CompressEncoding encoding;
 
-    public NarrowOopStamp(ObjectStamp stamp, CompressEncoding encoding) {
-        this(stamp.type(), stamp.isExactType(), stamp.nonNull(), stamp.alwaysNull(), encoding);
-    }
-
     public NarrowOopStamp(ResolvedJavaType type, boolean exactType, boolean nonNull, boolean alwaysNull, CompressEncoding encoding) {
         super(type, exactType, nonNull, alwaysNull);
         this.encoding = encoding;
     }
 
+    @Override
+    protected AbstractObjectStamp copyWith(ResolvedJavaType type, boolean exactType, boolean nonNull, boolean alwaysNull) {
+        return new NarrowOopStamp(type, exactType, nonNull, alwaysNull, encoding);
+    }
+
+    public static Stamp compressed(AbstractObjectStamp stamp, CompressEncoding encoding) {
+        return new NarrowOopStamp(stamp.type(), stamp.isExactType(), stamp.nonNull(), stamp.alwaysNull(), encoding);
+    }
+
     public Stamp uncompressed() {
         return new ObjectStamp(type(), isExactType(), nonNull(), alwaysNull());
     }
@@ -61,21 +66,6 @@
     }
 
     @Override
-    public Stamp unrestricted() {
-        return new NarrowOopStamp((ObjectStamp) super.unrestricted(), encoding);
-    }
-
-    @Override
-    public Stamp illegal() {
-        return new NarrowOopStamp((ObjectStamp) super.illegal(), encoding);
-    }
-
-    @Override
-    public Kind getStackKind() {
-        return Kind.Object;
-    }
-
-    @Override
     public PlatformKind getPlatformKind(PlatformKindTool tool) {
         return NarrowOop;
     }
@@ -84,33 +74,11 @@
     public String toString() {
         StringBuilder str = new StringBuilder();
         str.append('n');
-        str.append(super.toString());
+        appendString(str);
         return str.toString();
     }
 
     @Override
-    public Stamp meet(Stamp otherStamp) {
-        if (this == otherStamp) {
-            return this;
-        }
-        if (!isCompatible(otherStamp)) {
-            return StampFactory.illegal();
-        }
-        return new NarrowOopStamp((ObjectStamp) super.meet(otherStamp), encoding);
-    }
-
-    @Override
-    public Stamp join(Stamp otherStamp) {
-        if (this == otherStamp) {
-            return this;
-        }
-        if (!isCompatible(otherStamp)) {
-            return StampFactory.illegal(Kind.Illegal);
-        }
-        return new NarrowOopStamp((ObjectStamp) super.join(otherStamp), encoding);
-    }
-
-    @Override
     public boolean isCompatible(Stamp other) {
         if (this == other) {
             return true;
--- a/graal/com.oracle.graal.hotspotvmconfig/src/com/oracle/graal/hotspotvmconfig/HotSpotVMConfigProcessor.java	Tue May 20 19:06:41 2014 -0700
+++ b/graal/com.oracle.graal.hotspotvmconfig/src/com/oracle/graal/hotspotvmconfig/HotSpotVMConfigProcessor.java	Wed May 21 10:08:39 2014 -0700
@@ -135,8 +135,7 @@
         "#define set_optional_int_flag(varName, flagName) do { intx flagValue; if (intxAt((char*) flagName, &flagValue)) { set_int(varName, flagValue); } } while (0)",
         "#define set_optional_long_flag(varName, flagName) do { intx flagValue; if (intxAt((char*) flagName, &flagValue)) { set_long(varName, flagValue); } } while (0)",
         "",
-        "void VMStructs::initHotSpotVMConfig(JNIEnv *env, jobject config) {",
-        "  oop vmconfig_oop = JNIHandles::resolve(config);",
+        "void VMStructs::initHotSpotVMConfig(oop vmconfig_oop) {",
         "  InstanceKlass* vmconfig_klass = InstanceKlass::cast(vmconfig_oop->klass());",
         "",
         "  for (JavaFieldStream fs(vmconfig_klass); !fs.done(); fs.next()) {",
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/UseTrappingNullChecksPhase.java	Tue May 20 19:06:41 2014 -0700
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/UseTrappingNullChecksPhase.java	Wed May 21 10:08:39 2014 -0700
@@ -57,27 +57,53 @@
     }
 
     private static void tryUseTrappingNullCheck(MetaAccessProvider metaAccessProvider, DynamicDeoptimizeNode deopt) {
-        ValueNode speculation = deopt.getSpeculation();
-        if (!speculation.isConstant() || !speculation.asConstant().equals(Constant.NULL_OBJECT)) {
-            return;
-        }
         Node predecessor = deopt.predecessor();
         if (predecessor instanceof MergeNode) {
             MergeNode merge = (MergeNode) predecessor;
 
-            if (merge.phis().isEmpty()) {
-                // Process each predecessor at the merge, unpacking the reasons as needed.
-                ValueNode reason = deopt.getActionAndReason();
-                List<ValueNode> values = reason instanceof ValuePhiNode ? ((ValuePhiNode) reason).values().snapshot() : null;
+            // Process each predecessor at the merge, unpacking the reasons and speculations as
+            // needed.
+            ValueNode reason = deopt.getActionAndReason();
+            ValuePhiNode reasonPhi = null;
+            List<ValueNode> reasons = null;
+            int expectedPhis = 0;
+
+            if (reason instanceof ValuePhiNode) {
+                reasonPhi = (ValuePhiNode) reason;
+                if (reasonPhi.merge() != merge) {
+                    return;
+                }
+                reasons = reasonPhi.values().snapshot();
+                expectedPhis++;
+            } else if (!reason.isConstant()) {
+                return;
+            }
 
-                int index = 0;
-                for (AbstractEndNode end : merge.cfgPredecessors().snapshot()) {
-                    ValueNode thisReason = values != null ? values.get(index++) : reason;
-                    if (thisReason.isConstant()) {
-                        DeoptimizationReason deoptimizationReason = metaAccessProvider.decodeDeoptReason(thisReason.asConstant());
-                        tryUseTrappingNullCheck(deopt, end.predecessor(), deoptimizationReason, null);
-                    }
+            ValueNode speculation = deopt.getSpeculation();
+            ValuePhiNode speculationPhi = null;
+            List<ValueNode> speculations = null;
+            if (speculation instanceof ValuePhiNode) {
+                speculationPhi = (ValuePhiNode) speculation;
+                if (speculationPhi.merge() != merge) {
+                    return;
                 }
+                speculations = speculationPhi.values().snapshot();
+                expectedPhis++;
+            }
+
+            if (merge.phis().count() != expectedPhis) {
+                return;
+            }
+
+            int index = 0;
+            for (AbstractEndNode end : merge.cfgPredecessors().snapshot()) {
+                ValueNode thisReason = reasons != null ? reasons.get(index) : reason;
+                ValueNode thisSpeculation = speculations != null ? speculations.get(index++) : speculation;
+                if (!thisReason.isConstant() || !thisSpeculation.isConstant() || !thisSpeculation.asConstant().equals(Constant.NULL_OBJECT)) {
+                    continue;
+                }
+                DeoptimizationReason deoptimizationReason = metaAccessProvider.decodeDeoptReason(thisReason.asConstant());
+                tryUseTrappingNullCheck(deopt, end.predecessor(), deoptimizationReason, null);
             }
         }
     }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/InliningData.java	Tue May 20 19:06:41 2014 -0700
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/InliningData.java	Wed May 21 10:08:39 2014 -0700
@@ -338,17 +338,17 @@
         return new ExactInlineInfo(invoke, targetMethod);
     }
 
-    private void doInline(CallsiteHolder callerCallsiteHolder, MethodInvocation calleeInfo, Assumptions callerAssumptions) {
+    private void doInline(CallsiteHolder callerCallsiteHolder, MethodInvocation calleeInvocation, Assumptions callerAssumptions) {
         StructuredGraph callerGraph = callerCallsiteHolder.graph();
         Graph.Mark markBeforeInlining = callerGraph.getMark();
-        InlineInfo callee = calleeInfo.callee();
+        InlineInfo calleeInfo = calleeInvocation.callee();
         try {
             try (Debug.Scope scope = Debug.scope("doInline", callerGraph)) {
-                List<Node> invokeUsages = callee.invoke().asNode().usages().snapshot();
-                callee.inline(new Providers(context), callerAssumptions);
-                callerAssumptions.record(calleeInfo.assumptions());
+                List<Node> invokeUsages = calleeInfo.invoke().asNode().usages().snapshot();
+                calleeInfo.inline(new Providers(context), callerAssumptions);
+                callerAssumptions.record(calleeInvocation.assumptions());
                 metricInliningRuns.increment();
-                Debug.dump(callerGraph, "after %s", callee);
+                Debug.dump(callerGraph, "after %s", calleeInfo);
 
                 if (OptCanonicalizer.getValue()) {
                     Graph.Mark markBeforeCanonicalization = callerGraph.getMark();
@@ -369,27 +369,27 @@
         } catch (BailoutException bailout) {
             throw bailout;
         } catch (AssertionError | RuntimeException e) {
-            throw new GraalInternalError(e).addContext(callee.toString());
+            throw new GraalInternalError(e).addContext(calleeInfo.toString());
         } catch (GraalInternalError e) {
-            throw e.addContext(callee.toString());
+            throw e.addContext(calleeInfo.toString());
         }
     }
 
     /**
      * @return true iff inlining was actually performed
      */
-    private boolean tryToInline(CallsiteHolder callerCallsiteHolder, MethodInvocation calleeInfo, MethodInvocation parentInvocation, int inliningDepth) {
-        InlineInfo callee = calleeInfo.callee();
+    private boolean tryToInline(CallsiteHolder callerCallsiteHolder, MethodInvocation calleeInvocation, MethodInvocation parentInvocation, int inliningDepth) {
+        InlineInfo calleeInfo = calleeInvocation.callee();
         Assumptions callerAssumptions = parentInvocation.assumptions();
         metricInliningConsidered.increment();
 
-        if (inliningPolicy.isWorthInlining(probabilities, context.getReplacements(), callee, inliningDepth, calleeInfo.probability(), calleeInfo.relevance(), true)) {
-            doInline(callerCallsiteHolder, calleeInfo, callerAssumptions);
+        if (inliningPolicy.isWorthInlining(probabilities, context.getReplacements(), calleeInfo, inliningDepth, calleeInvocation.probability(), calleeInvocation.relevance(), true)) {
+            doInline(callerCallsiteHolder, calleeInvocation, callerAssumptions);
             return true;
         }
 
         if (context.getOptimisticOptimizations().devirtualizeInvokes()) {
-            callee.tryToDevirtualizeInvoke(context.getMetaAccess(), callerAssumptions);
+            calleeInfo.tryToDevirtualizeInvoke(context.getMetaAccess(), callerAssumptions);
         }
 
         return false;
@@ -403,16 +403,17 @@
         Invoke invoke = callsiteHolder.popInvoke();
         MethodInvocation callerInvocation = currentInvocation();
         Assumptions parentAssumptions = callerInvocation.assumptions();
-        InlineInfo info = getInlineInfo(invoke, parentAssumptions);
+        Assumptions calleeAssumptions = new Assumptions(parentAssumptions.useOptimisticAssumptions());
+        InlineInfo info = populateInlineInfo(invoke, parentAssumptions, calleeAssumptions);
 
         if (info != null) {
             double invokeProbability = callsiteHolder.invokeProbability(invoke);
             double invokeRelevance = callsiteHolder.invokeRelevance(invoke);
-            MethodInvocation calleeInvocation = pushInvocation(info, parentAssumptions, invokeProbability, invokeRelevance);
+            MethodInvocation methodInvocation = new MethodInvocation(info, calleeAssumptions, invokeProbability, invokeRelevance);
+            pushInvocation(methodInvocation);
 
             for (int i = 0; i < info.numberOfMethods(); i++) {
-                Inlineable elem = Inlineable.getInlineableElement(info.methodAt(i), info.invoke(), context.replaceAssumptions(calleeInvocation.assumptions()), canonicalizer);
-                info.setInlinableElement(i, elem);
+                Inlineable elem = info.inlineableElementAt(i);
                 if (elem instanceof InlineableGraph) {
                     pushGraph(((InlineableGraph) elem).getGraph(), invokeProbability * info.probabilityAt(i), invokeRelevance * info.relevanceAt(i));
                 } else {
@@ -423,6 +424,18 @@
         }
     }
 
+    private InlineInfo populateInlineInfo(Invoke invoke, Assumptions parentAssumptions, Assumptions calleeAssumptions) {
+        InlineInfo info = getInlineInfo(invoke, parentAssumptions);
+        if (info == null) {
+            return null;
+        }
+        for (int i = 0; i < info.numberOfMethods(); i++) {
+            Inlineable elem = Inlineable.getInlineableElement(info.methodAt(i), info.invoke(), context.replaceAssumptions(calleeAssumptions), canonicalizer);
+            info.setInlinableElement(i, elem);
+        }
+        return info;
+    }
+
     public int graphCount() {
         return graphQueue.size();
     }
@@ -479,12 +492,10 @@
         return invocationQueue.peekFirst();
     }
 
-    private MethodInvocation pushInvocation(InlineInfo info, Assumptions assumptions, double probability, double relevance) {
-        MethodInvocation methodInvocation = new MethodInvocation(info, new Assumptions(assumptions.useOptimisticAssumptions()), probability, relevance);
+    private void pushInvocation(MethodInvocation methodInvocation) {
         invocationQueue.addFirst(methodInvocation);
-        maxGraphs += info.numberOfMethods();
+        maxGraphs += methodInvocation.callee().numberOfMethods();
         assert graphQueue.size() <= maxGraphs;
-        return methodInvocation;
     }
 
     private void popInvocation() {
--- a/mx/mx_graal.py	Tue May 20 19:06:41 2014 -0700
+++ b/mx/mx_graal.py	Wed May 21 10:08:39 2014 -0700
@@ -1542,7 +1542,7 @@
                     if not mx.library(name, fatalIfMissing=False):
                         mx.log('Skipping ' + groupId + '.' + artifactId + '.jar as ' + name + ' cannot be resolved')
                         return
-        d = mx.Distribution(graalSuite, name=artifactId, path=path, sourcesPath=path, deps=deps, excludedDependencies=[], distDependencies=[])
+        d = mx.Distribution(graalSuite, name=artifactId, path=path, sourcesPath=path, deps=deps, mainClass=None, excludedDependencies=[], distDependencies=[])
         d.make_archive()
         cmd = ['mvn', 'install:install-file', '-DgroupId=' + groupId, '-DartifactId=' + artifactId,
                '-Dversion=1.0-SNAPSHOT', '-Dpackaging=jar', '-Dfile=' + d.path]
@@ -2093,37 +2093,3 @@
     _vm_prefix = opts.vm_prefix
 
     mx.distribution('GRAAL').add_update_listener(_installGraalJarInJdks)
-
-def packagejar(classpath, outputFile, mainClass=None, annotationProcessor=None, stripDebug=False):
-    prefix = '' if mx.get_os() != 'windows' else '\\??\\'  # long file name hack
-    print "creating", outputFile
-    filecount, totalsize = 0, 0
-    with zipfile.ZipFile(outputFile, 'w', zipfile.ZIP_DEFLATED) as zf:
-        manifest = "Manifest-Version: 1.0\n"
-        if mainClass != None:
-            manifest += "Main-Class: %s\n\n" % (mainClass)
-        zf.writestr("META-INF/MANIFEST.MF", manifest)
-        if annotationProcessor != None:
-            zf.writestr("META-INF/services/javax.annotation.processing.Processor", annotationProcessor)
-        for cp in classpath:
-            print "+", cp
-            if cp.endswith(".jar"):
-                with zipfile.ZipFile(cp, 'r') as jar:
-                    for arcname in jar.namelist():
-                        if arcname.endswith('/') or arcname == 'META-INF/MANIFEST.MF' or arcname.endswith('.java') or arcname.lower().startswith("license") or arcname in [".project", ".classpath"]:
-                            continue
-                        zf.writestr(arcname, jar.read(arcname))
-            else:
-                for root, _, files in os.walk(cp):
-                    for f in files:
-                        fullname = os.path.join(root, f)
-                        arcname = fullname[len(cp) + 1:].replace('\\', '/')
-                        if f.endswith(".class"):
-                            zf.write(prefix + fullname, arcname)
-
-        for zi in zf.infolist():
-            filecount += 1
-            totalsize += zi.file_size
-    print "%d files (total size: %.2f kB, jar size: %.2f kB)" % (filecount, totalsize / 1e3, os.path.getsize(outputFile) / 1e3)
-    mx.run([mx.exe_suffix(join(mx.java().jdk, 'bin', 'pack200')), '-r'] + (['-G'] if stripDebug else []) + [outputFile])
-    print "repacked jar size: %.2f kB" % (os.path.getsize(outputFile) / 1e3)
--- a/mxtool/mx.py	Tue May 20 19:06:41 2014 -0700
+++ b/mxtool/mx.py	Wed May 21 10:08:39 2014 -0700
@@ -34,6 +34,7 @@
 """
 
 import sys, os, errno, time, subprocess, shlex, types, urllib2, contextlib, StringIO, zipfile, signal, xml.sax.saxutils, tempfile, fnmatch
+import multiprocessing
 import textwrap
 import socket
 import tarfile
@@ -63,7 +64,7 @@
 A distribution is a jar or zip file containing the output from one or more Java projects.
 """
 class Distribution:
-    def __init__(self, suite, name, path, sourcesPath, deps, excludedDependencies, distDependencies):
+    def __init__(self, suite, name, path, sourcesPath, deps, mainClass, excludedDependencies, distDependencies):
         self.suite = suite
         self.name = name
         self.path = path.replace('/', os.sep)
@@ -71,6 +72,7 @@
         self.sourcesPath = _make_absolute(sourcesPath.replace('/', os.sep), suite.dir) if sourcesPath else None
         self.deps = deps
         self.update_listeners = set()
+        self.mainClass = mainClass
         self.excludedDependencies = excludedDependencies
         self.distDependencies = distDependencies
 
@@ -98,9 +100,17 @@
                 if not hasattr(zf, '_provenance'):
                     zf._provenance = {}
                 existingSource = zf._provenance.get(arcname, None)
-                if existingSource and existingSource != source and not arcname.endswith('/'):
-                    log('warning: ' + self.path + ': overwriting ' + arcname + '\n  new: ' + source + '\n  old: ' + existingSource)
+                isOverwrite = False
+                if existingSource and existingSource != source:
+                    log('warning: ' + self.path + ': avoid overwrite of ' + arcname + '\n  new: ' + source + '\n  old: ' + existingSource)
+                    isOverwrite = True
                 zf._provenance[arcname] = source
+                return isOverwrite
+
+            if self.mainClass:
+                manifest = "Manifest-Version: 1.0\nMain-Class: %s\n\n" % (self.mainClass)
+                if not overwriteCheck(arc.zf, "META-INF/MANIFEST.MF", "project files"):
+                    arc.zf.writestr("META-INF/MANIFEST.MF", manifest)
 
             for dep in self.sorted_deps(includeLibs=True):
                 if dep.isLibrary():
@@ -117,13 +127,13 @@
                                     assert '/' not in service
                                     services.setdefault(service, []).extend(lp.read(arcname).splitlines())
                                 else:
-                                    overwriteCheck(arc.zf, arcname, lpath + '!' + arcname)
-                                    arc.zf.writestr(arcname, lp.read(arcname))
+                                    if not overwriteCheck(arc.zf, arcname, lpath + '!' + arcname):
+                                        arc.zf.writestr(arcname, lp.read(arcname))
                     if srcArc.zf and libSourcePath:
                         with zipfile.ZipFile(libSourcePath, 'r') as lp:
                             for arcname in lp.namelist():
-                                overwriteCheck(srcArc.zf, arcname, lpath + '!' + arcname)
-                                srcArc.zf.writestr(arcname, lp.read(arcname))
+                                if not overwriteCheck(srcArc.zf, arcname, lpath + '!' + arcname):
+                                    srcArc.zf.writestr(arcname, lp.read(arcname))
                 elif dep.isProject():
                     p = dep
 
@@ -157,8 +167,8 @@
                         else:
                             for f in files:
                                 arcname = join(relpath, f).replace(os.sep, '/')
-                                overwriteCheck(arc.zf, arcname, join(root, f))
-                                arc.zf.write(join(root, f), arcname)
+                                if not overwriteCheck(arc.zf, arcname, join(root, f)):
+                                    arc.zf.write(join(root, f), arcname)
                     if srcArc.zf:
                         sourceDirs = p.source_dirs()
                         if p.source_gen_dir():
@@ -169,8 +179,8 @@
                                 for f in files:
                                     if f.endswith('.java'):
                                         arcname = join(relpath, f).replace(os.sep, '/')
-                                        overwriteCheck(srcArc.zf, arcname, join(root, f))
-                                        srcArc.zf.write(join(root, f), arcname)
+                                        if not overwriteCheck(srcArc.zf, arcname, join(root, f)):
+                                            srcArc.zf.write(join(root, f), arcname)
 
             for service, providers in services.iteritems():
                 arcname = 'META-INF/services/' + service
@@ -822,9 +832,10 @@
             path = attrs.pop('path')
             sourcesPath = attrs.pop('sourcesPath', None)
             deps = pop_list(attrs, 'dependencies')
+            mainClass = attrs.pop('mainClass', None)
             exclDeps = pop_list(attrs, 'exclude')
             distDeps = pop_list(attrs, 'distDependencies')
-            d = Distribution(self, name, path, sourcesPath, deps, exclDeps, distDeps)
+            d = Distribution(self, name, path, sourcesPath, deps, mainClass, exclDeps, distDeps)
             d.__dict__.update(attrs)
             self.dists.append(d)
 
@@ -1834,14 +1845,22 @@
     if _opts.killwithsigquit:
         _send_sigquit()
 
+    def is_alive(p):
+        if isinstance(p, subprocess.Popen):
+            return p.poll() is not None
+        assert isinstance(p, multiprocessing.Process), p
+        return p.is_alive()
+
     for p, args in _currentSubprocesses:
-        try:
-            if get_os() == 'windows':
-                p.terminate()
-            else:
-                _kill_process_group(p.pid, signal.SIGKILL)
-        except BaseException as e:
-            log('error while killing subprocess {} "{}": {}'.format(p.pid, ' '.join(args), e))
+        if is_alive(p):
+            try:
+                if get_os() == 'windows':
+                    p.terminate()
+                else:
+                    _kill_process_group(p.pid, signal.SIGKILL)
+            except BaseException as e:
+                if is_alive(p):
+                    log('error while killing subprocess {} "{}": {}'.format(p.pid, ' '.join(args), e))
 
     if _opts and _opts.verbose:
         import traceback
@@ -2285,7 +2304,6 @@
                 t._d = None
             return sorted(tasks, compareTasks)
 
-        import multiprocessing
         cpus = multiprocessing.cpu_count()
         worklist = sortWorklist(tasks.values())
         active = []
@@ -2625,6 +2643,10 @@
             # Atomic on Unix
             shutil.move(self.tmpPath, self.path)
 
+def _archive(args):
+    archive(args)
+    return 0
+
 def archive(args):
     """create jar files for projects and distributions"""
     parser = ArgumentParser(prog='mx archive')
@@ -2642,6 +2664,7 @@
             p = project(name)
             archives.append(p.make_archive())
 
+    logv("generated archives: " + str(archives))
     return archives
 
 def canonicalizeprojects(args):
@@ -4694,7 +4717,7 @@
     'ideclean': [ideclean, ''],
     'ideinit': [ideinit, ''],
     'intellijinit': [intellijinit, ''],
-    'archive': [archive, '[options]'],
+    'archive': [_archive, '[options]'],
     'projectgraph': [projectgraph, ''],
     'pylint': [pylint, ''],
     'javap': [javap, '<class name patterns>'],
--- a/src/share/vm/graal/graalCompilerToVM.cpp	Tue May 20 19:06:41 2014 -0700
+++ b/src/share/vm/graal/graalCompilerToVM.cpp	Wed May 21 10:08:39 2014 -0700
@@ -53,12 +53,6 @@
   TRACE_graal_3("CompilerToVM::" #name); \
   GRAAL_VM_ENTRY_MARK; \
 
-// Entry to native method implementation that calls a JNI function
-// and hence cannot transition current thread to '_thread_in_vm'.
-#define C2V_ENTRY(result_type, name, signature) \
-  JNIEXPORT result_type JNICALL c2v_ ## name signature { \
-  TRACE_graal_3("CompilerToVM::" #name); \
-
 #define C2V_END }
 
 extern "C" {
@@ -91,11 +85,11 @@
 extern uint64_t gHotSpotVMLongConstantEntryArrayStride;
 }
 
-C2V_VMENTRY(void, initializeConfiguration, (JNIEnv *env, jobject, jobject config))
-  VMStructs::initHotSpotVMConfig(env, config);
+C2V_VMENTRY(void, initializeConfiguration, (JNIEnv *, jobject, jobject config))
+  VMStructs::initHotSpotVMConfig(JNIHandles::resolve(config));
 C2V_END
 
-C2V_ENTRY(jbyteArray, initializeBytecode, (JNIEnv *env, jobject, jlong metaspace_method, jbyteArray result))
+C2V_VMENTRY(jbyteArray, initializeBytecode, (JNIEnv *, jobject, jlong metaspace_method))
   methodHandle method = asMethod(metaspace_method);
   ResourceMark rm;
 
@@ -162,9 +156,9 @@
     }
   }
 
-  env->SetByteArrayRegion(result, 0, code_size, reconstituted_code);
-
-  return result;
+  typeArrayOop result_array = oopFactory::new_byteArray(code_size, CHECK_NULL);
+  memcpy(result_array->byte_at_addr(0), reconstituted_code, code_size);
+  return (jbyteArray) JNIHandles::make_local(result_array);
 C2V_END
 
 C2V_VMENTRY(jint, exceptionTableLength, (JNIEnv *, jobject, jlong metaspace_method))
@@ -233,7 +227,7 @@
   return CompilerOracle::should_inline(method) || method->force_inline();
 C2V_END
 
-C2V_VMENTRY(jlong, lookupType, (JNIEnv *env, jobject, jstring jname, jclass accessing_class, jboolean resolve))
+C2V_VMENTRY(jlong, lookupType, (JNIEnv*, jobject, jstring jname, jclass accessing_class, jboolean resolve))
   ResourceMark rm;
   Handle name = JNIHandles::resolve(jname);
   Symbol* class_name = java_lang_String::as_symbol(name, THREAD);
@@ -258,44 +252,44 @@
   return (jlong) (address) resolved_klass;
 C2V_END
 
-C2V_VMENTRY(jobject, resolveConstantInPool, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index))
+C2V_VMENTRY(jobject, resolveConstantInPool, (JNIEnv*, jobject, jlong metaspace_constant_pool, jint index))
   ConstantPool* cp = (ConstantPool*) metaspace_constant_pool;
   oop result = cp->resolve_constant_at(index, CHECK_NULL);
   return JNIHandles::make_local(THREAD, result);
 C2V_END
 
-C2V_VMENTRY(jobject, resolvePossiblyCachedConstantInPool, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index))
+C2V_VMENTRY(jobject, resolvePossiblyCachedConstantInPool, (JNIEnv*, jobject, jlong metaspace_constant_pool, jint index))
   ConstantPool* cp = (ConstantPool*) metaspace_constant_pool;
   oop result = cp->resolve_possibly_cached_constant_at(index, CHECK_NULL);
   return JNIHandles::make_local(THREAD, result);
 C2V_END
 
-C2V_VMENTRY(jint, lookupNameAndTypeRefIndexInPool, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index))
+C2V_VMENTRY(jint, lookupNameAndTypeRefIndexInPool, (JNIEnv*, jobject, jlong metaspace_constant_pool, jint index))
   constantPoolHandle cp = (ConstantPool*) metaspace_constant_pool;
   return cp->name_and_type_ref_index_at(index);
 C2V_END
 
-C2V_VMENTRY(jlong, lookupNameRefInPool, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index))
+C2V_VMENTRY(jlong, lookupNameRefInPool, (JNIEnv*, jobject, jlong metaspace_constant_pool, jint index))
   constantPoolHandle cp = (ConstantPool*) metaspace_constant_pool;
   return (jlong) (address) cp->name_ref_at(index);
 C2V_END
 
-C2V_VMENTRY(jlong, lookupSignatureRefInPool, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index))
+C2V_VMENTRY(jlong, lookupSignatureRefInPool, (JNIEnv*, jobject, jlong metaspace_constant_pool, jint index))
   constantPoolHandle cp = (ConstantPool*) metaspace_constant_pool;
   return (jlong) (address) cp->signature_ref_at(index);
 C2V_END
 
-C2V_VMENTRY(jint, lookupKlassRefIndexInPool, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index))
+C2V_VMENTRY(jint, lookupKlassRefIndexInPool, (JNIEnv*, jobject, jlong metaspace_constant_pool, jint index))
   constantPoolHandle cp = (ConstantPool*) metaspace_constant_pool;
   return cp->klass_ref_index_at(index);
 C2V_END
 
-C2V_VMENTRY(jlong, constantPoolKlassAt, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index))
+C2V_VMENTRY(jlong, constantPoolKlassAt, (JNIEnv*, jobject, jlong metaspace_constant_pool, jint index))
   ConstantPool* cp = (ConstantPool*) metaspace_constant_pool;
   return (jlong) (address) cp->klass_at(index, THREAD);
 C2V_END
 
-C2V_VMENTRY(jlong, lookupKlassInPool, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index, jbyte opcode))
+C2V_VMENTRY(jlong, lookupKlassInPool, (JNIEnv*, jobject, jlong metaspace_constant_pool, jint index, jbyte opcode))
   constantPoolHandle cp = (ConstantPool*) metaspace_constant_pool;
   KlassHandle loading_klass(cp->pool_holder());
   bool is_accessible = false;
@@ -319,13 +313,13 @@
   return (jlong) CompilerToVM::tag_pointer(klass());
 C2V_END
 
-C2V_VMENTRY(jobject, lookupAppendixInPool, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index))
+C2V_VMENTRY(jobject, lookupAppendixInPool, (JNIEnv*, jobject, jlong metaspace_constant_pool, jint index))
   constantPoolHandle cp = (ConstantPool*) metaspace_constant_pool;
   oop appendix_oop = ConstantPool::appendix_at_if_loaded(cp, index);
   return JNIHandles::make_local(THREAD, appendix_oop);
 C2V_END
 
-C2V_VMENTRY(jlong, lookupMethodInPool, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index, jbyte opcode))
+C2V_VMENTRY(jlong, lookupMethodInPool, (JNIEnv*, jobject, jlong metaspace_constant_pool, jint index, jbyte opcode))
   constantPoolHandle cp = (ConstantPool*) metaspace_constant_pool;
   instanceKlassHandle pool_holder(cp->pool_holder());
   Bytecodes::Code bc = (Bytecodes::Code) (((int) opcode) & 0xFF);
@@ -333,12 +327,12 @@
   return (jlong) (address) method();
 C2V_END
 
-C2V_VMENTRY(jint, constantPoolRemapInstructionOperandFromCache, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index))
+C2V_VMENTRY(jint, constantPoolRemapInstructionOperandFromCache, (JNIEnv*, jobject, jlong metaspace_constant_pool, jint index))
   ConstantPool* cp = (ConstantPool*) metaspace_constant_pool;
   return cp->remap_instruction_operand_from_cache(index);
 C2V_END
 
-C2V_VMENTRY(jlong, resolveField, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index, jbyte opcode, jlongArray info_handle))
+C2V_VMENTRY(jlong, resolveField, (JNIEnv*, jobject, jlong metaspace_constant_pool, jint index, jbyte opcode, jlongArray info_handle))
   ResourceMark rm;
   constantPoolHandle cp = (ConstantPool*) metaspace_constant_pool;
   Bytecodes::Code code = (Bytecodes::Code)(((int) opcode) & 0xFF);
@@ -434,7 +428,7 @@
   return (jlong) (address) klass->class_initializer();
 C2V_END
 
-C2V_VMENTRY(jlong, getMaxCallTargetOffset, (JNIEnv *env, jobject, jlong addr))
+C2V_VMENTRY(jlong, getMaxCallTargetOffset, (JNIEnv*, jobject, jlong addr))
   address target_addr = (address) addr;
   if (target_addr != 0x0) {
     int64_t off_low = (int64_t)target_addr - ((int64_t)CodeCache::low_bound() + sizeof(int));
@@ -570,7 +564,7 @@
   return JNIHandles::make_local(result());
 C2V_END
 
-C2V_VMENTRY(jobject, getStackTraceElement, (JNIEnv *env, jobject, jlong metaspace_method, int bci))
+C2V_VMENTRY(jobject, getStackTraceElement, (JNIEnv*, jobject, jlong metaspace_method, int bci))
   ResourceMark rm;
   HandleMark hm;
 
@@ -579,7 +573,7 @@
   return JNIHandles::make_local(element);
 C2V_END
 
-C2V_VMENTRY(jobject, executeCompiledMethodVarargs, (JNIEnv *env, jobject, jobject args, jobject hotspotInstalledCode))
+C2V_VMENTRY(jobject, executeCompiledMethodVarargs, (JNIEnv*, jobject, jobject args, jobject hotspotInstalledCode))
   ResourceMark rm;
   HandleMark hm;
 
@@ -607,7 +601,7 @@
   }
 C2V_END
 
-C2V_ENTRY(jlongArray, getLineNumberTable, (JNIEnv *env, jobject, jlong metaspace_method))
+C2V_VMENTRY(jlongArray, getLineNumberTable, (JNIEnv *, jobject, jlong metaspace_method))
   Method* method = (Method*) metaspace_method;
   if (!method->has_linenumber_table()) {
     return NULL;
@@ -619,19 +613,19 @@
   }
 
   CompressedLineNumberReadStream stream(method->compressed_linenumber_table());
-  jlongArray result = env->NewLongArray(2 * num_entries);
+  typeArrayOop result = oopFactory::new_longArray(2 * num_entries, CHECK_NULL);
 
   int i = 0;
   jlong value;
   while (stream.read_pair()) {
     value = ((long) stream.bci());
-    env->SetLongArrayRegion(result,i,1,&value);
+    result->long_at_put(i, value);
     value = ((long) stream.line());
-    env->SetLongArrayRegion(result,i + 1,1,&value);
+    result->long_at_put(i + 1, value);
     i += 2;
   }
 
-  return result;
+  return (jlongArray) JNIHandles::make_local(result);
 C2V_END
 
 C2V_VMENTRY(jlong, getLocalVariableTableStart, (JNIEnv *, jobject, jlong metaspace_method))
@@ -649,7 +643,7 @@
   return method->localvariable_table_length();
 C2V_END
 
-C2V_VMENTRY(void, reprofile, (JNIEnv *env, jobject, jlong metaspace_method))
+C2V_VMENTRY(void, reprofile, (JNIEnv*, jobject, jlong metaspace_method))
   Method* method = asMethod(metaspace_method);
   MethodCounters* mcs = method->method_counters();
   if (mcs != NULL) {
@@ -673,7 +667,7 @@
 C2V_END
 
 
-C2V_VMENTRY(void, invalidateInstalledCode, (JNIEnv *env, jobject, jobject hotspotInstalledCode))
+C2V_VMENTRY(void, invalidateInstalledCode, (JNIEnv*, jobject, jobject hotspotInstalledCode))
   jlong nativeMethod = InstalledCode::address(hotspotInstalledCode);
   nmethod* m = (nmethod*)nativeMethod;
   if (m != NULL && !m->is_not_entrant()) {
@@ -684,32 +678,36 @@
   InstalledCode::set_address(hotspotInstalledCode, 0);
 C2V_END
 
-C2V_VMENTRY(jobject, getJavaMirror, (JNIEnv *env, jobject, jlong metaspace_klass))
+C2V_VMENTRY(jobject, getJavaMirror, (JNIEnv*, jobject, jlong metaspace_klass))
   Klass* klass = asKlass(metaspace_klass);
   return JNIHandles::make_local(klass->java_mirror());
 C2V_END
 
-C2V_VMENTRY(jlong, readUnsafeKlassPointer, (JNIEnv *env, jobject, jobject o))
+C2V_VMENTRY(jlong, readUnsafeKlassPointer, (JNIEnv*, jobject, jobject o))
   oop resolved_o = JNIHandles::resolve(o);
   jlong klass = (jlong)(address)resolved_o->klass();
   return klass;
 C2V_END
 
-C2V_VMENTRY(jlongArray, collectCounters, (JNIEnv *env, jobject))
+C2V_VMENTRY(jlongArray, collectCounters, (JNIEnv*, jobject))
   typeArrayOop arrayOop = oopFactory::new_longArray(GraalCounterSize, CHECK_NULL);
   JavaThread::collect_counters(arrayOop);
   return (jlongArray) JNIHandles::make_local(arrayOop);
 C2V_END
 
-C2V_ENTRY(jobject, getGPUs, (JNIEnv *env, jobject))
+// In general we should avoid using regular JNI methods to interact with the JVM but this
+// particular case is just about registering JNI methods so it should be a regular native
+// method.
+JNIEXPORT jobject JNICALL c2v_getGPUs (JNIEnv* env, jobject) {
+  TRACE_graal_3("CompilerToVM::getGPUs" );
 #if defined(TARGET_OS_FAMILY_bsd) || defined(TARGET_OS_FAMILY_linux) || defined(TARGET_OS_FAMILY_windows)
   return Gpu::probe_gpus(env);
 #else
   return env->NewStringUTF("");
 #endif
-C2V_END
+}
 
-C2V_VMENTRY(int, allocateCompileId, (JNIEnv *env, jobject, jlong metaspace_method, int entry_bci))
+C2V_VMENTRY(int, allocateCompileId, (JNIEnv*, jobject, jlong metaspace_method, int entry_bci))
   HandleMark hm;
   ResourceMark rm;
   Method* method = (Method*) metaspace_method;
@@ -717,17 +715,17 @@
 C2V_END
 
 
-C2V_VMENTRY(jboolean, isMature, (JNIEnv *env, jobject, jlong metaspace_method_data))
+C2V_VMENTRY(jboolean, isMature, (JNIEnv*, jobject, jlong metaspace_method_data))
   MethodData* mdo = asMethodData(metaspace_method_data);
   return mdo != NULL && mdo->is_mature();
 C2V_END
 
-C2V_VMENTRY(jboolean, hasCompiledCodeForOSR, (JNIEnv *env, jobject, jlong metaspace_method, int entry_bci, int comp_level))
+C2V_VMENTRY(jboolean, hasCompiledCodeForOSR, (JNIEnv*, jobject, jlong metaspace_method, int entry_bci, int comp_level))
   Method* method = asMethod(metaspace_method);
   return method->lookup_osr_nmethod_for(entry_bci, comp_level, true) != NULL;
 C2V_END
 
-C2V_VMENTRY(jlong, getTimeStamp, (JNIEnv *env, jobject))
+C2V_VMENTRY(jlong, getTimeStamp, (JNIEnv*, jobject))
   // tty->time_stamp is the time since VM start which should be used
   // for all HotSpot log output when a timestamp is required.
   return tty->time_stamp().milliseconds();
@@ -744,7 +742,7 @@
   return false;
 }
 
-C2V_VMENTRY(jobject, getNextStackFrame, (JNIEnv *env, jobject compilerToVM, jobject hs_frame, jlongArray methods, jint initialSkip))
+C2V_VMENTRY(jobject, getNextStackFrame, (JNIEnv*, jobject compilerToVM, jobject hs_frame, jlongArray methods, jint initialSkip))
   ResourceMark rm;
 
   if (!thread->has_last_Java_frame()) return NULL;
@@ -879,7 +877,7 @@
   return NULL;
 C2V_END
 
-C2V_VMENTRY(void, resolveInvokeDynamic, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index))
+C2V_VMENTRY(void, resolveInvokeDynamic, (JNIEnv*, jobject, jlong metaspace_constant_pool, jint index))
   ConstantPool* cp = (ConstantPool*)metaspace_constant_pool;
   CallInfo callInfo;
   LinkResolver::resolve_invokedynamic(callInfo, cp, index, CHECK);
@@ -888,7 +886,7 @@
 C2V_END
 
 // public native void materializeVirtualObjects(HotSpotStackFrameReference stackFrame, boolean invalidate);
-C2V_VMENTRY(void, materializeVirtualObjects, (JNIEnv *env, jobject, jobject hs_frame, bool invalidate))
+C2V_VMENTRY(void, materializeVirtualObjects, (JNIEnv*, jobject, jobject hs_frame, bool invalidate))
   ResourceMark rm;
 
   if (hs_frame == NULL) {
@@ -1006,7 +1004,7 @@
 #define METASPACE_SYMBOL      "J"
 
 JNINativeMethod CompilerToVM_methods[] = {
-  {CC"initializeBytecode",                           CC"("METASPACE_METHOD"[B)[B",                                             FN_PTR(initializeBytecode)},
+  {CC"initializeBytecode",                           CC"("METASPACE_METHOD")[B",                                               FN_PTR(initializeBytecode)},
   {CC"exceptionTableStart",                          CC"("METASPACE_METHOD")J",                                                FN_PTR(exceptionTableStart)},
   {CC"exceptionTableLength",                         CC"("METASPACE_METHOD")I",                                                FN_PTR(exceptionTableLength)},
   {CC"hasBalancedMonitors",                          CC"("METASPACE_METHOD")Z",                                                FN_PTR(hasBalancedMonitors)},
--- a/src/share/vm/runtime/vmStructs.hpp	Tue May 20 19:06:41 2014 -0700
+++ b/src/share/vm/runtime/vmStructs.hpp	Wed May 21 10:08:39 2014 -0700
@@ -127,7 +127,7 @@
 #endif
 
 #ifdef GRAAL
-  static void initHotSpotVMConfig(JNIEnv *env, jobject config);
+  static void initHotSpotVMConfig(oop config);
 #endif
 
 private: