Mercurial > hg > graal-jvmci-8
changeset 17238:45c8f71196ec
Merge
author | Stefan Anzinger <stefan.anzinger@oracle.com> |
---|---|
date | Fri, 26 Sep 2014 10:41:19 -0700 |
parents | c990248e816e (current diff) fd0f5f9abb79 (diff) |
children | d1cc47f5b1dd |
files | graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/EdgesSubstitutions.java |
diffstat | 15 files changed, 659 insertions(+), 357 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/FieldIntrospection.java Fri Sep 26 10:40:34 2014 -0700 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/FieldIntrospection.java Fri Sep 26 10:41:19 2014 -0700 @@ -29,8 +29,7 @@ public abstract class FieldIntrospection extends UnsafeAccess { /** - * Interface used by {@link #rescanAllFieldOffsets(CalcOffset)} to determine the offset (in - * bytes) of a field. + * Interface used to determine the offset (in bytes) of a field. */ public interface CalcOffset { @@ -60,14 +59,6 @@ return clazz; } - public static void rescanAllFieldOffsets(CalcOffset calc) { - for (FieldIntrospection nodeClass : allClasses.values()) { - nodeClass.rescanFieldOffsets(calc); - } - } - - protected abstract void rescanFieldOffsets(CalcOffset calc); - public abstract static class BaseFieldScanner { private final CalcOffset calc;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/Fields.java Fri Sep 26 10:41:19 2014 -0700 @@ -0,0 +1,219 @@ +/* + * Copyright (c) 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; + +import static com.oracle.graal.compiler.common.UnsafeAccess.*; + +import java.util.*; + +import sun.misc.*; + +/** + * Describes fields in a class, primarily for access via {@link Unsafe}. + */ +public class Fields { + + protected final Class<?> clazz; + protected final long[] offsets; + private final String[] names; + private final Class<?>[] types; + + public Fields(Class<?> clazz, long[] offsets, Map<Long, String> names, Map<Long, Class<?>> types) { + this.clazz = clazz; + this.offsets = offsets; + + this.names = new String[offsets.length]; + this.types = new Class[offsets.length]; + for (int i = 0; i < offsets.length; i++) { + this.names[i] = names.get(offsets[i]); + this.types[i] = types.get(offsets[i]); + } + } + + /** + * Gets the number of fields represented by this object. + */ + public int getCount() { + return offsets.length; + } + + /** + * Gets the value of a field for a given object. + * + * @param object the object whose field is to be read + * @param index the index of the field (between 0 and {@link #getCount()}) + * @return the value of the specified field which will be boxed if the field type is primitive + */ + public Object get(Object object, int index) { + long offset = offsets[index]; + Class<?> type = types[index]; + Object value = null; + if (type.isPrimitive()) { + if (type == Integer.TYPE) { + value = unsafe.getInt(object, offset); + } else if (type == Long.TYPE) { + value = unsafe.getLong(object, offset); + } else if (type == Boolean.TYPE) { + value = unsafe.getBoolean(object, offset); + } else if (type == Float.TYPE) { + value = unsafe.getFloat(object, offset); + } else if (type == Double.TYPE) { + value = unsafe.getDouble(object, offset); + } else if (type == Short.TYPE) { + value = unsafe.getShort(object, offset); + } else if (type == Character.TYPE) { + value = unsafe.getChar(object, offset); + } else if (type == Byte.TYPE) { + value = unsafe.getByte(object, offset); + } else { + assert false : "unhandled property type: " + type; + } + } else { + value = unsafe.getObject(object, offset); + } + return value; + } + + /** + * Determines if a field in the domain of this object is the same as the field denoted by the + * same index in another {@link Fields} object. + */ + public boolean isSame(Fields other, int index) { + return other.offsets[index] == offsets[index]; + } + + /** + * Gets the name of a field. + * + * @param index index of a field + */ + public String getName(int index) { + return names[index]; + } + + /** + * Gets the type of a field. + * + * @param index index of a field + */ + public Class<?> getType(int index) { + return types[index]; + } + + /** + * Checks that a given field is assignable from a given value. + * + * @param index the index of the field to check + * @param value a value that will be assigned to the field + */ + private boolean checkAssignableFrom(int index, Object value) { + assert value == null || getType(index).isAssignableFrom(value.getClass()) : String.format("%s.%s of type %s is not assignable from %s", clazz.getSimpleName(), getName(index), + getType(index).getSimpleName(), value.getClass().getSimpleName()); + return true; + } + + public void set(Object object, int index, Object value) { + long dataOffset = offsets[index]; + Class<?> type = types[index]; + if (type.isPrimitive()) { + if (type == Integer.TYPE) { + unsafe.putInt(object, dataOffset, (Integer) value); + } else if (type == Long.TYPE) { + unsafe.putLong(object, dataOffset, (Long) value); + } else if (type == Boolean.TYPE) { + unsafe.putBoolean(object, dataOffset, (Boolean) value); + } else if (type == Float.TYPE) { + unsafe.putFloat(object, dataOffset, (Float) value); + } else if (type == Double.TYPE) { + unsafe.putDouble(object, dataOffset, (Double) value); + } else if (type == Short.TYPE) { + unsafe.putShort(object, dataOffset, (Short) value); + } else if (type == Character.TYPE) { + unsafe.putChar(object, dataOffset, (Character) value); + } else if (type == Byte.TYPE) { + unsafe.putByte(object, dataOffset, (Byte) value); + } else { + assert false : "unhandled property type: " + type; + } + } else { + assert checkAssignableFrom(index, value); + unsafe.putObject(object, dataOffset, value); + } + } + + @Override + public String toString() { + return clazz.getSimpleName(); + } + + public void appendFields(StringBuilder sb) { + for (int i = 0; i < offsets.length; i++) { + sb.append(i == 0 ? "" : ", ").append(getName(i)).append('@').append(offsets[i]); + } + } + + public boolean getBoolean(Object n, int i) { + assert types[i] == boolean.class; + return unsafe.getBoolean(n, offsets[i]); + } + + public byte getByte(Object n, int i) { + assert types[i] == byte.class; + return unsafe.getByte(n, offsets[i]); + } + + public short getShort(Object n, int i) { + assert types[i] == short.class; + return unsafe.getShort(n, offsets[i]); + } + + public char getChar(Object n, int i) { + assert types[i] == char.class; + return unsafe.getChar(n, offsets[i]); + } + + public int getInt(Object n, int i) { + assert types[i] == int.class; + return unsafe.getInt(n, offsets[i]); + } + + public long getLong(Object n, int i) { + assert types[i] == long.class; + return unsafe.getLong(n, offsets[i]); + } + + public float getFloat(Object n, int i) { + assert types[i] == float.class; + return unsafe.getFloat(n, offsets[i]); + } + + public double getDouble(Object n, int i) { + assert types[i] == double.class; + return unsafe.getDouble(n, offsets[i]); + } + + public Object getObject(Object object, int i) { + assert !types[i].isPrimitive(); + return unsafe.getObject(object, offsets[i]); + } +}
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CheckGraalInvariants.java Fri Sep 26 10:40:34 2014 -0700 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CheckGraalInvariants.java Fri Sep 26 10:41:19 2014 -0700 @@ -75,28 +75,31 @@ bootclasspath.split(File.pathSeparator); - String graalJar = null; - for (String e : bootclasspath.split(File.pathSeparator)) { - if (e.endsWith("graal.jar")) { - graalJar = e; - break; - } - } - Assert.assertNotNull("Could not find graal.jar on boot class path: " + bootclasspath, graalJar); + final List<String> classNames = new ArrayList<>(); + for (String jarName : new String[]{"graal.jar", "graal-truffle.jar"}) { - final List<String> classNames = new ArrayList<>(); - try { - final ZipFile zipFile = new ZipFile(new File(graalJar)); - for (final Enumeration<? extends ZipEntry> e = zipFile.entries(); e.hasMoreElements();) { - final ZipEntry zipEntry = e.nextElement(); - String name = zipEntry.getName(); - if (name.endsWith(".class")) { - String className = name.substring(0, name.length() - ".class".length()).replace('/', '.'); - classNames.add(className); + String jar = null; + for (String e : bootclasspath.split(File.pathSeparator)) { + if (e.endsWith(jarName)) { + jar = e; + break; } } - } catch (IOException e) { - Assert.fail(e.toString()); + Assert.assertNotNull("Could not find graal.jar on boot class path: " + bootclasspath, jar); + + try { + final ZipFile zipFile = new ZipFile(new File(jar)); + for (final Enumeration<? extends ZipEntry> e = zipFile.entries(); e.hasMoreElements();) { + final ZipEntry zipEntry = e.nextElement(); + String name = zipEntry.getName(); + if (name.endsWith(".class")) { + String className = name.substring(0, name.length() - ".class".length()).replace('/', '.'); + classNames.add(className); + } + } + } catch (IOException e) { + Assert.fail(e.toString()); + } } // Allows a subset of methods to be checked through use of a system property @@ -131,8 +134,9 @@ boolean verifyEquals = !m.isAnnotationPresent(ExcludeFromIdentityComparisonVerification.class); if (matches(filters, methodName)) { executor.execute(() -> { - StructuredGraph graph = new StructuredGraph(metaAccess.lookupJavaMethod(m)); - try (DebugConfigScope s = Debug.setConfig(new DelegatingDebugConfig().disable(INTERCEPT))) { + ResolvedJavaMethod method = metaAccess.lookupJavaMethod(m); + StructuredGraph graph = new StructuredGraph(method); + try (DebugConfigScope s = Debug.setConfig(new DelegatingDebugConfig().disable(INTERCEPT)); Debug.Scope ds = Debug.scope("CheckingGraph", graph, method)) { graphBuilderSuite.apply(graph, context); // update phi stamps graph.getNodes().filter(PhiNode.class).forEach(PhiNode::inferStamp);
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Edges.java Fri Sep 26 10:40:34 2014 -0700 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Edges.java Fri Sep 26 10:41:19 2014 -0700 @@ -28,11 +28,13 @@ import java.util.*; +import com.oracle.graal.compiler.common.*; + /** * Describes {@link Node} fields representing the set of inputs for the node or the set of the * node's successors. */ -public abstract class Edges { +public abstract class Edges extends Fields { /** * Constants denoting whether a set of edges are inputs or successors. @@ -42,41 +44,13 @@ Successors; } - private final Class<? extends Node> nodeClass; private final int directCount; - private final long[] offsets; - private final String[] names; - private final Class<?>[] types; private final Type type; - @SuppressWarnings("unchecked") public Edges(Class<?> nodeClass, Type type, int directCount, long[] offsets, Map<Long, String> names, Map<Long, Class<?>> types) { - this.nodeClass = (Class<? extends Node>) nodeClass; + super(nodeClass, offsets, names, types); this.type = type; this.directCount = directCount; - this.offsets = offsets; - - this.names = new String[offsets.length]; - this.types = new Class[offsets.length]; - for (int i = 0; i < offsets.length; i++) { - this.names[i] = names.get(offsets[i]); - this.types[i] = types.get(offsets[i]); - } - } - - /** - * Gets the number of edges represented by this object. - */ - public int getCount() { - return offsets.length; - } - - /** - * Get the number of direct edges represented by this object. A direct edge goes directly to - * another {@link Node}. An indirect edge goes via a {@link NodeList}. - */ - public int getDirectCount() { - return directCount; } private static Node getNode(Node node, long offset) { @@ -97,6 +71,14 @@ } /** + * Get the number of direct edges represented by this object. A direct edge goes directly to + * another {@link Node}. An indirect edge goes via a {@link NodeList}. + */ + public int getDirectCount() { + return directCount; + } + + /** * Gets the {@link Node} at the end point of a {@linkplain #getDirectCount() direct} edge. * * @param node one end point of the edge @@ -117,7 +99,7 @@ * @return the {@link NodeList} at the other edge of the requested edge */ public NodeList<Node> getNodeList(Node node, int index) { - assert index >= directCount && index < offsets.length; + assert index >= directCount && index < getCount(); return getNodeList(node, offsets[index]); } @@ -152,7 +134,7 @@ * @param toNode the node to which the edges should be copied. */ public void copy(Node fromNode, Node toNode) { - assert fromNode.getNodeClass().getClazz() == nodeClass && toNode.getNodeClass().getClazz() == nodeClass; + assert fromNode.getNodeClass().getClazz() == clazz && toNode.getNodeClass().getClazz() == clazz; int index = 0; while (index < getDirectCount()) { initializeNode(toNode, index, getNode(fromNode, index)); @@ -187,7 +169,7 @@ } while (index < getCount()) { NodeList<Node> list = getNodeList(node, index); - assert list != null : nodeClass; + assert list != null : clazz; if (list.replaceFirst(key, replacement)) { return true; } @@ -196,36 +178,20 @@ return false; } - public boolean isSameEdge(Edges other, int index) { - return offsets[index] == other.offsets[index]; - } - - /** - * Gets the name of an edge. - * - * @param index index of an edge - */ - public String getName(int index) { - return names[index]; + @Override + public void set(Object node, int index, Object value) { + throw new IllegalArgumentException("Cannot call set on " + this); } /** - * Gets the type of the field storing the end point of an edge. + * Sets the value of a given edge without notifying the new and old nodes on the other end of + * the edge of the change. * - * @param index index of an edge + * @param node the node whose edge is to be updated + * @param index the index of the edge (between 0 and {@link #getCount()}) + * @param value the node to be written to the edge */ - public Class<?> getType(int index) { - return types[index]; - } - - private boolean checkAssignable(int index, Node value) { - assert value == null || getType(index).isAssignableFrom(value.getClass()) : String.format("%s.%s of type %s is not assignable from %s", nodeClass.getSimpleName(), getName(index), - getType(index).getSimpleName(), value.getClass().getSimpleName()); - return true; - } - public void initializeNode(Node node, int index, Node value) { - assert checkAssignable(index, value); putNode(node, offsets[index], value); } @@ -234,12 +200,18 @@ putNodeList(node, offsets[index], value); } + /** + * Sets the value of a given edge and notifies the new and old nodes on the other end of the + * edge of the change. + * + * @param node the node whose edge is to be updated + * @param index the index of the edge (between 0 and {@link #getCount()}) + * @param value the node to be written to the edge + */ public void setNode(Node node, int index, Node value) { assert index < directCount; - long offset = offsets[index]; - Node old = getNode(node, offset); - assert checkAssignable(index, value); - putNode(node, offset, value); + Node old = getNode(node, offsets[index]); + putNode(node, offsets[index], value); update(node, old, value); } @@ -263,7 +235,7 @@ * Determines if the edges of two given nodes are the same. */ public boolean areEqualIn(Node node, Node other) { - assert node.getNodeClass().getClazz() == nodeClass && other.getNodeClass().getClazz() == nodeClass; + assert node.getNodeClass().getClazz() == clazz && other.getNodeClass().getClazz() == clazz; int index = 0; while (index < directCount) { if (getNode(other, index) != getNode(node, index)) { @@ -476,12 +448,6 @@ @Override public String toString() { - return nodeClass.getSimpleName() + ":" + type; - } - - void appendOffsets(StringBuilder sb) { - for (int i = 0; i < offsets.length; i++) { - sb.append(i == 0 ? "" : ", ").append(offsets[i]); - } + return super.toString() + ":" + type; } }
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java Fri Sep 26 10:40:34 2014 -0700 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java Fri Sep 26 10:41:19 2014 -0700 @@ -28,6 +28,7 @@ import java.lang.annotation.*; import java.util.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.graph.Graph.NodeEventListener; import com.oracle.graal.graph.iterators.*; import com.oracle.graal.graph.spi.*; @@ -471,8 +472,9 @@ } /** - * Updates the usages sets of the given nodes after an input slot is changed from oldInput to - * newInput: removes this node from oldInput's usages and adds this node to newInput's usages. + * Updates the usages sets of the given nodes after an input slot is changed from + * {@code oldInput} to {@code newInput} by removing this node from {@code oldInput}'s usages and + * adds this node to {@code newInput}'s usages. */ protected void updateUsages(Node oldInput, Node newInput) { assert isAlive() && (newInput == null || newInput.isAlive()) : "adding " + newInput + " to " + this + " instead of " + oldInput; @@ -883,9 +885,9 @@ */ public Map<Object, Object> getDebugProperties(Map<Object, Object> map) { NodeClass nodeClass = getNodeClass(); - for (Integer pos : nodeClass.getPropertyPositions()) { - map.put(nodeClass.getPropertyName(pos), nodeClass.getProperty(this, pos)); - + Fields properties = nodeClass.getProperties(); + for (int i = 0; i < properties.getCount(); i++) { + map.put(properties.getName(i), properties.get(this, i)); } return map; }
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java Fri Sep 26 10:40:34 2014 -0700 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java Fri Sep 26 10:41:19 2014 -0700 @@ -111,8 +111,8 @@ private final Edges inputs; private final Edges successors; + private final Fields properties; - private final Class<?>[] dataTypes; private final boolean canGVN; private final int startGVNNumber; private final String shortName; @@ -174,11 +174,7 @@ inputs = new InputEdges(clazz, fs.inputOffsets.size(), sortedOffsets(fs.inputOffsets, fs.inputListOffsets), fs.fieldNames, fs.fieldTypes, fs.types, fs.optionalInputs); } try (TimerCloseable t1 = Init_Data.start()) { - dataOffsets = sortedLongCopy(fs.dataOffsets); - dataTypes = new Class[dataOffsets.length]; - for (int i = 0; i < dataOffsets.length; i++) { - dataTypes[i] = fs.fieldTypes.get(dataOffsets[i]); - } + properties = new Fields(clazz, sortedLongCopy(fs.dataOffsets), fs.fieldNames, fs.fieldTypes); } isLeafNode = inputs.getCount() + successors.getCount() == 0; @@ -281,11 +277,6 @@ return false; } - @Override - protected void rescanFieldOffsets(CalcOffset calc) { - throw new UnsupportedOperationException(); - } - /** * Determines if a given {@link Node} class is described by this {@link NodeClass} object. This * is useful for doing an exact type test (as opposed to an instanceof test) on a node. For @@ -293,7 +284,7 @@ * * <pre> * if (node.getNodeClass().is(BeginNode.class)) { ... } - * + * * // Due to generated Node classes, the test below * // is *not* the same as the test above: * if (node.getClass() == BeginNode.class) { ... } @@ -407,13 +398,11 @@ public String toString() { StringBuilder str = new StringBuilder(); str.append("NodeClass ").append(getClazz().getSimpleName()).append(" ["); - inputs.appendOffsets(str); - str.append("] ["); - successors.appendOffsets(str); + inputs.appendFields(str); str.append("] ["); - for (int i = 0; i < dataOffsets.length; i++) { - str.append(i == 0 ? "" : ", ").append(dataOffsets[i]); - } + successors.appendFields(str); + str.append("] ["); + properties.appendFields(str); str.append("]"); return str.toString(); } @@ -448,41 +437,41 @@ int number = 0; if (canGVN) { number = startGVNNumber; - for (int i = 0; i < dataOffsets.length; ++i) { - Class<?> type = dataTypes[i]; + for (int i = 0; i < properties.getCount(); ++i) { + Class<?> type = properties.getType(i); if (type.isPrimitive()) { if (type == Integer.TYPE) { - int intValue = unsafe.getInt(n, dataOffsets[i]); + int intValue = properties.getInt(n, i); number += intValue; } else if (type == Long.TYPE) { - long longValue = unsafe.getLong(n, dataOffsets[i]); + long longValue = properties.getLong(n, i); number += longValue ^ (longValue >>> 32); } else if (type == Boolean.TYPE) { - boolean booleanValue = unsafe.getBoolean(n, dataOffsets[i]); + boolean booleanValue = properties.getBoolean(n, i); if (booleanValue) { number += 7; } } else if (type == Float.TYPE) { - float floatValue = unsafe.getFloat(n, dataOffsets[i]); + float floatValue = properties.getFloat(n, i); number += Float.floatToRawIntBits(floatValue); } else if (type == Double.TYPE) { - double doubleValue = unsafe.getDouble(n, dataOffsets[i]); + double doubleValue = properties.getDouble(n, i); long longValue = Double.doubleToRawLongBits(doubleValue); number += longValue ^ (longValue >>> 32); } else if (type == Short.TYPE) { - short shortValue = unsafe.getShort(n, dataOffsets[i]); + short shortValue = properties.getShort(n, i); number += shortValue; } else if (type == Character.TYPE) { - char charValue = unsafe.getChar(n, dataOffsets[i]); + char charValue = properties.getChar(n, i); number += charValue; } else if (type == Byte.TYPE) { - byte byteValue = unsafe.getByte(n, dataOffsets[i]); + byte byteValue = properties.getByte(n, i); number += byteValue; } else { assert false : "unhandled property type: " + type; } } else { - Object o = unsafe.getObject(n, dataOffsets[i]); + Object o = properties.getObject(n, i); number += deepHashCode0(o); } number *= 13; @@ -522,54 +511,54 @@ if (a.getClass() != b.getClass()) { return a == b; } - for (int i = 0; i < dataOffsets.length; ++i) { - Class<?> type = dataTypes[i]; + for (int i = 0; i < properties.getCount(); ++i) { + Class<?> type = properties.getType(i); if (type.isPrimitive()) { if (type == Integer.TYPE) { - int aInt = unsafe.getInt(a, dataOffsets[i]); - int bInt = unsafe.getInt(b, dataOffsets[i]); + int aInt = properties.getInt(a, i); + int bInt = properties.getInt(b, i); if (aInt != bInt) { return false; } } else if (type == Boolean.TYPE) { - boolean aBoolean = unsafe.getBoolean(a, dataOffsets[i]); - boolean bBoolean = unsafe.getBoolean(b, dataOffsets[i]); + boolean aBoolean = properties.getBoolean(a, i); + boolean bBoolean = properties.getBoolean(b, i); if (aBoolean != bBoolean) { return false; } } else if (type == Long.TYPE) { - long aLong = unsafe.getLong(a, dataOffsets[i]); - long bLong = unsafe.getLong(b, dataOffsets[i]); + long aLong = properties.getLong(a, i); + long bLong = properties.getLong(b, i); if (aLong != bLong) { return false; } } else if (type == Float.TYPE) { - float aFloat = unsafe.getFloat(a, dataOffsets[i]); - float bFloat = unsafe.getFloat(b, dataOffsets[i]); + float aFloat = properties.getFloat(a, i); + float bFloat = properties.getFloat(b, i); if (aFloat != bFloat) { return false; } } else if (type == Double.TYPE) { - double aDouble = unsafe.getDouble(a, dataOffsets[i]); - double bDouble = unsafe.getDouble(b, dataOffsets[i]); + double aDouble = properties.getDouble(a, i); + double bDouble = properties.getDouble(b, i); if (aDouble != bDouble) { return false; } } else if (type == Short.TYPE) { - short aShort = unsafe.getShort(a, dataOffsets[i]); - short bShort = unsafe.getShort(b, dataOffsets[i]); + short aShort = properties.getShort(a, i); + short bShort = properties.getShort(b, i); if (aShort != bShort) { return false; } } else if (type == Character.TYPE) { - char aChar = unsafe.getChar(a, dataOffsets[i]); - char bChar = unsafe.getChar(b, dataOffsets[i]); + char aChar = properties.getChar(a, i); + char bChar = properties.getChar(b, i); if (aChar != bChar) { return false; } } else if (type == Byte.TYPE) { - byte aByte = unsafe.getByte(a, dataOffsets[i]); - byte bByte = unsafe.getByte(b, dataOffsets[i]); + byte aByte = properties.getByte(a, i); + byte bByte = properties.getByte(b, i); if (aByte != bByte) { return false; } @@ -577,8 +566,8 @@ assert false : "unhandled type: " + type; } } else { - Object objectA = unsafe.getObject(a, dataOffsets[i]); - Object objectB = unsafe.getObject(b, dataOffsets[i]); + Object objectA = properties.getObject(a, i); + Object objectB = properties.getObject(b, i); if (objectA != objectB) { if (objectA != null && objectB != null) { if (!deepEquals0(objectA, objectB)) { @@ -604,74 +593,14 @@ if (pos.getIndex() >= fromEdges.getCount()) { return false; } - return toEdges.isSameEdge(fromEdges, pos.getIndex()); - } - - public String getPropertyName(int pos) { - return fieldNames.get(dataOffsets[pos]); - } - - public Class<?> getPropertyType(int pos) { - return fieldTypes.get(dataOffsets[pos]); + return toEdges.isSame(fromEdges, pos.getIndex()); } - public Object getProperty(Node node, int pos) { - long dataOffset = dataOffsets[pos]; - Class<?> type = fieldTypes.get(dataOffset); - Object value = null; - if (type.isPrimitive()) { - if (type == Integer.TYPE) { - value = unsafe.getInt(node, dataOffset); - } else if (type == Long.TYPE) { - value = unsafe.getLong(node, dataOffset); - } else if (type == Boolean.TYPE) { - value = unsafe.getBoolean(node, dataOffset); - } else if (type == Float.TYPE) { - value = unsafe.getFloat(node, dataOffset); - } else if (type == Double.TYPE) { - value = unsafe.getDouble(node, dataOffset); - } else if (type == Short.TYPE) { - value = unsafe.getShort(node, dataOffset); - } else if (type == Character.TYPE) { - value = unsafe.getChar(node, dataOffset); - } else if (type == Byte.TYPE) { - value = unsafe.getByte(node, dataOffset); - } else { - assert false : "unhandled property type: " + type; - } - } else { - value = unsafe.getObject(node, dataOffset); - } - return value; - } - - public void setProperty(Node node, int pos, Object value) { - long dataOffset = dataOffsets[pos]; - Class<?> type = fieldTypes.get(dataOffset); - if (type.isPrimitive()) { - if (type == Integer.TYPE) { - unsafe.putInt(node, dataOffset, (Integer) value); - } else if (type == Long.TYPE) { - unsafe.putLong(node, dataOffset, (Long) value); - } else if (type == Boolean.TYPE) { - unsafe.putBoolean(node, dataOffset, (Boolean) value); - } else if (type == Float.TYPE) { - unsafe.putFloat(node, dataOffset, (Float) value); - } else if (type == Double.TYPE) { - unsafe.putDouble(node, dataOffset, (Double) value); - } else if (type == Short.TYPE) { - unsafe.putShort(node, dataOffset, (Short) value); - } else if (type == Character.TYPE) { - unsafe.putChar(node, dataOffset, (Character) value); - } else if (type == Byte.TYPE) { - unsafe.putByte(node, dataOffset, (Byte) value); - } else { - assert false : "unhandled property type: " + type; - } - } else { - assert value == null || !value.getClass().isPrimitive(); - unsafe.putObject(node, dataOffset, value); - } + /** + * Gets the non-edge properties defined by this node class. + */ + public Fields getProperties() { + return properties; } static void updateEdgesInPlace(Node node, InplaceUpdateClosure duplicationReplacement, Edges edges) { @@ -724,36 +653,6 @@ return type == Edges.Type.Inputs ? inputs : successors; } - public Collection<Integer> getPropertyPositions() { - return new AbstractCollection<Integer>() { - @Override - public Iterator<Integer> iterator() { - return new Iterator<Integer>() { - int i = 0; - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - - public Integer next() { - Integer pos = i++; - return pos; - } - - public boolean hasNext() { - return i < dataOffsets.length; - } - }; - } - - @Override - public int size() { - return dataOffsets.length; - } - }; - } - /** * Initializes a fresh allocated node for which no constructor is called yet. Needed to * implement node factories in svm.
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValueClass.java Fri Sep 26 10:40:34 2014 -0700 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValueClass.java Fri Sep 26 10:41:19 2014 -0700 @@ -83,22 +83,6 @@ fieldTypes = scanner.fieldTypes; } - @Override - protected void rescanFieldOffsets(CalcOffset calc) { - ValueFieldScanner scanner = new ValueFieldScanner(calc); - scanner.scan(getClazz()); - - OperandModeAnnotation mode = scanner.valueAnnotations.get(CompositeValue.Component.class); - copyInto(componentOffsets, sortedLongCopy(mode.scalarOffsets, mode.arrayOffsets)); - - copyInto(dataOffsets, sortedLongCopy(scanner.dataOffsets)); - - fieldNames.clear(); - fieldNames.putAll(scanner.fieldNames); - fieldTypes.clear(); - fieldTypes.putAll(scanner.fieldTypes); - } - private static class ValueFieldScanner extends FieldScanner { public ValueFieldScanner(CalcOffset calc) {
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstructionClass.java Fri Sep 26 10:40:34 2014 -0700 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstructionClass.java Fri Sep 26 10:41:19 2014 -0700 @@ -113,32 +113,6 @@ opcodeOffset = scanner.opcodeOffset; } - @Override - protected void rescanFieldOffsets(CalcOffset calc) { - InstructionFieldScanner scanner = new InstructionFieldScanner(calc); - scanner.scan(getClazz()); - - OperandModeAnnotation mode = scanner.valueAnnotations.get(LIRInstruction.Use.class); - copyInto(useOffsets, sortedLongCopy(mode.scalarOffsets, mode.arrayOffsets)); - mode = scanner.valueAnnotations.get(LIRInstruction.Alive.class); - copyInto(aliveOffsets, sortedLongCopy(mode.scalarOffsets, mode.arrayOffsets)); - mode = scanner.valueAnnotations.get(LIRInstruction.Temp.class); - copyInto(tempOffsets, sortedLongCopy(mode.scalarOffsets, mode.arrayOffsets)); - mode = scanner.valueAnnotations.get(LIRInstruction.Def.class); - copyInto(defOffsets, sortedLongCopy(mode.scalarOffsets, mode.arrayOffsets)); - - copyInto(stateOffsets, sortedLongCopy(scanner.stateOffsets)); - copyInto(dataOffsets, sortedLongCopy(scanner.dataOffsets)); - - fieldNames.clear(); - fieldNames.putAll(scanner.fieldNames); - fieldTypes.clear(); - fieldTypes.putAll(scanner.fieldTypes); - - opcodeConstant = scanner.opcodeConstant; - opcodeOffset = scanner.opcodeOffset; - } - private static class InstructionFieldScanner extends FieldScanner { private String opcodeConstant;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/EdgesTest.java Fri Sep 26 10:41:19 2014 -0700 @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2013, 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.replacements.test; + +import java.lang.reflect.*; + +import org.junit.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.compiler.test.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.Edges.Type; +import com.oracle.graal.nodeinfo.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.java.*; +import com.oracle.graal.phases.*; +import com.oracle.graal.phases.common.*; +import com.oracle.graal.phases.common.inlining.*; +import com.oracle.graal.phases.tiers.*; + +public class EdgesTest extends GraalCompilerTest { + + @NodeInfo + static class TestNode extends Node { + @Input NodeInputList<ValueNode> itail; + @Input ConstantNode i1; + @Input FloatingNode i2; + + public static TestNode create() { + return USE_GENERATED_NODES ? new EdgesTest_TestNodeGen() : new TestNode(); + } + } + + StructuredGraph graph = new StructuredGraph(); + TestNode node; + ConstantNode i1; + ConstantNode i2; + ConstantNode i3; + ConstantNode i4; + Edges inputs; + + public EdgesTest() { + node = TestNode.create(); + i1 = ConstantNode.forInt(1, graph); + i2 = ConstantNode.forDouble(1.0d, graph); + i3 = ConstantNode.forInt(4, graph); + i4 = ConstantNode.forInt(14, graph); + node.itail = new NodeInputList<>(node, new ValueNode[]{i3, i4}); + node.i1 = i1; + node.i2 = i2; + graph.add(node); + inputs = node.getNodeClass().getEdges(Type.Inputs); + } + + /** + * Checks that there are no checkcasts in the compiled version of + * {@link Edges#getNode(Node, int)} + */ + @Test + public void test0() { + testMethod(getMethod("getNode", Node.class, int.class), inputs, node, 0); + } + + /** + * Checks that there are no checkcasts in the compiled version of + * {@link Edges#getNodeList(Node, int)} + */ + @Test + public void test1() { + testMethod(getMethod("getNodeList", Node.class, int.class), inputs, node, 2); + } + + /** + * Checks that there are no checkcasts in the compiled version of + * {@link Edges#setNode(Node, int, Node)} + */ + @Test + public void test2() { + testMethod(getMethod("setNode", Node.class, int.class, Node.class), inputs, node, 1, i2); + } + + private void testMethod(Method method, Object receiver, Object... args) { + try { + // Invoke the method to ensure it has a type profile + for (int i = 0; i < 5000; i++) { + method.invoke(receiver, args); + } + } catch (Exception e) { + throw new RuntimeException(e); + } + + StructuredGraph g = parseProfiled(method); + Assumptions assumptions = new Assumptions(false); + HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); + new InliningPhase(new CanonicalizerPhase(true)).apply(g, context); + new CanonicalizerPhase(false).apply(g, context); + Assert.assertTrue(g.getNodes().filter(CheckCastNode.class).isEmpty()); + } + + private static Method getMethod(final String name, Class<?>... parameters) { + try { + return Edges.class.getDeclaredMethod(name, parameters); + } catch (NoSuchMethodException | SecurityException e) { + throw new RuntimeException(e); + } + } +}
--- a/graal/com.oracle.graal.replacements.verifier/src/com/oracle/graal/replacements/verifier/MethodSubstitutionVerifier.java Fri Sep 26 10:40:34 2014 -0700 +++ b/graal/com.oracle.graal.replacements.verifier/src/com/oracle/graal/replacements/verifier/MethodSubstitutionVerifier.java Fri Sep 26 10:41:19 2014 -0700 @@ -89,18 +89,18 @@ } String originalName = originalName(substitutionMethod, annotation); - TypeMirror[] originalSignature = originalSignature(originalType, substitutionMethod, annotation); + boolean isStatic = resolveAnnotationValue(Boolean.class, findAnnotationValue(annotation, ORIGINAL_IS_STATIC)); + TypeMirror[] originalSignature = originalSignature(originalType, substitutionMethod, annotation, isStatic); if (originalSignature == null) { return; } - ExecutableElement originalMethod = originalMethod(substitutionMethod, annotation, originalType, originalName, originalSignature); + ExecutableElement originalMethod = originalMethod(substitutionMethod, annotation, originalType, originalName, originalSignature, isStatic); if (DEBUG && originalMethod != null) { env.getMessager().printMessage(Kind.NOTE, String.format("Found original method %s in type %s.", originalMethod, findEnclosingClass(originalMethod))); } } - private TypeMirror[] originalSignature(TypeElement originalType, ExecutableElement method, AnnotationMirror annotation) { - boolean isStatic = resolveAnnotationValue(Boolean.class, findAnnotationValue(annotation, ORIGINAL_IS_STATIC)); + private TypeMirror[] originalSignature(TypeElement originalType, ExecutableElement method, AnnotationMirror annotation, boolean isStatic) { AnnotationValue signatureValue = findAnnotationValue(annotation, ORIGINAL_SIGNATURE); String signatureString = resolveAnnotationValue(String.class, signatureValue); List<TypeMirror> parameters = new ArrayList<>(); @@ -150,7 +150,7 @@ } private ExecutableElement originalMethod(ExecutableElement substitutionMethod, AnnotationMirror substitutionAnnotation, TypeElement originalType, String originalName, - TypeMirror[] originalSignature) { + TypeMirror[] originalSignature, boolean isStatic) { TypeMirror signatureReturnType = originalSignature[0]; TypeMirror[] signatureParameters = Arrays.copyOfRange(originalSignature, 1, originalSignature.length); List<ExecutableElement> searchElements; @@ -182,6 +182,14 @@ return null; } + if (originalMethod.getModifiers().contains(Modifier.STATIC) != isStatic) { + boolean optional = resolveAnnotationValue(Boolean.class, findAnnotationValue(substitutionAnnotation, "optional")); + if (!optional) { + env.getMessager().printMessage(Kind.ERROR, String.format("The %s element must be set to %s.", ORIGINAL_IS_STATIC, !isStatic), substitutionMethod, substitutionAnnotation); + } + return null; + } + if (!isTypeCompatible(originalMethod.getReturnType(), signatureReturnType)) { env.getMessager().printMessage( Kind.ERROR,
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/EdgesSubstitutions.java Fri Sep 26 10:40:34 2014 -0700 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/EdgesSubstitutions.java Fri Sep 26 10:41:19 2014 -0700 @@ -27,13 +27,14 @@ import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.replacements.nodes.*; /** * Substitutions for improving the performance of some critical methods in {@link Edges}. These * substitutions improve the performance by forcing the relevant methods to be inlined * (intrinsification being a special form of inlining) and removing a checked cast. The latter - * cannot be done directly in Java code as {@link PiNode} is not available to the project containing - * {@link Edges}. + * cannot be done directly in Java code as {@link DeferredPiNode} is not available to the project + * containing {@link Edges}. */ @ClassSubstitution(Edges.class) public class EdgesSubstitutions { @@ -57,5 +58,4 @@ private static void putNodeList(Node node, long offset, NodeList<?> value) { UnsafeStoreNode.store(node, offset, value, Kind.Object, LocationIdentity.ANY_LOCATION); } - }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraalMethodSubstitutions.java Fri Sep 26 10:40:34 2014 -0700 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraalMethodSubstitutions.java Fri Sep 26 10:41:19 2014 -0700 @@ -30,6 +30,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.api.replacements.*; import com.oracle.graal.api.runtime.*; +import com.oracle.graal.graph.*; import com.oracle.graal.nodes.spi.*; /** @@ -50,6 +51,7 @@ replacements.registerSubstitutions(Character.class, CharacterSubstitutions.class); replacements.registerSubstitutions(Short.class, ShortSubstitutions.class); replacements.registerSubstitutions(UnsignedMath.class, UnsignedMathSubstitutions.class); + replacements.registerSubstitutions(Edges.class, EdgesSubstitutions.class); } } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DeferredPiNode.java Fri Sep 26 10:41:19 2014 -0700 @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.replacements.nodes; + +//JaCoCo Exclude + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.type.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; +import com.oracle.graal.nodeinfo.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.replacements.*; + +/** + * A node for use in method substitutions or snippets that changes the type of its input where the + * type is not immediately available at {@link NodeIntrinsificationPhase intrinsification} time. It + * is replaced by a {@link PiNode} once the type becomes constant (which <b>must</b> happen). + */ +@NodeInfo +public class DeferredPiNode extends FloatingNode implements Canonicalizable { + + @Input ValueNode object; + @Input ValueNode type; + + public ValueNode object() { + return object; + } + + public static DeferredPiNode create(ValueNode type, ValueNode object) { + return USE_GENERATED_NODES ? new DeferredPiNodeGen(type, object) : new DeferredPiNode(type, object); + } + + protected DeferredPiNode(ValueNode type, ValueNode object) { + super(StampFactory.object()); + this.type = type; + this.object = object; + } + + @Override + public Node canonical(CanonicalizerTool tool) { + if (type.isConstant()) { + ResolvedJavaType javaType = tool.getConstantReflection().asJavaType(type.asConstant()); + ObjectStamp objectStamp = (ObjectStamp) stamp(); + return PiNode.create(object, javaType, objectStamp.isExactType(), objectStamp.nonNull()); + } + return this; + } + + @NodeIntrinsic + public static native <T> T piCast(Class<T> type, Object object); +}
--- a/mx/mx_graal.py Fri Sep 26 10:40:34 2014 -0700 +++ b/mx/mx_graal.py Fri Sep 26 10:41:19 2014 -0700 @@ -154,6 +154,9 @@ _vmbuild = self.previousBuild def chmodRecursive(dirname, chmodFlagsDir): + if mx.get_os() == 'windows': + return + def _chmodDir(chmodFlags, dirname, fnames): os.chmod(dirname, chmodFlagsDir) @@ -351,9 +354,10 @@ Get the directory within a JDK where the server and client subdirectories are located. """ - if platform.system() == 'Darwin': + mxos = mx.get_os() + if mxos == 'darwin': return join(jdk, 'jre', 'lib') - if platform.system() == 'Windows': + if mxos == 'windows' or mxos == 'cygwin': return join(jdk, 'jre', 'bin') return join(jdk, 'jre', 'lib', mx.get_arch()) @@ -361,9 +365,10 @@ """ Get the directories within a JDK where the jli library designates to. """ - if platform.system() == 'Darwin': + mxos = mx.get_os() + if mxos == 'darwin': return [join(jdk, 'jre', 'lib', 'jli')] - if platform.system() == 'Windows': + if mxos == 'windows' or mxos == 'cygwin': return [join(jdk, 'jre', 'bin'), join(jdk, 'bin')] return [join(jdk, 'jre', 'lib', mx.get_arch(), 'jli'), join(jdk, 'lib', mx.get_arch(), 'jli')] @@ -371,7 +376,8 @@ """ Get the jvm.cfg file. """ - if platform.system() == 'Windows': + mxos = mx.get_os() + if mxos == "windows" or mxos == "cygwin": return join(jdk, 'jre', 'lib', mx.get_arch(), jvmCfgFile) return join(_vmLibDirInJdk(jdk), jvmCfgFile) @@ -426,11 +432,9 @@ jvmCfgLines += [line] assert defaultVM is not None, 'Could not find default VM in ' + jvmCfg - if mx.get_os() != 'windows': - chmodRecursive(jdk, JDK_UNIX_PERMISSIONS_DIR) + chmodRecursive(jdk, JDK_UNIX_PERMISSIONS_DIR) shutil.move(join(_vmLibDirInJdk(jdk), defaultVM), join(_vmLibDirInJdk(jdk), 'original')) - with open(jvmCfg, 'w') as fp: for line in jvmCfgLines: fp.write(line) @@ -525,7 +529,7 @@ graalRuntime_inline_hpp = join(genSrcDir, 'graalRuntime.inline.hpp') cp = os.pathsep.join([mx.distribution(d).path for d in dist.distDependencies] + [dist.path, p.output_dir()]) tmp = StringIO.StringIO() - mx.run_java(['-cp', cp, mainClass], out=tmp.write) + mx.run_java(['-cp', mx._tspU2W(cp), mainClass], out=tmp.write) # Compute SHA1 for currently generated graalRuntime.inline.hpp content # and all other generated sources in genSrcDir @@ -548,7 +552,7 @@ javaClass = join(_graal_home, 'GeneratedSourcesSha1.class') with open(javaSource, 'w') as fp: print >> fp, 'class GeneratedSourcesSha1 { private static final String value = "' + sha1 + '"; }' - subprocess.check_call([mx.java().javac, '-d', _graal_home, javaSource], stderr=subprocess.PIPE, stdout=subprocess.PIPE) + subprocess.check_call([mx.java().javac, '-d', mx._tpU2W(_graal_home), mx._tpU2W(javaSource)], stderr=subprocess.PIPE, stdout=subprocess.PIPE) zf = zipfile.ZipFile(dist.path, 'a') with open(javaClass, 'rb') as fp: zf.writestr(os.path.basename(javaClass), fp.read()) @@ -607,21 +611,26 @@ winSDK = mx.get_env('WIN_SDK', 'C:\\Program Files\\Microsoft SDKs\\Windows\\v7.1\\') - if not exists(winSDK): + if not exists(mx._tpW2U(winSDK)): mx.abort("Could not find Windows SDK : '" + winSDK + "' does not exist") - if not exists(join(winSDK, 'Bin', 'SetEnv.cmd')): + winSDKSetEnv = mx._tpW2U(join(winSDK, 'Bin', 'SetEnv.cmd')) + if not exists(winSDKSetEnv): mx.abort("Invalid Windows SDK path (" + winSDK + ") : could not find Bin/SetEnv.cmd (you can use the WIN_SDK environment variable to specify an other path)") - p = subprocess.Popen('cmd.exe /E:ON /V:ON /K ""' + winSDK + '/Bin/SetEnv.cmd" & echo ' + startToken + '"', \ - shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, creationflags=subprocess.CREATE_NEW_PROCESS_GROUP) + wincmd = 'cmd.exe /E:ON /V:ON /K "' + mx._tpU2W(winSDKSetEnv) + '"' + p = subprocess.Popen(wincmd, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) stdout = p.stdout stdin = p.stdin if logFile: log = open(logFile, 'w') ret = False + + def _writeProcess(s): + stdin.write(s + newLine) + + _writeProcess("echo " + startToken) while True: - # encoding may be None on windows plattforms if sys.stdout.encoding is None: encoding = 'utf-8' @@ -634,25 +643,25 @@ line = line.strip() mx.log(line) if line == startToken: - stdin.write('cd /D ' + workingDir + ' & ' + cmd + ' & echo ' + endToken + newLine) + _writeProcess('cd /D ' + workingDir + ' & ' + cmd + ' & echo ' + endToken) for regex in respondTo.keys(): match = regex.search(line) if match: - stdin.write(respondTo[regex] + newLine) + _writeProcess(respondTo[regex]) if findInOutput: match = findInOutput.search(line) if match: ret = True if line == endToken: if not findInOutput: - stdin.write('echo ERRXXX%errorlevel%' + newLine) + _writeProcess('echo ERRXXX%errorlevel%') else: break if line.startswith('ERRXXX'): if line == 'ERRXXX0': ret = True break - stdin.write('exit' + newLine) + _writeProcess("exit") if logFile: log.close() return ret @@ -806,8 +815,7 @@ vmDir = join(_vmLibDirInJdk(jdk), vm) if not exists(vmDir): - if mx.get_os() != 'windows': - chmodRecursive(jdk, JDK_UNIX_PERMISSIONS_DIR) + chmodRecursive(jdk, JDK_UNIX_PERMISSIONS_DIR) mx.log('Creating VM directory in JDK: ' + vmDir) os.makedirs(vmDir) @@ -838,21 +846,22 @@ mx.logv('[all files in src and make directories are older than ' + timestampFile[len(_graal_home) + 1:] + ' - skipping native build]') continue - if platform.system() == 'Windows': - compilelogfile = _graal_home + '/graalCompile.log' + if platform.system() == 'Windows' or "CYGWIN" in platform.system(): + t_compilelogfile = mx._tpU2W(os.path.join(_graal_home, "graalCompile.log")) mksHome = mx.get_env('MKS_HOME', 'C:\\cygwin\\bin') variant = {'client': 'compiler1', 'server': 'compiler2'}.get(vm, vm) project_config = variant + '_' + build - _runInDebugShell('msbuild ' + _graal_home + r'\build\vs-amd64\jvm.vcproj /p:Configuration=' + project_config + ' /target:clean', _graal_home) - winCompileCmd = r'set HotSpotMksHome=' + mksHome + r'& set OUT_DIR=' + jdk + r'& set JAVA_HOME=' + jdk + r'& set path=%JAVA_HOME%\bin;%path%;%HotSpotMksHome%& cd /D "' + _graal_home + r'\make\windows"& call create.bat ' + _graal_home + t_graal_home = mx._tpU2W(_graal_home) + _runInDebugShell('msbuild ' + t_graal_home + r'\build\vs-amd64\jvm.vcproj /p:Configuration=' + project_config + ' /target:clean', t_graal_home) + winCompileCmd = r'set HotSpotMksHome=' + mksHome + r'& set OUT_DIR=' + mx._tpU2W(jdk) + r'& set JAVA_HOME=' + mx._tpU2W(jdk) + r'& set path=%JAVA_HOME%\bin;%path%;%HotSpotMksHome%& cd /D "' + t_graal_home + r'\make\windows"& call create.bat ' + t_graal_home print winCompileCmd winCompileSuccess = re.compile(r"^Writing \.vcxproj file:") - if not _runInDebugShell(winCompileCmd, _graal_home, compilelogfile, winCompileSuccess): + if not _runInDebugShell(winCompileCmd, t_graal_home, t_compilelogfile, winCompileSuccess): mx.log('Error executing create command') return - winBuildCmd = 'msbuild ' + _graal_home + r'\build\vs-amd64\jvm.vcxproj /p:Configuration=' + project_config + ' /p:Platform=x64' - if not _runInDebugShell(winBuildCmd, _graal_home, compilelogfile): + winBuildCmd = 'msbuild ' + t_graal_home + r'\build\vs-amd64\jvm.vcxproj /p:Configuration=' + project_config + ' /p:Platform=x64' + if not _runInDebugShell(winBuildCmd, t_graal_home, t_compilelogfile): mx.log('Error building project') return else: @@ -1442,7 +1451,8 @@ _jacoco = 'off' t = Task('CleanAndBuildIdealGraphVisualizer') - mx.run(['ant', '-f', join(_graal_home, 'src', 'share', 'tools', 'IdealGraphVisualizer', 'build.xml'), '-q', 'clean', 'build']) + buildxml = mx._tpU2W(join(_graal_home, 'src', 'share', 'tools', 'IdealGraphVisualizer', 'build.xml')) + mx.run(['ant', '-f', buildxml, '-q', 'clean', 'build']) tasks.append(t.stop()) # Prevent Graal modifications from breaking the standard builds @@ -2235,13 +2245,13 @@ findbugsJar = join(findbugsLib, 'findbugs.jar') assert exists(findbugsJar) nonTestProjects = [p for p in mx.projects() if not p.name.endswith('.test') and not p.name.endswith('.jtt')] - outputDirs = [p.output_dir() for p in nonTestProjects] + outputDirs = map(mx._tpU2W, [p.output_dir() for p in nonTestProjects]) findbugsResults = join(_graal_home, 'findbugs.results') - cmd = ['-jar', findbugsJar, '-textui', '-low', '-maxRank', '15'] + cmd = ['-jar', mx._tpU2W(findbugsJar), '-textui', '-low', '-maxRank', '15'] if sys.stdout.isatty(): cmd.append('-progress') - cmd = cmd + ['-auxclasspath', mx.classpath([d.name for d in _jdkDeployedDists] + [p.name for p in nonTestProjects]), '-output', findbugsResults, '-exitcode'] + args + outputDirs + cmd = cmd + ['-auxclasspath', mx.classpath([d.name for d in _jdkDeployedDists] + [p.name for p in nonTestProjects]), '-output', mx._tpU2W(findbugsResults), '-exitcode'] + args + outputDirs exitcode = mx.run_java(cmd, nonZeroIsFatal=False) if exitcode != 0: with open(findbugsResults) as fp:
--- a/mxtool/mx.py Fri Sep 26 10:40:34 2014 -0700 +++ b/mxtool/mx.py Fri Sep 26 10:41:19 2014 -0700 @@ -639,16 +639,7 @@ return NotImplemented def is_present_in_jdk(self, jdk): - for e in jdk.bootclasspath().split(os.pathsep): - if basename(e) == self.jar: - return True - for d in jdk.extdirs().split(os.pathsep): - if len(d) and self.jar in os.listdir(d): - return True - for d in jdk.endorseddirs().split(os.pathsep): - if len(d) and self.jar in os.listdir(d): - return True - return False + return jdk.containsJar(self.jar) def all_deps(self, deps, includeLibs, includeSelf=True, includeJreLibs=False, includeAnnotationProcessors=False): """ @@ -1337,11 +1328,47 @@ return 'linux' elif sys.platform.startswith('sunos'): return 'solaris' - elif sys.platform.startswith('win32') or sys.platform.startswith('cygwin'): + elif sys.platform.startswith('win32'): return 'windows' + elif sys.platform.startswith('cygwin'): + return 'cygwin' else: abort('Unknown operating system ' + sys.platform) +def _tpU2W(p): + """ + Translate a path from unix-style to windows-style + """ + if p is None or get_os() != "cygwin": + return p + return subprocess.check_output(['cygpath', '-w', p]).strip() + +def _tpW2U(p): + """ + Translate a path from windows-style to unix-style + """ + if p is None or get_os() != "cygwin": + return p + return subprocess.check_output(['cygpath', '-u', p]).strip() + +def _tspU2W(p): + """ + Translate a group of paths, seperated by a path seperator. + unix-style to windows-style. + """ + if p is None or p == "" or get_os() != "cygwin": + return p + return ';'.join(map(_tpU2W, p.split(os.pathsep))) + +def _tspW2U(p): + """ + Translate a group of paths, seperated by a path seperator. + windows-style to unix-style. + """ + if p is None or p == "" or get_os() != "cygwin": + return p + return os.pathsep.join(map(_tpW2U, p.split(';'))) + def get_arch(): machine = platform.uname()[4] if machine in ['amd64', 'AMD64', 'x86_64', 'i86pc']: @@ -1530,7 +1557,8 @@ if includeBootClasspath: result = os.pathsep.join([java().bootclasspath(), result]) - return result + + return _tspU2W(result) def classpath_walk(names=None, resolve=True, includeSelf=True, includeBootClasspath=False): """ @@ -1998,7 +2026,7 @@ return cmp(self.parts, other.parts) def _filter_non_existant_paths(paths): - return os.pathsep.join([path for path in paths.split(os.pathsep) if exists(path)]) + return os.pathsep.join([path for path in _tspW2U(paths).split(os.pathsep) if exists(path)]) """ A JavaConfig object encapsulates info on how Java commands are run. @@ -2063,8 +2091,8 @@ os.makedirs(outDir) javaSource = join(myDir, 'ClasspathDump.java') if not exists(join(outDir, 'ClasspathDump.class')): - subprocess.check_call([self.javac, '-d', outDir, javaSource], stderr=subprocess.PIPE, stdout=subprocess.PIPE) - self._bootclasspath, self._extdirs, self._endorseddirs = [x if x != 'null' else None for x in subprocess.check_output([self.java, '-cp', outDir, 'ClasspathDump'], stderr=subprocess.PIPE).split('|')] + subprocess.check_call([self.javac, '-d', _tpU2W(outDir), _tpU2W(javaSource)], stderr=subprocess.PIPE, stdout=subprocess.PIPE) + self._bootclasspath, self._extdirs, self._endorseddirs = [x if x != 'null' else None for x in subprocess.check_output([self.java, '-cp', _tspU2W(outDir), 'ClasspathDump'], stderr=subprocess.PIPE).split('|')] if not self._bootclasspath or not self._extdirs or not self._endorseddirs: warn("Could not find all classpaths: boot='" + str(self._bootclasspath) + "' extdirs='" + str(self._extdirs) + "' endorseddirs='" + str(self._endorseddirs) + "'") self._bootclasspath = _filter_non_existant_paths(self._bootclasspath) @@ -2091,17 +2119,32 @@ def bootclasspath(self): if self._bootclasspath is None: self._init_classpaths() - return self._bootclasspath + return _tspU2W(self._bootclasspath) def extdirs(self): if self._extdirs is None: self._init_classpaths() - return self._extdirs + return _tspU2W(self._extdirs) def endorseddirs(self): if self._endorseddirs is None: self._init_classpaths() - return self._endorseddirs + return _tspU2W(self._endorseddirs) + + def containsJar(self, jar): + if self._bootclasspath is None: + self._init_classpaths() + + for e in self._bootclasspath.split(os.pathsep): + if basename(e) == self.jar: + return True + for d in self._extdirs.split(os.pathsep): + if len(d) and self.jar in os.listdir(d): + return True + for d in self._endorseddirs.split(os.pathsep): + if len(d) and self.jar in os.listdir(d): + return True + return False def check_get_env(key): """ @@ -2232,11 +2275,11 @@ javaSource = join(myDir, 'URLConnectionDownload.java') javaClass = join(myDir, 'URLConnectionDownload.class') if not exists(javaClass) or getmtime(javaClass) < getmtime(javaSource): - subprocess.check_call([java().javac, '-d', myDir, javaSource]) + subprocess.check_call([java().javac, '-d', _tpU2W(myDir), _tpU2W(javaSource)]) verbose = [] if sys.stderr.isatty(): verbose.append("-v") - if run([java().java, '-cp', myDir, 'URLConnectionDownload', path] + verbose + urls, nonZeroIsFatal=False) == 0: + if run([java().java, '-cp', _tpU2W(myDir), 'URLConnectionDownload', _tpU2W(path)] + verbose + urls, nonZeroIsFatal=False) == 0: return abort('Could not download to ' + path + ' from any of the following URLs:\n\n ' + @@ -2291,24 +2334,23 @@ def execute(self): argfileName = join(self.proj.dir, 'javafilelist.txt') argfile = open(argfileName, 'wb') - argfile.write('\n'.join(self.javafilelist)) + argfile.write('\n'.join(map(_tpU2W, self.javafilelist))) argfile.close() processorArgs = [] - processorPath = self.proj.annotation_processors_path() if processorPath: genDir = self.proj.source_gen_dir() if exists(genDir): shutil.rmtree(genDir) os.mkdir(genDir) - processorArgs += ['-processorpath', join(processorPath), '-s', genDir] + processorArgs += ['-processorpath', _tspU2W(join(processorPath)), '-s', _tpU2W(genDir)] else: processorArgs += ['-proc:none'] args = self.args jdk = self.jdk - outputDir = self.outputDir + outputDir = _tpU2W(self.outputDir) compliance = str(jdk.javaCompliance) cp = classpath(self.proj.name, includeSelf=True) toBeDeleted = [argfileName] @@ -2323,7 +2365,7 @@ if jdk.debug_port is not None: javacCmd += ['-J-Xdebug', '-J-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=' + str(jdk.debug_port)] javacCmd += processorArgs - javacCmd += ['@' + argfile.name] + javacCmd += ['@' + _tpU2W(argfile.name)] if not args.warnAPI: javacCmd.append('-XDignore.symbol.file')