# HG changeset patch # User Christian Haeubl # Date 1354260622 -3600 # Node ID e0fcf7802786bb158852f167a0e810fd82f31c60 # Parent 9bd688f91d3ff568e9bac0af75b8da1583e3bf84# Parent 4983da9d3fc7f60ffda46310128d8ae3b5f10bef Merge. diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/TypeCheckHints.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/TypeCheckHints.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/TypeCheckHints.java Fri Nov 30 08:30:22 2012 +0100 @@ -86,7 +86,7 @@ double totalHintProbability = 0.0d; for (ProfiledType ptype : ptypes) { ResolvedJavaType hint = ptype.getType(); - if (type != null && hint.isAssignableTo(type)) { + if (type != null && type.isAssignableFrom(hint)) { hintTypes[hintCount++] = hint; totalHintProbability += ptype.getProbability(); } diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/NameAndSignature.java --- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/NameAndSignature.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/NameAndSignature.java Fri Nov 30 08:30:22 2012 +0100 @@ -26,8 +26,12 @@ import java.util.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.runtime.*; class NameAndSignature { + + public static final MetaAccessProvider runtime = Graal.getRequiredCapability(MetaAccessProvider.class); + final String name; final Class returnType; final Class[] parameterTypes; @@ -67,14 +71,14 @@ public boolean signatureEquals(ResolvedJavaMethod m) { Signature s = m.getSignature(); ResolvedJavaType declaringClass = m.getDeclaringClass(); - if (!s.getReturnType(declaringClass).resolve(declaringClass).isClass(returnType)) { + if (!s.getReturnType(declaringClass).resolve(declaringClass).equals(runtime.lookupJavaType(returnType))) { return false; } if (s.getParameterCount(false) != parameterTypes.length) { return false; } for (int i = 0; i < parameterTypes.length; i++) { - if (!s.getParameterType(i, declaringClass).resolve(declaringClass).isClass(parameterTypes[i])) { + if (!s.getParameterType(i, declaringClass).resolve(declaringClass).equals(runtime.lookupJavaType(parameterTypes[i]))) { return false; } } diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestJavaMethod.java --- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestJavaMethod.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestJavaMethod.java Fri Nov 30 08:30:22 2012 +0100 @@ -68,7 +68,7 @@ for (Map.Entry e : methods.entrySet()) { Class expected = e.getKey().getDeclaringClass(); ResolvedJavaType actual = e.getValue().getDeclaringClass(); - assertTrue(actual.isClass(expected)); + assertTrue(actual.equals(runtime.lookupJavaType(expected))); } } diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestMetaAccessProvider.java --- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestMetaAccessProvider.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestMetaAccessProvider.java Fri Nov 30 08:30:22 2012 +0100 @@ -184,7 +184,6 @@ for (Class c : classes) { ResolvedJavaType type = runtime.lookupJavaType(c); assertNotNull(type); - assertTrue(type.isClass(c)); assertEquals(c.getModifiers(), type.getModifiers()); if (!type.isArray()) { assertEquals(type.getName(), toInternalName(c.getName())); @@ -202,7 +201,7 @@ int expected = reflect.getModifiers() & Modifier.methodModifiers(); int actual = method.getModifiers(); assertEquals(String.format("%s: 0x%x != 0x%x", reflect, expected, actual), expected, actual); - assertTrue(method.getDeclaringClass().isClass(reflect.getDeclaringClass())); + assertTrue(method.getDeclaringClass().equals(runtime.lookupJavaType(reflect.getDeclaringClass()))); } } } @@ -216,7 +215,7 @@ int expected = reflect.getModifiers() & Modifier.fieldModifiers(); int actual = field.getModifiers(); assertEquals(String.format("%s: 0x%x != 0x%x", reflect, expected, actual), expected, actual); - assertTrue(field.getDeclaringClass().isClass(reflect.getDeclaringClass())); + assertTrue(field.getDeclaringClass().equals(runtime.lookupJavaType(reflect.getDeclaringClass()))); } } } @@ -224,11 +223,11 @@ @Test public void lookupJavaTypeConstantTest() { for (Constant c : constants) { - if (c.getKind().isObject() && !c.isNull()) { + if (c.getKind() == Kind.Object && !c.isNull()) { Object o = c.asObject(); ResolvedJavaType type = runtime.lookupJavaType(c); assertNotNull(type); - assertTrue(type.isClass(o.getClass())); + assertTrue(type.equals(runtime.lookupJavaType(o.getClass()))); } else { assertEquals(runtime.lookupJavaType(c), null); } @@ -241,7 +240,7 @@ for (Constant c2 : constants) { // test symmetry assertEquals(runtime.constantEquals(c1, c2), runtime.constantEquals(c2, c1)); - if (!c1.getKind().isObject() && !c2.getKind().isObject()) { + if (c1.getKind() != Kind.Object && c2.getKind() != Kind.Object) { assertEquals(c1.equals(c2), runtime.constantEquals(c2, c1)); } } @@ -251,7 +250,7 @@ @Test public void lookupArrayLengthTest() { for (Constant c : constants) { - if (!c.getKind().isObject() || c.isNull() || !c.asObject().getClass().isArray()) { + if (c.getKind() != Kind.Object || c.isNull() || !c.asObject().getClass().isArray()) { try { int length = runtime.lookupArrayLength(c); fail("Expected " + IllegalArgumentException.class.getName() + " for " + c + ", not " + length); diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaType.java --- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaType.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaType.java Fri Nov 30 08:30:22 2012 +0100 @@ -111,10 +111,10 @@ ResolvedJavaType t1 = runtime.lookupJavaType(c1); ResolvedJavaType t2 = runtime.lookupJavaType(c2); boolean expected = c1.isAssignableFrom(c2); - boolean actual = t2.isAssignableTo(t1); + boolean actual = t1.isAssignableFrom(t2); assertEquals(expected, actual); if (expected && t1 != t2) { - assertFalse(t1.isAssignableTo(t2)); + assertFalse(t2.isAssignableFrom(t1)); } } } @@ -123,7 +123,7 @@ @Test public void isInstanceTest() { for (Constant c : constants) { - if (c.getKind().isObject() && !c.isNull()) { + if (c.getKind() == Kind.Object && !c.isNull()) { Object o = c.asObject(); Class< ? extends Object> cls = o.getClass(); while (cls != null) { @@ -160,7 +160,7 @@ assertTrue("exact(" + c.getName() + ") != null", exactType == null); } else { assertNotNull(exactType); - assertTrue(exactType.isClass(expected)); + assertTrue(exactType.equals(runtime.lookupJavaType(expected))); } } } @@ -175,7 +175,7 @@ assertTrue(actual == null); } else { assertNotNull(actual); - assertTrue(actual.isClass(expected)); + assertTrue(actual.equals(runtime.lookupJavaType(expected))); } } } @@ -188,7 +188,7 @@ ResolvedJavaType[] actual = type.getInterfaces(); assertEquals(expected.length, actual.length); for (int i = 0; i < expected.length; i++) { - assertTrue(actual[i].isClass(expected[i])); + assertTrue(actual[i].equals(runtime.lookupJavaType(expected[i]))); } } } @@ -242,7 +242,7 @@ assertTrue(actual == null); } else { assertNotNull(actual); - assertTrue(actual.isClass(expected)); + assertTrue(actual.equals(runtime.lookupJavaType(expected))); } } } @@ -264,7 +264,7 @@ if (expected == null) { assertNull(subtype); } else { - assertTrue(subtype.isClass(expected)); + assertTrue(subtype.equals(runtime.lookupJavaType(expected))); } } @@ -318,7 +318,7 @@ if (expected == null) { assertNull(actual); } else { - assertTrue(actual.isClass(expected)); + assertTrue(actual.equals(runtime.lookupJavaType(expected))); } } } @@ -330,7 +330,7 @@ ResolvedJavaType type = runtime.lookupJavaType(c); Class expected = getArrayClass(c); ResolvedJavaType actual = type.getArrayClass(); - assertTrue(actual.isClass(expected)); + assertTrue(actual.equals(runtime.lookupJavaType(expected))); } } } @@ -459,9 +459,9 @@ } public static boolean fieldsEqual(Field f, ResolvedJavaField rjf) { - return rjf.getDeclaringClass().isClass(f.getDeclaringClass()) && + return rjf.getDeclaringClass().equals(runtime.lookupJavaType(f.getDeclaringClass())) && rjf.getName().equals(f.getName()) && - rjf.getType().resolve(rjf.getDeclaringClass()).isClass(f.getType()); + rjf.getType().resolve(rjf.getDeclaringClass()).equals(runtime.lookupJavaType(f.getType())); } public static ResolvedJavaField lookupField(ResolvedJavaField[] fields, Field key) { @@ -485,10 +485,10 @@ } private static boolean isHiddenFromReflection(ResolvedJavaField f) { - if (f.getDeclaringClass().isClass(Throwable.class) && f.getName().equals("backtrace")) { + if (f.getDeclaringClass().equals(runtime.lookupJavaType(Throwable.class)) && f.getName().equals("backtrace")) { return true; } - if (f.getDeclaringClass().isClass(ConstantPool.class) && f.getName().equals("constantPoolOop")) { + if (f.getDeclaringClass().equals(runtime.lookupJavaType(ConstantPool.class)) && f.getName().equals("constantPoolOop")) { return true; } return false; diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java Fri Nov 30 08:30:22 2012 +0100 @@ -34,27 +34,27 @@ private static final Constant[] INT_CONSTANT_CACHE = new Constant[100]; static { for (int i = 0; i < INT_CONSTANT_CACHE.length; ++i) { - INT_CONSTANT_CACHE[i] = new Constant(Kind.Int, i); + INT_CONSTANT_CACHE[i] = new Constant(Kind.Int, null, i); } } - public static final Constant NULL_OBJECT = new Constant(null); - public static final Constant INT_MINUS_1 = new Constant(Kind.Int, -1); + public static final Constant NULL_OBJECT = new Constant(Kind.Object, null, 0); + public static final Constant INT_MINUS_1 = new Constant(Kind.Int, null, -1); public static final Constant INT_0 = forInt(0); public static final Constant INT_1 = forInt(1); public static final Constant INT_2 = forInt(2); public static final Constant INT_3 = forInt(3); public static final Constant INT_4 = forInt(4); public static final Constant INT_5 = forInt(5); - public static final Constant LONG_0 = new Constant(Kind.Long, 0L); - public static final Constant LONG_1 = new Constant(Kind.Long, 1L); - public static final Constant FLOAT_0 = new Constant(Kind.Float, Float.floatToRawIntBits(0.0F)); - public static final Constant FLOAT_1 = new Constant(Kind.Float, Float.floatToRawIntBits(1.0F)); - public static final Constant FLOAT_2 = new Constant(Kind.Float, Float.floatToRawIntBits(2.0F)); - public static final Constant DOUBLE_0 = new Constant(Kind.Double, Double.doubleToRawLongBits(0.0D)); - public static final Constant DOUBLE_1 = new Constant(Kind.Double, Double.doubleToRawLongBits(1.0D)); - public static final Constant TRUE = new Constant(Kind.Boolean, 1L); - public static final Constant FALSE = new Constant(Kind.Boolean, 0L); + public static final Constant LONG_0 = new Constant(Kind.Long, null, 0L); + public static final Constant LONG_1 = new Constant(Kind.Long, null, 1L); + public static final Constant FLOAT_0 = new Constant(Kind.Float, null, Float.floatToRawIntBits(0.0F)); + public static final Constant FLOAT_1 = new Constant(Kind.Float, null, Float.floatToRawIntBits(1.0F)); + public static final Constant FLOAT_2 = new Constant(Kind.Float, null, Float.floatToRawIntBits(2.0F)); + public static final Constant DOUBLE_0 = new Constant(Kind.Double, null, Double.doubleToRawLongBits(0.0D)); + public static final Constant DOUBLE_1 = new Constant(Kind.Double, null, Double.doubleToRawLongBits(1.0D)); + public static final Constant TRUE = new Constant(Kind.Boolean, null, 1L); + public static final Constant FALSE = new Constant(Kind.Boolean, null, 0L); static { assert FLOAT_0 != forFloat(-0.0F) : "Constant for 0.0f must be different from -0.0f"; @@ -75,43 +75,9 @@ */ private final long primitive; - /** - * Creates a constant represented by the specified object reference. - * @param object the value of this constant - */ - private Constant(Object object) { - super(Kind.Object); - this.object = object; - this.primitive = 0L; - } - - /** - * Creates a constant represented by the specified primitive. - * - * @param kind the type of this constant - * @param primitive the value of this constant - */ - public Constant(Kind kind, long primitive) { + private Constant(Kind kind, Object object, long primitive) { super(kind); - assert !kind.isObject(); - this.object = null; - this.primitive = primitive; - } - - /** - * Creates an annotated primitive constant. An annotation enables a {@linkplain MetaAccessProvider provider} to - * associate some extra semantic or debugging information with a primitive. An annotated primitive constant - * is never {@linkplain #equals(Object) equal} to a non-annotated constant. - * - * @param kind the type of this constant - * @param primitive the value of this constant - * @param annotation an arbitrary non-null object - */ - public Constant(Kind kind, long primitive, Object annotation) { - super(kind); - assert !kind.isObject(); - assert annotation != null; - this.object = annotation; + this.object = object; this.primitive = primitive; } @@ -121,7 +87,7 @@ * @return {@code true} if this constant is a primitive, or an object constant that is not null */ public boolean isNonNull() { - return !getKind().isObject() || object != null; + return getKind() != Kind.Object || object != null; } /** @@ -130,7 +96,7 @@ * @return {@code true} if this constant is the null constant */ public boolean isNull() { - return getKind().isObject() && object == null; + return getKind() == Kind.Object && object == null; } /** @@ -145,7 +111,7 @@ @Override public String toString() { String annotationSuffix = ""; - if (!getKind().isObject() && getPrimitiveAnnotation() != null) { + if (getKind() != Kind.Object && getPrimitiveAnnotation() != null) { annotationSuffix = "{" + getPrimitiveAnnotation() + "}"; } return getKind().getJavaName() + "[" + getKind().format(asBoxedValue()) + (getKind() != Kind.Object ? "|0x" + Long.toHexString(primitive) : "") + "]" + annotationSuffix; @@ -187,115 +153,72 @@ if (!ignoreKind && getKind() != other.getKind()) { return false; } - if (getKind().isObject()) { + if (getKind() == Kind.Object) { return object == other.object; } return primitive == other.primitive && getPrimitiveAnnotation() == other.getPrimitiveAnnotation(); } /** - * Converts this constant to a primitive int. + * Returns the primitive int value this constant represents. The constant must have a {@link Kind#getStackKind()} of + * {@link Kind#Int}, or kind {@link Kind#Jsr}. * - * @return the int value of this constant + * @return the constant value */ public int asInt() { - if (getKind().getStackKind().isStackInt() || getKind().isJsr()) { - return (int) primitive; - } - throw new Error("Constant is not int: " + this); + assert getKind().getStackKind() == Kind.Int || getKind() == Kind.Jsr; + return (int) primitive; } /** - * Converts this constant to a primitive boolean. + * Returns the primitive boolean value this constant represents. The constant must have kind {@link Kind#Boolean}. * - * @return the boolean value of this constant + * @return the constant value */ public boolean asBoolean() { - if (getKind() == Kind.Boolean) { - return primitive != 0L; - } - throw new Error("Constant is not boolean: " + this); - } - - /** - * Converts this constant to a primitive long. - * - * @return the long value of this constant - */ - public long asLong() { - switch (getKind().getStackKind()) { - case Jsr: - case Int: - case Long: - return primitive; - case Float: - return (long) asFloat(); - case Double: - return (long) asDouble(); - default: - throw new Error("Constant is not long: " + this); - } + assert getKind() == Kind.Boolean; + return primitive != 0L; } /** - * Converts this constant to a primitive float. + * Returns the primitive long value this constant represents. The constant must have kind {@link Kind#Long}, a + * {@link Kind#getStackKind()} of {@link Kind#Int}, or kind {@link Kind#Jsr}. * - * @return the float value of this constant + * @return the constant value */ - public float asFloat() { - if (getKind().isFloat()) { - return Float.intBitsToFloat((int) primitive); - } - throw new Error("Constant is not float: " + this); - } - - /** - * Converts this constant to a primitive double. - * - * @return the double value of this constant - */ - public double asDouble() { - if (getKind().isFloat()) { - return Float.intBitsToFloat((int) primitive); - } - if (getKind().isDouble()) { - return Double.longBitsToDouble(primitive); - } - throw new Error("Constant is not double: " + this); + public long asLong() { + assert getKind() == Kind.Long || getKind().getStackKind() == Kind.Int || getKind() == Kind.Jsr; + return primitive; } /** - * Converts this constant to the object reference it represents. + * Returns the primitive float value this constant represents. The constant must have kind {@link Kind#Float}. * - * @return the object which this constant represents + * @return the constant value */ - public Object asObject() { - if (getKind().isObject()) { - return object; - } - throw new Error("Constant is not object: " + this); + public float asFloat() { + assert getKind() == Kind.Float; + return Float.intBitsToFloat((int) primitive); } /** - * Converts this constant to the jsr reference it represents. + * Returns the primitive double value this constant represents. The constant must have kind {@link Kind#Double}. * - * @return the object which this constant represents + * @return the constant value */ - public int asJsr() { - if (getKind().isJsr()) { - return (int) primitive; - } - throw new Error("Constant is not jsr: " + this); + public double asDouble() { + assert getKind() == Kind.Double; + return Double.longBitsToDouble(primitive); } /** - * Unchecked access to a primitive value. + * Returns the object reference this constant represents. The constant must have kind {@link Kind#Object}. + * + * @return the constant value */ - public long asPrimitive() { - if (getKind().isObject()) { - throw new Error("Constant is not primitive: " + this); - } - return primitive; + public Object asObject() { + assert getKind() == Kind.Object; + return object; } /** @@ -304,7 +227,7 @@ * @return null if this constant is not primitive or has no annotation */ public Object getPrimitiveAnnotation() { - return getKind().isObject() ? null : object; + return getKind() == Kind.Object ? null : object; } /** @@ -314,7 +237,7 @@ */ @Override public int hashCode() { - if (getKind().isObject()) { + if (getKind() == Kind.Object) { return System.identityHashCode(object); } return (int) primitive; @@ -345,7 +268,7 @@ if (Double.compare(d, 1.0D) == 0) { return DOUBLE_1; } - return new Constant(Kind.Double, Double.doubleToRawLongBits(d)); + return new Constant(Kind.Double, null, Double.doubleToRawLongBits(d)); } /** @@ -364,7 +287,7 @@ if (Float.compare(f, 2.0F) == 0) { return FLOAT_2; } - return new Constant(Kind.Float, Float.floatToRawIntBits(f)); + return new Constant(Kind.Float, null, Float.floatToRawIntBits(f)); } /** @@ -374,7 +297,7 @@ * @return a boxed copy of {@code value} */ public static Constant forLong(long i) { - return i == 0 ? LONG_0 : i == 1 ? LONG_1 : new Constant(Kind.Long, i); + return i == 0 ? LONG_0 : i == 1 ? LONG_1 : new Constant(Kind.Long, null, i); } /** @@ -390,7 +313,7 @@ if (i >= 0 && i < INT_CONSTANT_CACHE.length) { return INT_CONSTANT_CACHE[i]; } - return new Constant(Kind.Int, i); + return new Constant(Kind.Int, null, i); } /** @@ -400,7 +323,7 @@ * @return a boxed copy of {@code value} */ public static Constant forByte(byte i) { - return new Constant(Kind.Byte, i); + return new Constant(Kind.Byte, null, i); } /** @@ -420,7 +343,7 @@ * @return a boxed copy of {@code value} */ public static Constant forChar(char i) { - return new Constant(Kind.Char, i); + return new Constant(Kind.Char, null, i); } /** @@ -430,7 +353,7 @@ * @return a boxed copy of {@code value} */ public static Constant forShort(short i) { - return new Constant(Kind.Short, i); + return new Constant(Kind.Short, null, i); } /** @@ -440,7 +363,7 @@ * @return a boxed copy of {@code value} */ public static Constant forJsr(int i) { - return new Constant(Kind.Jsr, i); + return new Constant(Kind.Jsr, null, i); } /** @@ -453,7 +376,27 @@ if (o == null) { return NULL_OBJECT; } - return new Constant(o); + return new Constant(Kind.Object, o, 0L); + } + + /** + * Creates an annotated int or long constant. An annotation enables a client to associate some extra semantic or + * debugging information with a primitive. An annotated primitive constant is never {@linkplain #equals(Object) + * equal} to a non-annotated constant. + * + * @param kind the type of this constant + * @param i the value of this constant + * @param annotation an arbitrary non-null object + */ + public static Constant forIntegerKind(Kind kind, long i, Object annotation) { + switch (kind) { + case Int: + return new Constant(kind, annotation, (int) i); + case Long: + return new Constant(kind, annotation, i); + default: + throw new IllegalArgumentException("not an integer kind: " + kind); + } } /** diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Kind.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Kind.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Kind.java Fri Nov 30 08:30:22 2012 +0100 @@ -24,8 +24,6 @@ import java.lang.reflect.*; -import sun.misc.*; - /** * Denotes the basic kinds of types in CRI, including the all the Java primitive types, for example, {@link Kind#Int} * for {@code int} and {@link Kind#Object} for all object types. A kind has a single character short name, a Java name, @@ -33,51 +31,54 @@ */ public enum Kind { /** The primitive boolean kind, represented as an int on the stack. */ - Boolean('z', "boolean", true, true), + Boolean('z', "boolean", true, java.lang.Boolean.TYPE, java.lang.Boolean.class), /** The primitive byte kind, represented as an int on the stack. */ - Byte('b', "byte", true, true), + Byte('b', "byte", true, java.lang.Byte.TYPE, java.lang.Byte.class), /** The primitive short kind, represented as an int on the stack. */ - Short('s', "short", true, true), + Short('s', "short", true, java.lang.Short.TYPE, java.lang.Short.class), /** The primitive char kind, represented as an int on the stack. */ - Char('c', "char", true, true), + Char('c', "char", true, java.lang.Character.TYPE, java.lang.Character.class), /** The primitive int kind, represented as an int on the stack. */ - Int('i', "int", true, true), + Int('i', "int", true, java.lang.Integer.TYPE, java.lang.Integer.class), /** The primitive float kind. */ - Float('f', "float", true, false), + Float('f', "float", false, java.lang.Float.TYPE, java.lang.Float.class), /** The primitive long kind. */ - Long('j', "long", true, false), + Long('j', "long", false, java.lang.Long.TYPE, java.lang.Long.class), /** The primitive double kind. */ - Double('d', "double", true, false), + Double('d', "double", false, java.lang.Double.TYPE, java.lang.Double.class), /** The Object kind, also used for arrays. */ - Object('a', "Object", false, false), + Object('a', "Object", false, null, null), /** The void float kind. */ - Void('v', "void", false, false), + Void('v', "void", false, java.lang.Void.TYPE, java.lang.Void.class), /** Denote a bytecode address in a {@code JSR} bytecode. */ - Jsr('r', "jsr", false, false), + Jsr('r', "jsr", false, null, null), /** The non-type. */ - Illegal('-', "illegal", false, false); + Illegal('-', "illegal", false, null, null); private final char typeChar; private final String javaName; private final boolean isStackInt; - private final boolean isPrimitive; + private final Class primitiveJavaClass; + private final Class boxedJavaClass; - private Kind(char typeChar, String javaName, boolean isPrimitive, boolean isStackInt) { + private Kind(char typeChar, String javaName, boolean isStackInt, Class primitiveJavaClass, Class boxedJavasClass) { this.typeChar = typeChar; this.javaName = javaName; - this.isPrimitive = isPrimitive; this.isStackInt = isStackInt; + this.primitiveJavaClass = primitiveJavaClass; + this.boxedJavaClass = boxedJavasClass; + assert primitiveJavaClass == null || javaName.equals(primitiveJavaClass.getName()); } /** @@ -96,22 +97,13 @@ } /** - * Checks whether this type is valid as an {@code int} on the Java operand stack. - * - * @return {@code true} if this type is represented by an {@code int} on the operand stack - */ - public boolean isStackInt() { - return this.isStackInt; - } - - /** * Checks whether this type is a Java primitive type. * * @return {@code true} if this is {@link #Boolean}, {@link #Byte}, {@link #Char}, {@link #Short}, {@link #Int}, - * {@link #Long}, {@link #Float} or {@link #Double}. + * {@link #Long}, {@link #Float}, {@link #Double}, or {@link #Void}. */ public boolean isPrimitive() { - return this.isPrimitive; + return primitiveJavaClass != null; } /** @@ -120,7 +112,7 @@ * @return the kind used on the operand stack */ public Kind getStackKind() { - if (isStackInt()) { + if (isStackInt) { return Int; } return this; @@ -178,23 +170,23 @@ * @return the kind */ public static Kind fromJavaClass(Class< ? > klass) { - if (klass == java.lang.Boolean.TYPE) { + if (klass == Boolean.primitiveJavaClass) { return Boolean; - } else if (klass == java.lang.Byte.TYPE) { + } else if (klass == Byte.primitiveJavaClass) { return Byte; - } else if (klass == java.lang.Short.TYPE) { + } else if (klass == Short.primitiveJavaClass) { return Short; - } else if (klass == java.lang.Character.TYPE) { + } else if (klass == Char.primitiveJavaClass) { return Char; - } else if (klass == java.lang.Integer.TYPE) { + } else if (klass == Int.primitiveJavaClass) { return Int; - } else if (klass == java.lang.Long.TYPE) { + } else if (klass == Long.primitiveJavaClass) { return Long; - } else if (klass == java.lang.Float.TYPE) { + } else if (klass == Float.primitiveJavaClass) { return Float; - } else if (klass == java.lang.Double.TYPE) { + } else if (klass == Double.primitiveJavaClass) { return Double; - } else if (klass == java.lang.Void.TYPE) { + } else if (klass == Void.primitiveJavaClass) { return Void; } else { return Object; @@ -207,28 +199,7 @@ * @return the Java class */ public Class< ? > toJavaClass() { - switch (this) { - case Void: - return java.lang.Void.TYPE; - case Long: - return java.lang.Long.TYPE; - case Int: - return java.lang.Integer.TYPE; - case Byte: - return java.lang.Byte.TYPE; - case Char: - return java.lang.Character.TYPE; - case Double: - return java.lang.Double.TYPE; - case Float: - return java.lang.Float.TYPE; - case Short: - return java.lang.Short.TYPE; - case Boolean: - return java.lang.Boolean.TYPE; - default: - return null; - } + return primitiveJavaClass; } /** @@ -237,91 +208,7 @@ * @return the Java class */ public Class< ? > toBoxedJavaClass() { - switch (this) { - case Void: - return java.lang.Void.class; - case Long: - return java.lang.Long.class; - case Int: - return java.lang.Integer.class; - case Byte: - return java.lang.Byte.class; - case Char: - return java.lang.Character.class; - case Double: - return java.lang.Double.class; - case Float: - return java.lang.Float.class; - case Short: - return java.lang.Short.class; - case Boolean: - return java.lang.Boolean.class; - default: - return null; - } - } - - /** - * Checks whether this value type is void. - * - * @return {@code true} if this type is void - */ - public final boolean isVoid() { - return this == Kind.Void; - } - - /** - * Checks whether this value type is long. - * - * @return {@code true} if this type is long - */ - public final boolean isLong() { - return this == Kind.Long; - } - - /** - * Checks whether this value type is float. - * - * @return {@code true} if this type is float - */ - public final boolean isFloat() { - return this == Kind.Float; - } - - /** - * Checks whether this value type is double. - * - * @return {@code true} if this type is double - */ - public final boolean isDouble() { - return this == Kind.Double; - } - - /** - * Checks whether this value type is float or double. - * - * @return {@code true} if this type is float or double - */ - public final boolean isFloatOrDouble() { - return this == Kind.Double || this == Kind.Float; - } - - /** - * Checks whether this value type is an object type. - * - * @return {@code true} if this type is an object - */ - public final boolean isObject() { - return this == Kind.Object; - } - - /** - * Checks whether this value type is an address type. - * - * @return {@code true} if this type is an address - */ - public boolean isJsr() { - return this == Kind.Jsr; + return boxedJavaClass; } /** @@ -346,7 +233,7 @@ * @return a formatted string for {@code value} based on this kind */ public String format(Object value) { - if (isObject()) { + if (this == Kind.Object) { if (value == null) { return "null"; } else { @@ -401,112 +288,6 @@ } /** - * The offset from the origin of an array to the first element. - * - * @return the offset in bytes - */ - public final int getArrayBaseOffset() { - switch (this) { - case Boolean: - return Unsafe.ARRAY_BOOLEAN_BASE_OFFSET; - case Byte: - return Unsafe.ARRAY_BYTE_BASE_OFFSET; - case Char: - return Unsafe.ARRAY_CHAR_BASE_OFFSET; - case Short: - return Unsafe.ARRAY_SHORT_BASE_OFFSET; - case Int: - return Unsafe.ARRAY_INT_BASE_OFFSET; - case Long: - return Unsafe.ARRAY_LONG_BASE_OFFSET; - case Float: - return Unsafe.ARRAY_FLOAT_BASE_OFFSET; - case Double: - return Unsafe.ARRAY_DOUBLE_BASE_OFFSET; - case Object: - return Unsafe.ARRAY_OBJECT_BASE_OFFSET; - default: - assert false : "unexpected kind: " + this; - return -1; - } - } - - /** - * The scale used for the index when accessing elements of an array of this kind. - * - * @return the scale in order to convert the index into a byte offset - */ - public final int getArrayIndexScale() { - switch (this) { - case Boolean: - return Unsafe.ARRAY_BOOLEAN_INDEX_SCALE; - case Byte: - return Unsafe.ARRAY_BYTE_INDEX_SCALE; - case Char: - return Unsafe.ARRAY_CHAR_INDEX_SCALE; - case Short: - return Unsafe.ARRAY_SHORT_INDEX_SCALE; - case Int: - return Unsafe.ARRAY_INT_INDEX_SCALE; - case Long: - return Unsafe.ARRAY_LONG_INDEX_SCALE; - case Float: - return Unsafe.ARRAY_FLOAT_INDEX_SCALE; - case Double: - return Unsafe.ARRAY_DOUBLE_INDEX_SCALE; - case Object: - return Unsafe.ARRAY_OBJECT_INDEX_SCALE; - default: - assert false : "unexpected kind: " + this; - return -1; - } - } - - private static Unsafe unsafeCache; - - private static Unsafe unsafe() { - if (unsafeCache == null) { - unsafeCache = Unsafe.getUnsafe(); - } - return unsafeCache; - } - - - /** - * Utility function for reading a value of this kind using an object and a displacement. - * - * @param object the object from which the value is read - * @param displacement the displacement within the object in bytes - * @return the read value encapsulated in a {@link Constant} object - */ - public Constant readUnsafeConstant(Object object, long displacement) { - assert object != null : displacement; - switch (this) { - case Boolean: - return Constant.forBoolean(unsafe().getBoolean(object, displacement)); - case Byte: - return Constant.forByte(unsafe().getByte(object, displacement)); - case Char: - return Constant.forChar(unsafe().getChar(object, displacement)); - case Short: - return Constant.forShort(unsafe().getShort(object, displacement)); - case Int: - return Constant.forInt(unsafe().getInt(object, displacement)); - case Long: - return Constant.forLong(unsafe().getLong(object, displacement)); - case Float: - return Constant.forFloat(unsafe().getFloat(object, displacement)); - case Double: - return Constant.forDouble(unsafe().getDouble(object, displacement)); - case Object: - return Constant.forObject(unsafe().getObject(object, displacement)); - default: - assert false : "unexpected kind: " + this; - return null; - } - } - - /** * The minimum value that can be represented as a value of this kind. * * @return the minimum value diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaUtil.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaUtil.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaUtil.java Fri Nov 30 08:30:22 2012 +0100 @@ -37,6 +37,15 @@ public class MetaUtil { /** + * Returns true if the specified typed is exactly the type {@link java.lang.Object}. + */ + public static boolean isJavaLangObject(ResolvedJavaType type) { + boolean result = type.getSuperclass() == null && !type.isInterface() && type.getKind() == Kind.Object; + assert result == type.getName().equals("Ljava/lang/Object;") : type.getName(); + return result; + } + + /** * Gets the {@link Class} mirror for a given resolved type. * * @param type the type for which the Java mirror is requested @@ -153,7 +162,7 @@ */ public static String toJavaName(JavaType type, boolean qualified) { Kind kind = type.getKind(); - if (kind.isObject()) { + if (kind == Kind.Object) { return internalNameToJava(type.getName(), qualified); } return type.getKind().getJavaName(); diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java Fri Nov 30 08:30:22 2012 +0100 @@ -38,16 +38,6 @@ */ public enum Representation { /** - * The runtime representation of the data structure containing the static primitive fields of this type. - */ - StaticPrimitiveFields, - - /** - * The runtime representation of the data structure containing the static object fields of this type. - */ - StaticObjectFields, - - /** * The runtime representation of the Java class object of this type. */ JavaClass, @@ -130,13 +120,11 @@ void initialize(); /** - * Checks whether this type is a subtype of another type. - * - * @param other the type to test - * @return {@code true} if this type a subtype of the specified type - * @see Class#isAssignableFrom(Class) + * Determines if this type is either the same as, or is a superclass or superinterface of, the type represented by + * the specified parameter. This method is identical to {@link Class#isAssignableFrom(Class)} in terms of the value + * return for this type. */ - boolean isAssignableTo(ResolvedJavaType other); + boolean isAssignableFrom(ResolvedJavaType other); /** * Checks whether the specified object is an instance of this type. @@ -243,11 +231,6 @@ T getAnnotation(Class annotationClass); /** - * Determines if this type is the same as that represented by a given {@link Class}. - */ - boolean isClass(Class c); - - /** * Returns the instance field of this class (or one of its super classes) at the given * offset, or {@code null} if there is no such field. * diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java --- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Fri Nov 30 08:30:22 2012 +0100 @@ -586,7 +586,7 @@ @Override public void emitBitScanReverse(Variable result, Value value) { - if (value.getKind().isStackInt()) { + if (value.getKind().getStackKind() == Kind.Int) { append(new AMD64BitScanOp(AMD64BitScanOp.IntrinsicOpcode.IBSR, result, value)); } else { append(new AMD64BitScanOp(AMD64BitScanOp.IntrinsicOpcode.LBSR, result, value)); diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java Fri Nov 30 08:30:22 2012 +0100 @@ -128,7 +128,7 @@ new InliningPhase(null, runtime(), hints, assumptions, null, phasePlan, OptimisticOptimizations.ALL).apply(graph); new CanonicalizerPhase(null, runtime(), assumptions).apply(graph); Debug.dump(graph, "Graph"); - new BoxingEliminationPhase().apply(graph); + new BoxingEliminationPhase(runtime()).apply(graph); Debug.dump(graph, "Graph"); new ExpandBoxingNodesPhase(pool).apply(graph); new CanonicalizerPhase(null, runtime(), assumptions).apply(graph); diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/IfBoxingEliminationTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/IfBoxingEliminationTest.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/IfBoxingEliminationTest.java Fri Nov 30 08:30:22 2012 +0100 @@ -93,7 +93,7 @@ new PhiStampPhase().apply(graph); new CanonicalizerPhase(null, runtime(), assumptions).apply(graph); Debug.dump(graph, "Graph"); - new BoxingEliminationPhase().apply(graph); + new BoxingEliminationPhase(runtime()).apply(graph); Debug.dump(graph, "Graph"); new ExpandBoxingNodesPhase(pool).apply(graph); new CanonicalizerPhase(null, runtime(), assumptions).apply(graph); diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Fri Nov 30 08:30:22 2012 +0100 @@ -164,7 +164,7 @@ if (GraalOptions.OptFloatingReads) { int mark = graph.getMark(); new FloatingReadPhase().apply(graph); - new CanonicalizerPhase(target, runtime, assumptions, mark, null).apply(graph); + new CanonicalizerPhase(target, runtime, assumptions, mark).apply(graph); if (GraalOptions.OptReadElimination) { new ReadEliminationPhase().apply(graph); } diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Fri Nov 30 08:30:22 2012 +0100 @@ -507,7 +507,7 @@ @Override public void visitReturn(ReturnNode x) { Value operand = Value.ILLEGAL; - if (!x.kind().isVoid()) { + if (x.kind() != Kind.Void) { operand = resultOperandFor(x.kind()); emitMove(operand(x.result()), operand); } diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRegisterConfig.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRegisterConfig.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRegisterConfig.java Fri Nov 30 08:30:22 2012 +0100 @@ -159,7 +159,7 @@ } } - Value returnLocation = returnKind.isVoid() ? Value.ILLEGAL : getReturnRegister(returnKind).asValue(returnKind); + Value returnLocation = returnKind == Kind.Void ? Value.ILLEGAL : getReturnRegister(returnKind).asValue(returnKind); return new CallingConvention(currentStackOffset, returnLocation, locations); } diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java Fri Nov 30 08:30:22 2012 +0100 @@ -76,7 +76,7 @@ * Reads a word value from a given address. */ public static long unsafeReadWord(long address) { - if (wordKind.isLong()) { + if (wordKind == Kind.Long) { return unsafe.getLong(address); } return unsafe.getInt(address); diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotInstalledCode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotInstalledCode.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotInstalledCode.java Fri Nov 30 08:30:22 2012 +0100 @@ -75,8 +75,8 @@ for (int i = 0; i < sig.length; i++) { Object arg = args[i]; if (arg == null) { - assert sig[i].isObject() : MetaUtil.format("%H.%n(%p): expected arg ", method) + i + " to be Object, not " + sig[i]; - } else if (!sig[i].isObject()) { + assert sig[i] == Kind.Object : MetaUtil.format("%H.%n(%p): expected arg ", method) + i + " to be Object, not " + sig[i]; + } else if (sig[i] != Kind.Object) { assert sig[i].toBoxedJavaClass() == arg.getClass() : MetaUtil.format("%H.%n(%p): expected arg ", method) + i + " to be " + sig[i] + ", not " + arg.getClass(); } } diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java Fri Nov 30 08:30:22 2012 +0100 @@ -27,8 +27,8 @@ import java.lang.reflect.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.meta.ResolvedJavaType.*; import com.oracle.graal.hotspot.*; +import com.oracle.graal.nodes.extended.*; import com.oracle.graal.phases.*; /** @@ -100,13 +100,12 @@ if (receiver == null) { assert Modifier.isStatic(flags); if (holder.isInitialized()) { - Constant encoding = holder.getEncoding(getKind() == Kind.Object ? Representation.StaticObjectFields : Representation.StaticPrimitiveFields); - return this.getKind().readUnsafeConstant(encoding.asObject(), offset); + return ReadNode.readUnsafeConstant(getKind(), holder.mirror(), offset); } return null; } else { assert !Modifier.isStatic(flags); - return this.getKind().readUnsafeConstant(receiver.asObject(), offset); + return ReadNode.readUnsafeConstant(getKind(), receiver.asObject(), offset); } } @@ -115,7 +114,7 @@ } @Override - public ResolvedJavaType getDeclaringClass() { + public HotSpotResolvedObjectType getDeclaringClass() { return holder; } diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java Fri Nov 30 08:30:22 2012 +0100 @@ -83,7 +83,7 @@ * @return the {@link ResolvedJavaType} corresponding to {@code klassConstant} */ public static ResolvedJavaType fromMetaspaceKlass(Constant metaspaceKlass) { - assert metaspaceKlass.getKind().isLong(); + assert metaspaceKlass.getKind() == Kind.Long; return fromMetaspaceKlass(metaspaceKlass.asLong()); } @@ -222,10 +222,10 @@ HotSpotResolvedObjectType t1 = this; HotSpotResolvedObjectType t2 = (HotSpotResolvedObjectType) otherType; while (true) { - if (t2.isAssignableTo(t1)) { + if (t1.isAssignableFrom(t2)) { return t1; } - if (t1.isAssignableTo(t2)) { + if (t2.isAssignableFrom(t1)) { return t2; } t1 = t1.getSupertype(); @@ -249,9 +249,6 @@ return Constant.forObject(javaMirror); case ObjectHub: return klass(); - case StaticPrimitiveFields: - case StaticObjectFields: - return Constant.forObject(javaMirror); default: assert false : "Should not reach here."; return null; @@ -297,7 +294,7 @@ @Override public boolean isInstance(Constant obj) { - if (obj.getKind().isObject() && !obj.isNull()) { + if (obj.getKind() == Kind.Object && !obj.isNull()) { return javaMirror.isInstance(obj.asObject()); } return false; @@ -314,10 +311,10 @@ } @Override - public boolean isAssignableTo(ResolvedJavaType other) { + public boolean isAssignableFrom(ResolvedJavaType other) { if (other instanceof HotSpotResolvedObjectType) { HotSpotResolvedObjectType otherType = (HotSpotResolvedObjectType) other; - return otherType.javaMirror.isAssignableFrom(javaMirror); + return javaMirror.isAssignableFrom(otherType.javaMirror); } return false; } @@ -438,11 +435,6 @@ } @Override - public boolean isClass(Class c) { - return c == javaMirror; - } - - @Override public T getAnnotation(Class annotationClass) { return javaMirror.getAnnotation(annotationClass); } @@ -456,7 +448,7 @@ * Gets the address of the C++ Klass object for this type. */ public Constant klass() { - return new Constant(HotSpotGraalRuntime.getInstance().getTarget().wordKind, metaspaceKlass, this); + return Constant.forIntegerKind(HotSpotGraalRuntime.getInstance().getTarget().wordKind, metaspaceKlass, this); } public boolean isPrimaryType() { diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedPrimitiveType.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedPrimitiveType.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedPrimitiveType.java Fri Nov 30 08:30:22 2012 +0100 @@ -42,7 +42,7 @@ super(String.valueOf(Character.toUpperCase(kind.getTypeChar()))); this.kind = kind; this.javaMirror = kind.toJavaClass(); - this.javaArrayMirror = kind.isVoid() ? null : Array.newInstance(javaMirror, 0).getClass(); + this.javaArrayMirror = kind == Kind.Void ? null : Array.newInstance(javaMirror, 0).getClass(); } @Override @@ -127,7 +127,7 @@ } @Override - public boolean isAssignableTo(ResolvedJavaType other) { + public boolean isAssignableFrom(ResolvedJavaType other) { return other == this; } @@ -167,11 +167,6 @@ } @Override - public boolean isClass(Class c) { - return c == javaMirror; - } - - @Override public ResolvedJavaType resolve(ResolvedJavaType accessingClass) { return this; } diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Fri Nov 30 08:30:22 2012 +0100 @@ -38,6 +38,8 @@ import java.lang.reflect.*; import java.util.*; +import sun.misc.*; + import com.oracle.graal.api.code.*; import com.oracle.graal.api.code.CodeUtil.RefMapFormatter; import com.oracle.graal.api.code.CompilationResult.Call; @@ -81,15 +83,75 @@ private final Map runtimeCalls = new HashMap<>(); + /** + * The offset from the origin of an array to the first element. + * + * @return the offset in bytes + */ + public static int getArrayBaseOffset(Kind kind) { + switch (kind) { + case Boolean: + return Unsafe.ARRAY_BOOLEAN_BASE_OFFSET; + case Byte: + return Unsafe.ARRAY_BYTE_BASE_OFFSET; + case Char: + return Unsafe.ARRAY_CHAR_BASE_OFFSET; + case Short: + return Unsafe.ARRAY_SHORT_BASE_OFFSET; + case Int: + return Unsafe.ARRAY_INT_BASE_OFFSET; + case Long: + return Unsafe.ARRAY_LONG_BASE_OFFSET; + case Float: + return Unsafe.ARRAY_FLOAT_BASE_OFFSET; + case Double: + return Unsafe.ARRAY_DOUBLE_BASE_OFFSET; + case Object: + return Unsafe.ARRAY_OBJECT_BASE_OFFSET; + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + + /** + * The scale used for the index when accessing elements of an array of this kind. + * + * @return the scale in order to convert the index into a byte offset + */ + public static int getArrayIndexScale(Kind kind) { + switch (kind) { + case Boolean: + return Unsafe.ARRAY_BOOLEAN_INDEX_SCALE; + case Byte: + return Unsafe.ARRAY_BYTE_INDEX_SCALE; + case Char: + return Unsafe.ARRAY_CHAR_INDEX_SCALE; + case Short: + return Unsafe.ARRAY_SHORT_INDEX_SCALE; + case Int: + return Unsafe.ARRAY_INT_INDEX_SCALE; + case Long: + return Unsafe.ARRAY_LONG_INDEX_SCALE; + case Float: + return Unsafe.ARRAY_FLOAT_INDEX_SCALE; + case Double: + return Unsafe.ARRAY_DOUBLE_INDEX_SCALE; + case Object: + return Unsafe.ARRAY_OBJECT_INDEX_SCALE; + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + protected Value ret(Kind kind) { - if (kind.isVoid()) { + if (kind == Kind.Void) { return ILLEGAL; } return globalStubRegConfig.getReturnRegister(kind).asValue(kind); } protected Value arg(int index, Kind kind) { - if (kind.isFloat() || kind.isDouble()) { + if (kind == Kind.Float || kind == Kind.Double) { return globalStubRegConfig.getCallingConventionRegisters(CallingConvention.Type.RuntimeCall, RegisterFlag.FPU)[index].asValue(kind); } return globalStubRegConfig.getCallingConventionRegisters(CallingConvention.Type.RuntimeCall, RegisterFlag.CPU)[index].asValue(kind); @@ -330,7 +392,7 @@ @Override public ResolvedJavaType lookupJavaType(Constant constant) { - if (!constant.getKind().isObject() || constant.isNull()) { + if (constant.getKind() != Kind.Object || constant.isNull()) { return null; } Object o = constant.asObject(); @@ -367,7 +429,7 @@ @Override public int lookupArrayLength(Constant array) { - if (!array.getKind().isObject() || array.isNull() || !array.asObject().getClass().isArray()) { + if (array.getKind() != Kind.Object || array.isNull() || !array.asObject().getClass().isArray()) { throw new IllegalArgumentException(array + " is not an array"); } return Array.getLength(array.asObject()); @@ -423,13 +485,14 @@ callTarget.replaceAndDelete(loweredCallTarget); } } else if (n instanceof LoadFieldNode) { - LoadFieldNode field = (LoadFieldNode) n; - int displacement = ((HotSpotResolvedJavaField) field.field()).offset(); - assert field.kind() != Kind.Illegal; - ReadNode memoryRead = graph.add(new ReadNode(field.object(), LocationNode.create(field.field(), field.field().getKind(), displacement, graph), field.stamp())); - memoryRead.dependencies().add(tool.createNullCheckGuard(field.object(), field.leafGraphId())); - graph.replaceFixedWithFixed(field, memoryRead); - if (field.isVolatile()) { + LoadFieldNode loadField = (LoadFieldNode) n; + HotSpotResolvedJavaField field = (HotSpotResolvedJavaField) loadField.field(); + ValueNode object = loadField.isStatic() ? ConstantNode.forObject(field.getDeclaringClass().mirror(), this, graph) : loadField.object(); + assert loadField.kind() != Kind.Illegal; + ReadNode memoryRead = graph.add(new ReadNode(object, LocationNode.create(field, field.getKind(), field.offset(), graph), loadField.stamp())); + memoryRead.dependencies().add(tool.createNullCheckGuard(object, loadField.leafGraphId())); + graph.replaceFixedWithFixed(loadField, memoryRead); + if (loadField.isVolatile()) { MembarNode preMembar = graph.add(new MembarNode(JMM_PRE_VOLATILE_READ)); graph.addBeforeFixed(memoryRead, preMembar); MembarNode postMembar = graph.add(new MembarNode(JMM_POST_VOLATILE_READ)); @@ -438,8 +501,9 @@ } else if (n instanceof StoreFieldNode) { StoreFieldNode storeField = (StoreFieldNode) n; HotSpotResolvedJavaField field = (HotSpotResolvedJavaField) storeField.field(); - WriteNode memoryWrite = graph.add(new WriteNode(storeField.object(), storeField.value(), LocationNode.create(field, field.getKind(), field.offset(), graph))); - memoryWrite.dependencies().add(tool.createNullCheckGuard(storeField.object(), storeField.leafGraphId())); + ValueNode object = storeField.isStatic() ? ConstantNode.forObject(field.getDeclaringClass().mirror(), this, graph) : storeField.object(); + WriteNode memoryWrite = graph.add(new WriteNode(object, storeField.value(), LocationNode.create(field, field.getKind(), field.offset(), graph))); + memoryWrite.dependencies().add(tool.createNullCheckGuard(object, storeField.leafGraphId())); memoryWrite.setStateAfter(storeField.stateAfter()); graph.replaceFixedWithFixed(storeField, memoryWrite); FixedWithNextNode last = memoryWrite; @@ -460,7 +524,7 @@ ValueNode expected = cas.expected(); if (expected.kind() == Kind.Object && !cas.newValue().objectStamp().alwaysNull()) { ResolvedJavaType type = cas.object().objectStamp().type(); - if (type != null && !type.isArray() && !type.isClass(Object.class)) { + if (type != null && !type.isArray() && !MetaUtil.isJavaLangObject(type)) { // Use a field write barrier since it's not an array store FieldWriteBarrier writeBarrier = graph.add(new FieldWriteBarrier(cas.object())); graph.addAfterFixed(cas, writeBarrier); @@ -491,7 +555,7 @@ ResolvedJavaType arrayType = array.objectStamp().type(); if (arrayType != null && array.objectStamp().isExactType()) { ResolvedJavaType elementType = arrayType.getComponentType(); - if (!elementType.isClass(Object.class)) { + if (!MetaUtil.isJavaLangObject(elementType)) { CheckCastNode checkcast = graph.add(new CheckCastNode(elementType, value, null)); graph.addBeforeFixed(storeIndexed, checkcast); value = checkcast; @@ -533,7 +597,7 @@ if (write.value().kind() == Kind.Object && !write.value().objectStamp().alwaysNull()) { ResolvedJavaType type = object.objectStamp().type(); WriteBarrier writeBarrier; - if (type != null && !type.isArray() && !type.isClass(Object.class)) { + if (type != null && !type.isArray() && !MetaUtil.isJavaLangObject(type)) { // Use a field write barrier since it's not an array store writeBarrier = graph.add(new FieldWriteBarrier(object)); } else { @@ -581,7 +645,7 @@ } private static IndexedLocationNode createArrayLocation(Graph graph, Kind elementKind, ValueNode index) { - return IndexedLocationNode.create(LocationNode.getArrayLocation(elementKind), elementKind, elementKind.getArrayBaseOffset(), index, graph, true); + return IndexedLocationNode.create(LocationNode.getArrayLocation(elementKind), elementKind, getArrayBaseOffset(elementKind), index, graph, true); } private SafeReadNode safeReadArrayLength(ValueNode array, long leafGraphId) { @@ -602,7 +666,7 @@ ResolvedJavaType holder = method.getDeclaringClass(); String fullName = method.getName() + ((HotSpotSignature) method.getSignature()).asString(); Kind wordKind = graalRuntime.getTarget().wordKind; - if (holder.isClass(Object.class)) { + if (MetaUtil.isJavaLangObject(holder)) { if (fullName.equals("getClass()Ljava/lang/Class;")) { ValueNode obj = (ValueNode) parameters.get(0); ObjectStamp stamp = (ObjectStamp) obj.stamp(); @@ -624,7 +688,7 @@ hub.setNext(ret); return graph; } - } else if (holder.isClass(Class.class)) { + } else if (holder.equals(lookupJavaType(Class.class))) { if (fullName.equals("getModifiers()I")) { StructuredGraph graph = new StructuredGraph(); LocalNode receiver = graph.unique(new LocalNode(0, StampFactory.objectNonNull())); @@ -639,7 +703,7 @@ klass.setNext(ret); return graph; } - } else if (holder.isClass(Thread.class)) { + } else if (holder.equals(lookupJavaType(Thread.class))) { if (fullName.equals("currentThread()Ljava/lang/Thread;")) { StructuredGraph graph = new StructuredGraph(); ReturnNode ret = graph.add(new ReturnNode(graph.unique(new CurrentThread(config.threadObjectOffset, this)))); diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/BeginLockScopeNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/BeginLockScopeNode.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/BeginLockScopeNode.java Fri Nov 30 08:30:22 2012 +0100 @@ -56,10 +56,11 @@ public void generate(LIRGenerator gen) { gen.lock(); StackSlot lockData = gen.peekLock(); - Value result = eliminated ? new Constant(gen.target().wordKind, 0L) : gen.emitLea(lockData); - FrameState stateAfter = stateAfter(); - assert stateAfter != null; - gen.setResult(this, result); + assert stateAfter() != null; + if (!eliminated) { + Value result = gen.emitLea(lockData); + gen.setResult(this, result); + } } @NodeIntrinsic diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/HotSpotSnippetUtils.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/HotSpotSnippetUtils.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/HotSpotSnippetUtils.java Fri Nov 30 08:30:22 2012 +0100 @@ -27,6 +27,7 @@ import com.oracle.graal.graph.Node.ConstantNodeParameter; import com.oracle.graal.graph.Node.NodeIntrinsic; import com.oracle.graal.hotspot.*; +import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.nodes.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.snippets.Snippet.Fold; @@ -154,12 +155,12 @@ @Fold static int arrayBaseOffset(Kind elementKind) { - return elementKind.getArrayBaseOffset(); + return HotSpotRuntime.getArrayBaseOffset(elementKind); } @Fold static int arrayIndexScale(Kind elementKind) { - return elementKind.getArrayIndexScale(); + return HotSpotRuntime.getArrayIndexScale(elementKind); } @Fold diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/IntrinsifyArrayCopyPhase.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/IntrinsifyArrayCopyPhase.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/IntrinsifyArrayCopyPhase.java Fri Nov 30 08:30:22 2012 +0100 @@ -108,7 +108,7 @@ snippetMethod = objectArrayCopy; } } else if (componentKind == Kind.Object - && srcType.getComponentType().isAssignableTo(destType.getComponentType())) { + && destType.getComponentType().isAssignableFrom(srcType.getComponentType())) { snippetMethod = objectArrayCopy; } } diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/NewObjectSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/NewObjectSnippets.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/NewObjectSnippets.java Fri Nov 30 08:30:22 2012 +0100 @@ -273,7 +273,7 @@ ValueNode memory; if (!useTLAB) { - memory = ConstantNode.forConstant(new Constant(target.wordKind, 0L), runtime, graph); + memory = ConstantNode.defaultForKind(target.wordKind, graph); } else { ConstantNode sizeNode = ConstantNode.forInt(size, graph); TLABAllocateNode tlabAllocateNode = graph.add(new TLABAllocateNode(sizeNode)); @@ -296,11 +296,11 @@ ResolvedJavaType arrayType = elementType.getArrayClass(); Kind elementKind = elementType.getKind(); final int alignment = target.wordSize; - final int headerSize = elementKind.getArrayBaseOffset(); + final int headerSize = HotSpotRuntime.getArrayBaseOffset(elementKind); final Integer length = lengthNode.isConstant() ? Integer.valueOf(lengthNode.asConstant().asInt()) : null; int log2ElementSize = CodeUtil.log2(target.sizeInBytes(elementKind)); if (!useTLAB) { - ConstantNode zero = ConstantNode.forConstant(new Constant(target.wordKind, 0L), runtime, graph); + ConstantNode zero = ConstantNode.defaultForKind(target.wordKind, graph); // value for 'size' doesn't matter as it isn't used since a stub call will be made anyway // for both allocation and initialization - it just needs to be non-null ConstantNode size = ConstantNode.forInt(-1, graph); @@ -363,8 +363,8 @@ assert elementType != null; ConstantNode hub = ConstantNode.forConstant(type.klass(), runtime, graph); Kind elementKind = elementType.getKind(); - final int headerSize = elementKind.getArrayBaseOffset(); - Key key = new Key(elementKind.isObject() ? initializeObjectArray : initializePrimitiveArray).add("headerSize", headerSize).add("fillContents", initializeNode.fillContents()).add("locked", initializeNode.locked()); + final int headerSize = HotSpotRuntime.getArrayBaseOffset(elementKind); + Key key = new Key(elementKind == Kind.Object ? initializeObjectArray : initializePrimitiveArray).add("headerSize", headerSize).add("fillContents", initializeNode.fillContents()).add("locked", initializeNode.locked()); ValueNode memory = initializeNode.memory(); Arguments arguments = arguments("memory", memory).add("hub", hub).add("prototypeMarkWord", type.prototypeMarkWord()).add("size", initializeNode.size()).add("length", initializeNode.length()); SnippetTemplate template = cache.get(key, assumptions); diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java Fri Nov 30 08:30:22 2012 +0100 @@ -762,7 +762,7 @@ while (stream.currentBCI() <= block.endBci) { switch (stream.currentBC()) { case RETURN: - if (method.isConstructor() && method.getDeclaringClass().isClass(Object.class)) { + if (method.isConstructor() && MetaUtil.isJavaLangObject(method.getDeclaringClass())) { // return from Object.init implicitly registers a finalizer // for the receiver if needed, so keep it alive. loadOne(block, 0); diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Fri Nov 30 08:30:22 2012 +0100 @@ -536,7 +536,7 @@ ValueNode b = mirror ? x : y; CompareNode condition; - assert !a.kind().isFloatOrDouble(); + assert a.kind() != Kind.Double && a.kind() != Kind.Float; if (cond == Condition.EQ || cond == Condition.NE) { if (a.kind() == Kind.Object) { condition = new ObjectEqualsNode(a, b); @@ -832,37 +832,28 @@ } private void genGetStatic(JavaField field) { - JavaType holder = field.getDeclaringClass(); - boolean isInitialized = (field instanceof ResolvedJavaField) && ((ResolvedJavaType) holder).isInitialized(); - Constant constantValue = null; - if (isInitialized) { - constantValue = ((ResolvedJavaField) field).readConstantValue(null); - } - if (constantValue != null) { - frameState.push(constantValue.getKind().getStackKind(), appendConstant(constantValue)); + Kind kind = field.getKind(); + if (field instanceof ResolvedJavaField && ((ResolvedJavaType) field.getDeclaringClass()).isInitialized()) { + Constant constantValue = ((ResolvedJavaField) field).readConstantValue(null); + if (constantValue != null) { + frameState.push(constantValue.getKind().getStackKind(), appendConstant(constantValue)); + } else { + LoadFieldNode load = currentGraph.add(new LoadFieldNode(null, (ResolvedJavaField) field, graphId)); + appendOptimizedLoadField(kind, load); + } } else { - ValueNode container = genTypeOrDeopt(field.getKind() == Kind.Object ? Representation.StaticObjectFields : Representation.StaticPrimitiveFields, holder, isInitialized); - Kind kind = field.getKind(); - if (container != null) { - LoadFieldNode load = currentGraph.add(new LoadFieldNode(container, (ResolvedJavaField) field, graphId)); - appendOptimizedLoadField(kind, load); - } else { - // deopt will be generated by genTypeOrDeopt, not needed here - frameState.push(kind.getStackKind(), append(ConstantNode.defaultForKind(kind, currentGraph))); - } + append(currentGraph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.Unresolved, graphId))); + frameState.push(kind.getStackKind(), append(ConstantNode.defaultForKind(kind, currentGraph))); } } private void genPutStatic(JavaField field) { - JavaType holder = field.getDeclaringClass(); - boolean isInitialized = (field instanceof ResolvedJavaField) && ((ResolvedJavaType) holder).isInitialized(); - ValueNode container = genTypeOrDeopt(field.getKind() == Kind.Object ? Representation.StaticObjectFields : Representation.StaticPrimitiveFields, holder, isInitialized); ValueNode value = frameState.pop(field.getKind().getStackKind()); - if (container != null) { - StoreFieldNode store = currentGraph.add(new StoreFieldNode(container, (ResolvedJavaField) field, value, graphId)); + if (field instanceof ResolvedJavaField && ((ResolvedJavaType) field.getDeclaringClass()).isInitialized()) { + StoreFieldNode store = currentGraph.add(new StoreFieldNode(null, (ResolvedJavaField) field, value, graphId)); appendOptimizedStoreField(store); } else { - // deopt will be generated by genTypeOrDeopt, not needed here + append(currentGraph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.Unresolved, graphId))); } } @@ -1396,7 +1387,7 @@ } private void createReturn() { - if (method.isConstructor() && method.getDeclaringClass().isClass(Object.class)) { + if (method.isConstructor() && MetaUtil.isJavaLangObject(method.getDeclaringClass())) { callRegisterFinalizer(); } Kind returnKind = method.getSignature().getReturnKind().getStackKind(); @@ -1442,7 +1433,7 @@ if (initialized && graphBuilderConfig.getSkippedExceptionTypes() != null) { ResolvedJavaType resolvedCatchType = (ResolvedJavaType) catchType; for (ResolvedJavaType skippedType : graphBuilderConfig.getSkippedExceptionTypes()) { - initialized &= !resolvedCatchType.isAssignableTo(skippedType); + initialized &= !skippedType.isAssignableFrom(resolvedCatchType); if (!initialized) { break; } diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopTransformations.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopTransformations.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopTransformations.java Fri Nov 30 08:30:22 2012 +0100 @@ -44,10 +44,6 @@ return null; } @Override - public boolean isImmutable(Constant objectConstant) { - return false; - } - @Override public Assumptions assumptions() { return null; } @@ -85,7 +81,7 @@ while (!loopBegin.isDeleted()) { int mark = graph.getMark(); peel(loop); - new CanonicalizerPhase(null, runtime, assumptions, mark, null).apply(graph); + new CanonicalizerPhase(null, runtime, assumptions, mark).apply(graph); if (iterations++ > UNROLL_LIMIT || graph.getNodeCount() > GraalOptions.MaximumDesiredSize * 3) { throw new BailoutException("FullUnroll : Graph seems to grow out of proportion"); } diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java Fri Nov 30 08:30:22 2012 +0100 @@ -224,7 +224,7 @@ @Override public Map getDebugProperties(Map map) { Map properties = super.getDebugProperties(map); - properties.put("rawvalue", value.getKind().isObject() ? value.getKind().format(value.asBoxedValue()) : value.asBoxedValue()); + properties.put("rawvalue", value.getKind() == Kind.Object ? value.getKind().format(value.asBoxedValue()) : value.asBoxedValue()); return properties; } diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java Fri Nov 30 08:30:22 2012 +0100 @@ -232,7 +232,7 @@ copy.remove(copy.size() - 1); } ValueNode lastSlot = copy.get(copy.size() - 1); - assert lastSlot.kind().getStackKind() == popKind.getStackKind() || (lastSlot instanceof BoxedVirtualObjectNode && popKind.isObject()); + assert lastSlot.kind().getStackKind() == popKind.getStackKind() || (lastSlot instanceof BoxedVirtualObjectNode && popKind == Kind.Object); copy.remove(copy.size() - 1); } Collections.addAll(copy, pushedValues); diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java Fri Nov 30 08:30:22 2012 +0100 @@ -141,7 +141,7 @@ @Override public void intrinsify(Node node) { - assert !(node instanceof ValueNode) || ((ValueNode) node).kind().isVoid() == kind().isVoid(); + assert !(node instanceof ValueNode) || (((ValueNode) node).kind() == Kind.Void) == (kind() == Kind.Void); CallTargetNode call = callTarget; FrameState stateAfter = stateAfter(); if (node instanceof StateSplit) { diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java Fri Nov 30 08:30:22 2012 +0100 @@ -177,7 +177,7 @@ @Override public void intrinsify(Node node) { - assert !(node instanceof ValueNode) || ((ValueNode) node).kind().isVoid() == kind().isVoid(); + assert !(node instanceof ValueNode) || (((ValueNode) node).kind() == Kind.Void) == (kind() == Kind.Void); CallTargetNode call = callTarget; FrameState state = stateAfter(); killExceptionEdge(); diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java Fri Nov 30 08:30:22 2012 +0100 @@ -131,22 +131,22 @@ public static CompareNode createCompareNode(Condition condition, ValueNode x, ValueNode y) { assert x.kind() == y.kind(); assert condition.isCanonical() : "condition is not canonical: " + condition; + assert x.kind() != Kind.Double && x.kind() != Kind.Float; - assert !x.kind().isFloatOrDouble(); CompareNode comparison; if (condition == Condition.EQ) { - if (x.kind().isObject()) { + if (x.kind() == Kind.Object) { comparison = new ObjectEqualsNode(x, y); } else { - assert x.kind().getStackKind().isStackInt() || x.kind().isLong(); + assert x.kind().getStackKind() == Kind.Int || x.kind() == Kind.Long; comparison = new IntegerEqualsNode(x, y); } } else if (condition == Condition.LT) { - assert x.kind().getStackKind().isStackInt() || x.kind().isLong(); + assert x.kind().getStackKind() == Kind.Int || x.kind() == Kind.Long; comparison = new IntegerLessThanNode(x, y); } else { assert condition == Condition.BT; - assert x.kind().getStackKind().isStackInt() || x.kind().isLong(); + assert x.kind().getStackKind() == Kind.Int || x.kind() == Kind.Long; comparison = new IntegerBelowThanNode(x, y); } diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/Condition.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/Condition.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/Condition.java Fri Nov 30 08:30:22 2012 +0100 @@ -247,7 +247,7 @@ * {@link Boolean#FALSE} if the comparison is known to be false */ public boolean foldCondition(Constant lt, Constant rt, CodeCacheProvider runtime) { - assert !lt.getKind().isFloatOrDouble() && !rt.getKind().isFloatOrDouble(); + assert lt.getKind() != Kind.Double && lt.getKind() != Kind.Float && rt.getKind() != Kind.Double && rt.getKind() != Kind.Float; return foldCondition(lt, rt, runtime, false); } diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatEqualsNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatEqualsNode.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatEqualsNode.java Fri Nov 30 08:30:22 2012 +0100 @@ -22,6 +22,7 @@ */ package com.oracle.graal.nodes.calc; +import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; @@ -36,8 +37,8 @@ */ public FloatEqualsNode(ValueNode x, ValueNode y) { super(x, y); - assert x.kind().isFloatOrDouble(); - assert y.kind().isFloatOrDouble(); + assert x.kind() == Kind.Double || x.kind() == Kind.Float; + assert y.kind() == Kind.Double || y.kind() == Kind.Float; } @Override diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatLessThanNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatLessThanNode.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatLessThanNode.java Fri Nov 30 08:30:22 2012 +0100 @@ -22,6 +22,7 @@ */ package com.oracle.graal.nodes.calc; +import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; @@ -40,8 +41,8 @@ */ public FloatLessThanNode(ValueNode x, ValueNode y, boolean unorderedIsTrue) { super(x, y); - assert x.kind().isFloatOrDouble(); - assert y.kind().isFloatOrDouble(); + assert x.kind() == Kind.Double || x.kind() == Kind.Float; + assert y.kind() == Kind.Double || y.kind() == Kind.Float; this.unorderedIsTrue = unorderedIsTrue; } diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerAddNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerAddNode.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerAddNode.java Fri Nov 30 08:30:22 2012 +0100 @@ -79,13 +79,13 @@ public static boolean isIntegerAddition(ValueNode result, ValueNode a, ValueNode b) { Kind kind = result.kind(); - if (kind != a.kind() || kind != b.kind() || !(kind.isStackInt() || kind.isLong())) { + if (kind != a.kind() || kind != b.kind() || !(kind.getStackKind() == Kind.Int || kind == Kind.Long)) { return false; } if (result.isConstant() && a.isConstant() && b.isConstant()) { - if (kind.isStackInt()) { + if (kind.getStackKind() == Kind.Int) { return result.asConstant().asInt() == a.asConstant().asInt() + b.asConstant().asInt(); - } else if (kind.isLong()) { + } else if (kind == Kind.Long) { return result.asConstant().asLong() == a.asConstant().asLong() + b.asConstant().asLong(); } } else if (result instanceof IntegerAddNode) { diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerBelowThanNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerBelowThanNode.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerBelowThanNode.java Fri Nov 30 08:30:22 2012 +0100 @@ -39,8 +39,8 @@ */ public IntegerBelowThanNode(ValueNode x, ValueNode y) { super(x, y); - assert !x.kind().isFloatOrDouble() && x.kind() != Kind.Object; - assert !y.kind().isFloatOrDouble() && y.kind() != Kind.Object; + assert x.kind() != Kind.Double && x.kind() != Kind.Float && x.kind() != Kind.Object; + assert y.kind() != Kind.Double && y.kind() != Kind.Float && y.kind() != Kind.Object; } @Override diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerDivNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerDivNode.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerDivNode.java Fri Nov 30 08:30:22 2012 +0100 @@ -70,10 +70,10 @@ // no rounding if dividend is positive or if its low bits are always 0 if (stampX.canBeNegative() || (stampX.mask() & (abs - 1)) != 0) { int bits; - if (kind().isStackInt()) { + if (kind().getStackKind() == Kind.Int) { bits = 32; } else { - assert kind().isLong(); + assert kind() == Kind.Long; bits = 64; } RightShiftNode sign = graph().unique(new RightShiftNode(kind(), x(), ConstantNode.forInt(bits - 1, graph()))); diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerEqualsNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerEqualsNode.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerEqualsNode.java Fri Nov 30 08:30:22 2012 +0100 @@ -38,8 +38,8 @@ */ public IntegerEqualsNode(ValueNode x, ValueNode y) { super(x, y); - assert !x.kind().isFloatOrDouble() && x.kind() != Kind.Object; - assert !y.kind().isFloatOrDouble() && y.kind() != Kind.Object; + assert x.kind() != Kind.Double && x.kind() != Kind.Float && x.kind() != Kind.Object; + assert y.kind() != Kind.Double && y.kind() != Kind.Float && y.kind() != Kind.Object; } @Override @@ -58,7 +58,7 @@ ValueNode a = mirrored ? normalizeNode.y() : normalizeNode.x(); ValueNode b = mirrored ? normalizeNode.x() : normalizeNode.y(); - if (normalizeNode.x().kind().isFloatOrDouble()) { + if (normalizeNode.x().kind() == Kind.Double || normalizeNode.x().kind() == Kind.Float) { return graph().unique(new FloatEqualsNode(a, b)); } else { return graph().unique(new IntegerEqualsNode(a, b)); diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerLessThanNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerLessThanNode.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerLessThanNode.java Fri Nov 30 08:30:22 2012 +0100 @@ -39,8 +39,8 @@ */ public IntegerLessThanNode(ValueNode x, ValueNode y) { super(x, y); - assert !x.kind().isFloatOrDouble() && x.kind() != Kind.Object; - assert !y.kind().isFloatOrDouble() && y.kind() != Kind.Object; + assert x.kind() != Kind.Double && x.kind() != Kind.Float && x.kind() != Kind.Object; + assert y.kind() != Kind.Double && y.kind() != Kind.Float && y.kind() != Kind.Object; } @Override @@ -60,7 +60,7 @@ ValueNode a = mirrored ? normalizeNode.y() : normalizeNode.x(); ValueNode b = mirrored ? normalizeNode.x() : normalizeNode.y(); - if (normalizeNode.x().kind().isFloatOrDouble()) { + if (normalizeNode.x().kind() == Kind.Double || normalizeNode.x().kind() == Kind.Float) { return graph().unique(new FloatLessThanNode(a, b, mirrored ^ normalizeNode.isUnorderedLess)); } else { return graph().unique(new IntegerLessThanNode(a, b)); diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IsNullNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IsNullNode.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IsNullNode.java Fri Nov 30 08:30:22 2012 +0100 @@ -57,7 +57,7 @@ @Override public boolean verify() { assertTrue(object() != null, "is null input must not be null"); - assertTrue(object().kind().isObject(), "is null input must be an object"); + assertTrue(object().kind() == Kind.Object, "is null input must be an object"); return super.verify(); } diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NormalizeCompareNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NormalizeCompareNode.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NormalizeCompareNode.java Fri Nov 30 08:30:22 2012 +0100 @@ -50,7 +50,7 @@ BooleanNode equalComp; BooleanNode lessComp; - if (x().kind().isFloatOrDouble()) { + if (x().kind() == Kind.Double || x().kind() == Kind.Float) { equalComp = graph.unique(new FloatEqualsNode(x(), y())); lessComp = graph.unique(new FloatLessThanNode(x(), y(), isUnorderedLess)); } else { diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxingMethodPool.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxingMethodPool.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxingMethodPool.java Fri Nov 30 08:30:22 2012 +0100 @@ -22,32 +22,11 @@ */ package com.oracle.graal.nodes.extended; -import java.lang.reflect.*; import java.util.*; -import java.util.Map.Entry; import com.oracle.graal.api.meta.*; public class BoxingMethodPool { - private static final Map boxings = new HashMap<>(); - private static class BoxingMethod { - final Class type; - final String unboxMethod; - public BoxingMethod(Class< ? > type, String unboxMethod) { - this.type = type; - this.unboxMethod = unboxMethod; - } - } - static { - boxings.put(Kind.Boolean, new BoxingMethod(Boolean.class, "booleanValue")); - boxings.put(Kind.Byte, new BoxingMethod(Byte.class, "byteValue")); - boxings.put(Kind.Char, new BoxingMethod(Character.class, "charValue")); - boxings.put(Kind.Short, new BoxingMethod(Short.class, "shortValue")); - boxings.put(Kind.Int, new BoxingMethod(Integer.class, "intValue")); - boxings.put(Kind.Long, new BoxingMethod(Long.class, "longValue")); - boxings.put(Kind.Float, new BoxingMethod(Float.class, "floatValue")); - boxings.put(Kind.Double, new BoxingMethod(Double.class, "doubleValue")); - } private final Set specialMethods = new HashSet<>(); private final MetaAccessProvider runtime; @@ -57,25 +36,22 @@ public BoxingMethodPool(MetaAccessProvider runtime) { this.runtime = runtime; - initialize(); - } - private void initialize() { try { - for (Entry entry : boxings.entrySet()) { - Kind kind = entry.getKey(); - BoxingMethod boxing = entry.getValue(); - initialize(kind, boxing.type, boxing.unboxMethod); - } - } catch (SecurityException e) { - throw new RuntimeException(e); - } catch (NoSuchMethodException e) { + initialize(Kind.Boolean, Boolean.class, "booleanValue"); + initialize(Kind.Byte, Byte.class, "byteValue"); + initialize(Kind.Char, Character.class, "charValue"); + initialize(Kind.Short, Short.class, "shortValue"); + initialize(Kind.Int, Integer.class, "intValue"); + initialize(Kind.Long, Long.class, "longValue"); + initialize(Kind.Float, Float.class, "floatValue"); + initialize(Kind.Double, Double.class, "doubleValue"); + } catch (SecurityException | NoSuchMethodException e) { throw new RuntimeException(e); } } private void initialize(Kind kind, Class type, String unboxMethod) throws SecurityException, NoSuchMethodException { - // Get boxing method from runtime. ResolvedJavaMethod boxingMethod = runtime.lookupJavaMethod(type.getDeclaredMethod("valueOf", kind.toJavaClass())); specialMethods.add(boxingMethod); @@ -116,38 +92,4 @@ public ResolvedJavaField getBoxField(Kind kind) { return boxFields[kind.ordinal()]; } - - public static boolean isSpecialMethodStatic(ResolvedJavaMethod method) { - return isUnboxingMethodStatic(method) || isBoxingMethodStatic(method); - } - - public static boolean isBoxingMethodStatic(ResolvedJavaMethod method) { - Signature signature = method.getSignature(); - if (!Modifier.isStatic(method.getModifiers()) - || signature.getReturnKind() == Kind.Object - || signature.getParameterCount(false) != 1) { - return false; - } - Kind kind = signature.getParameterKind(0); - BoxingMethod boxing = boxings.get(kind); - if (boxing == null) { - return false; - } - return method.getDeclaringClass().isClass(boxing.type) && method.getName().equals("valueOf"); - } - - public static boolean isUnboxingMethodStatic(ResolvedJavaMethod method) { - Signature signature = method.getSignature(); - if (signature.getReturnKind() == Kind.Object - || signature.getParameterCount(false) != 0 - || Modifier.isStatic(method.getModifiers())) { - return false; - } - Kind kind = signature.getReturnKind(); - BoxingMethod boxing = boxings.get(kind); - if (boxing == null) { - return false; - } - return method.getDeclaringClass().isClass(boxing.type) && method.getName().equals(boxing.unboxMethod); - } } diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Fri Nov 30 08:30:22 2012 +0100 @@ -22,6 +22,7 @@ */ package com.oracle.graal.nodes.extended; +import static com.oracle.graal.graph.FieldIntrospection.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; @@ -47,6 +48,39 @@ return canonicalizeRead(this, tool); } + /** + * Utility function for reading a value of this kind using an object and a displacement. + * + * @param object the object from which the value is read + * @param displacement the displacement within the object in bytes + * @return the read value encapsulated in a {@link Constant} object + */ + public static Constant readUnsafeConstant(Kind kind, Object object, long displacement) { + assert object != null; + switch (kind) { + case Boolean: + return Constant.forBoolean(unsafe.getBoolean(object, displacement)); + case Byte: + return Constant.forByte(unsafe.getByte(object, displacement)); + case Char: + return Constant.forChar(unsafe.getChar(object, displacement)); + case Short: + return Constant.forShort(unsafe.getShort(object, displacement)); + case Int: + return Constant.forInt(unsafe.getInt(object, displacement)); + case Long: + return Constant.forLong(unsafe.getLong(object, displacement)); + case Float: + return Constant.forFloat(unsafe.getFloat(object, displacement)); + case Double: + return Constant.forDouble(unsafe.getDouble(object, displacement)); + case Object: + return Constant.forObject(unsafe.getObject(object, displacement)); + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + public static ValueNode canonicalizeRead(Access read, CanonicalizerTool tool) { MetaAccessProvider runtime = tool.runtime(); if (runtime != null && read.object() != null && read.object().isConstant() && read.object().kind() == Kind.Object) { @@ -55,10 +89,8 @@ if (value != null) { long displacement = read.location().displacement(); Kind kind = read.location().getValueKind(); - Constant constant = kind.readUnsafeConstant(value, displacement); - if (constant != null) { - return ConstantNode.forConstant(constant, runtime, read.node().graph()); - } + Constant constant = readUnsafeConstant(kind, value, displacement); + return ConstantNode.forConstant(constant, runtime, read.node().graph()); } } } diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java Fri Nov 30 08:30:22 2012 +0100 @@ -46,7 +46,7 @@ } public UnsafeCastNode(ValueNode object, ResolvedJavaType toType, boolean exactType, boolean nonNull) { - this(object, toType.getKind().isObject() ? StampFactory.object(toType, exactType, nonNull || object.stamp().nonNull()) : StampFactory.forKind(toType.getKind())); + this(object, toType.getKind() == Kind.Object ? StampFactory.object(toType, exactType, nonNull || object.stamp().nonNull()) : StampFactory.forKind(toType.getKind())); } @Override @@ -68,7 +68,7 @@ if (my.nonNull() && !other.nonNull()) { return this; } - if (my.type() != other.type() && my.type().isAssignableTo(other.type())) { + if (my.type() != other.type() && other.type().isAssignableFrom(my.type())) { return this; } } diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessFieldNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessFieldNode.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessFieldNode.java Fri Nov 30 08:30:22 2012 +0100 @@ -100,7 +100,7 @@ @Override public boolean verify() { - assertTrue(object != null, "Access object can not be null"); + assertTrue((object == null) == isStatic(), "static field must not have object, instance field must have object"); return super.verify(); } } diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java Fri Nov 30 08:30:22 2012 +0100 @@ -72,7 +72,7 @@ if (type != null) { ResolvedJavaType objectType = object().objectStamp().type(); - if (objectType != null && objectType.isAssignableTo(type)) { + if (objectType != null && type.isAssignableFrom(objectType)) { // we don't have to check for null types here because they will also pass the checkcast. return object(); } @@ -102,7 +102,7 @@ @Override public void virtualize(VirtualizerTool tool) { VirtualObjectNode virtual = tool.getVirtualState(object()); - if (virtual != null && virtual.type().isAssignableTo(type())) { + if (virtual != null && type().isAssignableFrom(virtual.type())) { tool.replaceWithVirtual(virtual); } } diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java Fri Nov 30 08:30:22 2012 +0100 @@ -70,7 +70,7 @@ ResolvedJavaType stampType = stamp.type(); if (stamp.isExactType()) { - boolean subType = stampType.isAssignableTo(type()); + boolean subType = type().isAssignableFrom(stampType); if (subType) { if (stamp.nonNull()) { @@ -87,7 +87,7 @@ return ConstantNode.forBoolean(false, graph()); } } else if (stampType != null) { - boolean subType = stampType.isAssignableTo(type()); + boolean subType = type().isAssignableFrom(stampType); if (subType) { if (stamp.nonNull()) { @@ -135,7 +135,7 @@ public void virtualize(VirtualizerTool tool) { VirtualObjectNode virtual = tool.getVirtualState(object()); if (virtual != null) { - tool.replaceWithValue(ConstantNode.forBoolean(virtual.type().isAssignableTo(type()), graph())); + tool.replaceWithValue(ConstantNode.forBoolean(type().isAssignableFrom(virtual.type()), graph())); } } } diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java Fri Nov 30 08:30:22 2012 +0100 @@ -22,8 +22,6 @@ */ package com.oracle.graal.nodes.java; -import java.lang.reflect.*; - import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; @@ -34,7 +32,7 @@ /** * The {@code LoadIndexedNode} represents a read from an element of an array. */ -public final class LoadIndexedNode extends AccessIndexedNode implements Canonicalizable, Node.IterableNodeType, Virtualizable { +public final class LoadIndexedNode extends AccessIndexedNode implements Node.IterableNodeType, Virtualizable { /** * Creates a new LoadIndexedNode. @@ -55,24 +53,6 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { - MetaAccessProvider runtime = tool.runtime(); - if (runtime != null && index().isConstant() && array().isConstant() && !array().isNullConstant()) { - Constant arrayConst = array().asConstant(); - if (tool.isImmutable(arrayConst)) { - int index = index().asConstant().asInt(); - Object array = arrayConst.asObject(); - int length = Array.getLength(array); - if (index >= 0 && index < length) { - return ConstantNode.forConstant(elementKind().readUnsafeConstant(array, - elementKind().getArrayBaseOffset() + index * elementKind().getArrayIndexScale()), runtime, graph()); - } - } - } - return this; - } - - @Override public void virtualize(VirtualizerTool tool) { VirtualObjectNode virtualArray = tool.getVirtualState(array()); if (virtualArray != null) { diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/TypeSwitchNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/TypeSwitchNode.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/TypeSwitchNode.java Fri Nov 30 08:30:22 2012 +0100 @@ -98,7 +98,7 @@ if (stamp.type() != null) { int validKeys = 0; for (int i = 0; i < keyCount(); i++) { - if (keys[i].isAssignableTo(stamp.type())) { + if (stamp.type().isAssignableFrom(keys[i])) { validKeys++; } } @@ -113,7 +113,7 @@ double totalProbability = 0; int current = 0; for (int i = 0; i < keyCount() + 1; i++) { - if (i == keyCount() || keys[i].isAssignableTo(stamp.type())) { + if (i == keyCount() || stamp.type().isAssignableFrom(keys[i])) { int index = newSuccessors.indexOf(keySuccessor(i)); if (index == -1) { index = newSuccessors.size(); diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/CanonicalizerTool.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/CanonicalizerTool.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/CanonicalizerTool.java Fri Nov 30 08:30:22 2012 +0100 @@ -30,10 +30,4 @@ TargetDescription target(); Assumptions assumptions(); MetaAccessProvider runtime(); - - /** - * Determines if a given constant is an object/array whose current - * fields/elements will never change. - */ - boolean isImmutable(Constant objectConstant); } diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/ObjectStamp.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/ObjectStamp.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/ObjectStamp.java Fri Nov 30 08:30:22 2012 +0100 @@ -78,7 +78,7 @@ return false; } else if (other.nonNull || nonNull) { // One of the two values cannot be null. - return !other.type.isInterface() && !type.isInterface() && !other.type.isAssignableTo(type) && !type.isAssignableTo(other.type); + return !other.type.isInterface() && !type.isInterface() && !type.isAssignableFrom(other.type) && !other.type.isAssignableFrom(type); } return false; } @@ -139,7 +139,7 @@ joinType = type; } else { // both types are != null - if (other.type.isAssignableTo(type)) { + if (type.isAssignableFrom(other.type)) { joinType = other.type; } else { joinType = type; diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampFactory.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampFactory.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampFactory.java Fri Nov 30 08:30:22 2012 +0100 @@ -137,7 +137,9 @@ } else { if (value.getKind() == Kind.Int || value.getKind() == Kind.Long) { return forInteger(value.getKind(), value.asLong(), value.asLong(), value.asLong() & IntegerStamp.defaultMask(value.getKind())); - } else if (value.getKind() == Kind.Float || value.getKind() == Kind.Double) { + } else if (value.getKind() == Kind.Float) { + return forFloat(value.getKind(), value.asFloat(), value.asFloat(), !Float.isNaN(value.asFloat())); + } else if (value.getKind() == Kind.Double) { return forFloat(value.getKind(), value.asDouble(), value.asDouble(), !Double.isNaN(value.asDouble())); } return forKind(value.getKind().getStackKind()); diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/BoxingEliminationPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/BoxingEliminationPhase.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/BoxingEliminationPhase.java Fri Nov 30 08:30:22 2012 +0100 @@ -37,8 +37,13 @@ public class BoxingEliminationPhase extends Phase { + private final MetaAccessProvider metaAccess; private int virtualIds = Integer.MIN_VALUE; + public BoxingEliminationPhase(MetaAccessProvider metaAccess) { + this.metaAccess = metaAccess; + } + @Override protected void run(StructuredGraph graph) { if (graph.getNodes(UnboxNode.class).isNotEmpty()) { @@ -71,7 +76,7 @@ ObjectStamp stamp = phiNode.objectStamp(); if (stamp.nonNull() && stamp.isExactType()) { ResolvedJavaType type = stamp.type(); - if (type != null && type.isClass(kind.toBoxedJavaClass())) { + if (type != null && type.equals(metaAccess.lookupJavaType(kind.toBoxedJavaClass()))) { StructuredGraph graph = (StructuredGraph) phiNode.graph(); result = graph.add(new PhiNode(kind, phiNode.merge())); phiReplacements.put(phiNode, result); diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java Fri Nov 30 08:30:22 2012 +0100 @@ -50,7 +50,6 @@ private final TargetDescription target; private final Assumptions assumptions; private final MetaAccessProvider runtime; - private final IsImmutablePredicate immutabilityPredicate; private final Iterable initWorkingSet; private NodeWorkList workList; @@ -58,7 +57,7 @@ private List snapshotTemp; public CanonicalizerPhase(TargetDescription target, MetaAccessProvider runtime, Assumptions assumptions) { - this(target, runtime, assumptions, null, 0, null); + this(target, runtime, assumptions, null, 0); } /** @@ -66,26 +65,24 @@ * @param runtime * @param assumptions * @param workingSet the initial working set of nodes on which the canonicalizer works, should be an auto-grow node bitmap - * @param immutabilityPredicate */ - public CanonicalizerPhase(TargetDescription target, MetaAccessProvider runtime, Assumptions assumptions, Iterable workingSet, IsImmutablePredicate immutabilityPredicate) { - this(target, runtime, assumptions, workingSet, 0, immutabilityPredicate); + public CanonicalizerPhase(TargetDescription target, MetaAccessProvider runtime, Assumptions assumptions, Iterable workingSet) { + this(target, runtime, assumptions, workingSet, 0); } /** * @param newNodesMark only the {@linkplain Graph#getNewNodes(int) new nodes} specified by * this mark are processed otherwise all nodes in the graph are processed */ - public CanonicalizerPhase(TargetDescription target, MetaAccessProvider runtime, Assumptions assumptions, int newNodesMark, IsImmutablePredicate immutabilityPredicate) { - this(target, runtime, assumptions, null, newNodesMark, immutabilityPredicate); + public CanonicalizerPhase(TargetDescription target, MetaAccessProvider runtime, Assumptions assumptions, int newNodesMark) { + this(target, runtime, assumptions, null, newNodesMark); } - private CanonicalizerPhase(TargetDescription target, MetaAccessProvider runtime, Assumptions assumptions, Iterable workingSet, int newNodesMark, IsImmutablePredicate immutabilityPredicate) { + private CanonicalizerPhase(TargetDescription target, MetaAccessProvider runtime, Assumptions assumptions, Iterable workingSet, int newNodesMark) { this.newNodesMark = newNodesMark; this.target = target; this.assumptions = assumptions; this.runtime = runtime; - this.immutabilityPredicate = immutabilityPredicate; this.initWorkingSet = workingSet; this.snapshotTemp = new ArrayList<>(); } @@ -101,18 +98,10 @@ workList = graph.createNodeWorkList(false, MAX_ITERATION_PER_NODE); workList.addAll(initWorkingSet); } - tool = new Tool(workList, runtime, target, assumptions, immutabilityPredicate); + tool = new Tool(workList, runtime, target, assumptions); processWorkSet(graph); } - public interface IsImmutablePredicate { - /** - * Determines if a given constant is an object/array whose current - * fields/elements will never change. - */ - boolean apply(Constant constant); - } - private void processWorkSet(StructuredGraph graph) { graph.trackInputChange(new InputChangedListener() { @Override @@ -288,14 +277,12 @@ private final MetaAccessProvider runtime; private final TargetDescription target; private final Assumptions assumptions; - private final IsImmutablePredicate immutabilityPredicate; - public Tool(NodeWorkList nodeWorkSet, MetaAccessProvider runtime, TargetDescription target, Assumptions assumptions, IsImmutablePredicate immutabilityPredicate) { + public Tool(NodeWorkList nodeWorkSet, MetaAccessProvider runtime, TargetDescription target, Assumptions assumptions) { this.nodeWorkSet = nodeWorkSet; this.runtime = runtime; this.target = target; this.assumptions = assumptions; - this.immutabilityPredicate = immutabilityPredicate; } @Override @@ -329,10 +316,5 @@ public void addToWorkList(Node node) { nodeWorkSet.addAgain(node); } - - @Override - public boolean isImmutable(Constant objectConstant) { - return immutabilityPredicate != null && immutabilityPredicate.apply(objectConstant); - } } } diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java Fri Nov 30 08:30:22 2012 +0100 @@ -240,9 +240,9 @@ return a; } else if (a == b) { return a; - } else if (a.isAssignableTo(b)) { + } else if (b.isAssignableFrom(a)) { return a; - } else if (b.isAssignableTo(a)) { + } else if (a.isAssignableFrom(b)) { return b; } else { return a; @@ -326,7 +326,7 @@ } else if (node instanceof CheckCastNode) { CheckCastNode checkCast = (CheckCastNode) node; ResolvedJavaType type = state.getNodeType(checkCast.object()); - if (type != null && type.isAssignableTo(checkCast.type())) { + if (type != null && checkCast.type().isAssignableFrom(type)) { PiNode piNode; boolean nonNull = state.knownNotNull.contains(checkCast.object()); piNode = graph.unique(new PiNode(checkCast.object(), lastBegin, nonNull ? StampFactory.declaredNonNull(type) : StampFactory.declared(type))); @@ -351,7 +351,7 @@ replaceWith = ConstantNode.forBoolean(false, graph); } else if (state.knownNotNull.contains(object)) { ResolvedJavaType type = state.getNodeType(object); - if (type != null && type.isAssignableTo(instanceOf.type())) { + if (type != null && instanceOf.type().isAssignableFrom(type)) { replaceWith = ConstantNode.forBoolean(true, graph); } } diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java Fri Nov 30 08:30:22 2012 +0100 @@ -89,7 +89,7 @@ Debug.dump(graph, "after %s", candidate); Iterable newNodes = graph.getNewNodes(mark); if (GraalOptions.OptCanonicalizer) { - new CanonicalizerPhase(target, runtime, assumptions, mark, null).apply(graph); + new CanonicalizerPhase(target, runtime, assumptions, mark).apply(graph); } metricInliningPerformed.increment(); diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Fri Nov 30 08:30:22 2012 +0100 @@ -560,7 +560,7 @@ result.setProbability(probability); Kind kind = invoke.node().kind(); - if (!kind.isVoid()) { + if (kind != Kind.Void) { FrameState stateAfter = invoke.stateAfter(); stateAfter = stateAfter.duplicate(stateAfter.bci); stateAfter.replaceFirstInput(invoke.node(), result.node()); @@ -658,7 +658,7 @@ ObjectStamp receiverStamp = callTarget.receiver().objectStamp(); ResolvedJavaType receiverType = receiverStamp.type(); if (receiverStamp.isExactType()) { - assert receiverType.isAssignableTo(targetMethod.getDeclaringClass()) : receiverType + " subtype of " + targetMethod.getDeclaringClass() + " for " + targetMethod; + assert targetMethod.getDeclaringClass().isAssignableFrom(receiverType) : receiverType + " subtype of " + targetMethod.getDeclaringClass() + " for " + targetMethod; ResolvedJavaMethod resolved = receiverType.resolveMethod(targetMethod); if (!checkTargetConditions(invoke, resolved, optimisticOpts, runtime)) { return null; @@ -671,7 +671,7 @@ if (receiverStamp.type() != null) { // the invoke target might be more specific than the holder (happens after inlining: locals lose their declared type...) // TODO (lstadler) fix this - if (receiverType != null && receiverType.isAssignableTo(holder)) { + if (receiverType != null && holder.isAssignableFrom(receiverType)) { holder = receiverType; } } diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IterativeConditionalEliminationPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IterativeConditionalEliminationPhase.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IterativeConditionalEliminationPhase.java Fri Nov 30 08:30:22 2012 +0100 @@ -55,7 +55,7 @@ if (canonicalizationRoots.isEmpty()) { break; } - new CanonicalizerPhase(target, runtime, assumptions, canonicalizationRoots, null).apply(graph); + new CanonicalizerPhase(target, runtime, assumptions, canonicalizationRoots).apply(graph); canonicalizationRoots.clear(); } } diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java Fri Nov 30 08:30:22 2012 +0100 @@ -129,7 +129,7 @@ processBlock(schedule.getCFG().getStartBlock(), graph.createNodeBitMap(), null, schedule, processed); Debug.dump(graph, "Lowering iteration %d", i++); - new CanonicalizerPhase(null, runtime, assumptions, mark, null).apply(graph); + new CanonicalizerPhase(null, runtime, assumptions, mark).apply(graph); if (!containsLowerable(graph.getNewNodes(mark))) { // No new lowerable nodes - done! diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/WordTest.java --- a/graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/WordTest.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/WordTest.java Fri Nov 30 08:30:22 2012 +0100 @@ -32,6 +32,8 @@ import com.oracle.graal.compiler.*; import com.oracle.graal.compiler.test.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.snippets.Snippet.DefaultSnippetInliningPolicy; import com.oracle.graal.snippets.Snippet.SnippetInliningPolicy; /** @@ -114,9 +116,10 @@ @Test public void test_fromObject() { - inliningPolicy.set(new SnippetInliningPolicy() { + inliningPolicy.set(new DefaultSnippetInliningPolicy(new BoxingMethodPool(runtime())) { + @Override public boolean shouldInline(ResolvedJavaMethod method, ResolvedJavaMethod caller) { - return SnippetInliningPolicy.Default.shouldInline(method, caller) && !method.getName().equals("hashCode"); + return super.shouldInline(method, caller) && !method.getName().equals("hashCode"); } }); test("fromToObject", "object1", "object2"); diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Snippet.java --- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Snippet.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Snippet.java Fri Nov 30 08:30:22 2012 +0100 @@ -48,7 +48,7 @@ /** * Specifies the class defining the inlining policy for this snippet. - * A {@linkplain SnippetInliningPolicy#Default default} policy is used if none is supplied. + * A {@linkplain DefaultSnippetInliningPolicy default} policy is used if none is supplied. */ Class inlining() default SnippetInliningPolicy.class; @@ -60,42 +60,49 @@ * Determines if {@code method} should be inlined into {@code caller}. */ boolean shouldInline(ResolvedJavaMethod method, ResolvedJavaMethod caller); + } - /** - * The default inlining policy which inlines everything except for methods - * in any of the following categories. - *
    - *
  • {@linkplain Fold foldable} methods
  • - *
  • {@linkplain NodeIntrinsic node intrinsics}
  • - *
  • native methods
  • - *
  • constructors of {@link Throwable} classes
  • - *
- */ - SnippetInliningPolicy Default = new SnippetInliningPolicy() { - public boolean shouldInline(ResolvedJavaMethod method, ResolvedJavaMethod caller) { - if (Modifier.isNative(method.getModifiers())) { + /** + * The default inlining policy which inlines everything except for methods + * in any of the following categories. + *
    + *
  • {@linkplain Fold foldable} methods
  • + *
  • {@linkplain NodeIntrinsic node intrinsics}
  • + *
  • native methods
  • + *
  • constructors of {@link Throwable} classes
  • + *
+ */ + public static class DefaultSnippetInliningPolicy implements SnippetInliningPolicy { + private final BoxingMethodPool pool; + + public DefaultSnippetInliningPolicy(BoxingMethodPool pool) { + this.pool = pool; + } + + @Override + public boolean shouldInline(ResolvedJavaMethod method, ResolvedJavaMethod caller) { + if (Modifier.isNative(method.getModifiers())) { + return false; + } + if (method.getAnnotation(Fold.class) != null) { + return false; + } + if (method.getAnnotation(NodeIntrinsic.class) != null) { + return false; + } + if (Throwable.class.isAssignableFrom(getMirrorOrFail(method.getDeclaringClass(), null))) { + if (method.getName().equals("")) { return false; } - if (method.getAnnotation(Fold.class) != null) { - return false; - } - if (method.getAnnotation(NodeIntrinsic.class) != null) { - return false; - } - if (Throwable.class.isAssignableFrom(getMirrorOrFail(method.getDeclaringClass(), null))) { - if (method.getName().equals("")) { - return false; - } - } - if (method.getAnnotation(Operation.class) != null) { - return false; - } - if (BoxingMethodPool.isSpecialMethodStatic(method)) { - return false; - } - return true; + } + if (method.getAnnotation(Operation.class) != null) { + return false; } - }; + if (pool.isSpecialMethod(method)) { + return false; + } + return true; + } } /** diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetInstaller.java --- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetInstaller.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetInstaller.java Fri Nov 30 08:30:22 2012 +0100 @@ -37,6 +37,7 @@ import com.oracle.graal.nodes.java.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; +import com.oracle.graal.snippets.Snippet.DefaultSnippetInliningPolicy; import com.oracle.graal.snippets.Snippet.SnippetInliningPolicy; /** @@ -122,14 +123,14 @@ } } - private static SnippetInliningPolicy inliningPolicy(ResolvedJavaMethod method) { + private SnippetInliningPolicy inliningPolicy(ResolvedJavaMethod method) { Class policyClass = SnippetInliningPolicy.class; Snippet snippet = method.getAnnotation(Snippet.class); if (snippet != null) { policyClass = snippet.inlining(); } if (policyClass == SnippetInliningPolicy.class) { - return SnippetInliningPolicy.Default; + return new DefaultSnippetInliningPolicy(pool); } try { return policyClass.getConstructor().newInstance(); @@ -169,7 +170,7 @@ Debug.dump(graph, "%s: %s", method.getName(), GraphBuilderPhase.class.getSimpleName()); - new SnippetVerificationPhase().apply(graph); + new SnippetVerificationPhase(runtime).apply(graph); new SnippetIntrinsificationPhase(runtime, pool, true).apply(graph); diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetIntrinsificationPhase.java --- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetIntrinsificationPhase.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetIntrinsificationPhase.java Fri Nov 30 08:30:22 2012 +0100 @@ -319,7 +319,7 @@ try { ValueNode intrinsicNode = (ValueNode) constructor.newInstance(arguments); if (setStampFromReturnType) { - if (returnType.getKind().isObject()) { + if (returnType.getKind() == Kind.Object) { intrinsicNode.setStamp(StampFactory.declared(returnType)); } else { intrinsicNode.setStamp(StampFactory.forKind(returnType.getKind())); diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetTemplate.java --- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetTemplate.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetTemplate.java Fri Nov 30 08:30:22 2012 +0100 @@ -267,7 +267,7 @@ new SnippetIntrinsificationPhase(runtime, new BoxingMethodPool(runtime), false).apply(snippetCopy); new WordTypeRewriterPhase(target.wordKind).apply(snippetCopy); - new CanonicalizerPhase(null, runtime, assumptions, 0, null).apply(snippetCopy); + new CanonicalizerPhase(null, runtime, assumptions, 0).apply(snippetCopy); } // Gather the template parameters @@ -321,7 +321,7 @@ LoopEx loop = new LoopsData(snippetCopy).loop(loopBegin); int mark = snippetCopy.getMark(); LoopTransformations.fullUnroll(loop, runtime, null); - new CanonicalizerPhase(null, runtime, assumptions, mark, null).apply(snippetCopy); + new CanonicalizerPhase(null, runtime, assumptions, mark).apply(snippetCopy); } FixedNode explodeLoopNext = explodeLoop.next(); explodeLoop.clearSuccessors(); @@ -390,7 +390,7 @@ } private static boolean checkConstantArgument(final ResolvedJavaMethod method, Signature signature, int i, String name, Object arg, Kind kind) { - if (kind.isObject()) { + if (kind == Kind.Object) { ResolvedJavaType type = signature.getParameterType(i, method.getDeclaringClass()).resolve(method.getDeclaringClass()); assert arg == null || type.isInstance(Constant.forObject(arg)) : method + ": wrong value type for " + name + ": expected " + type.getName() + ", got " + arg.getClass().getName(); @@ -458,7 +458,7 @@ replacements.put((LocalNode) parameter, (ValueNode) argument); } else { Kind kind = ((LocalNode) parameter).kind(); - assert argument != null || kind.isObject() : this + " cannot accept null for non-object parameter named " + name; + assert argument != null || kind == Kind.Object : this + " cannot accept null for non-object parameter named " + name; Constant constant = Constant.forBoxed(kind, argument); replacements.put((LocalNode) parameter, ConstantNode.forConstant(constant, runtime, replaceeGraph)); } diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetVerificationPhase.java --- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetVerificationPhase.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetVerificationPhase.java Fri Nov 30 08:30:22 2012 +0100 @@ -42,8 +42,16 @@ */ public class SnippetVerificationPhase extends Phase { + private final MetaAccessProvider metaAccess; + + public SnippetVerificationPhase(MetaAccessProvider metaAccess) { + this.metaAccess = metaAccess; + } + @Override protected void run(StructuredGraph graph) { + ResolvedJavaType wordType = metaAccess.lookupJavaType(Word.class); + for (ValueNode node : graph.getNodes().filter(ValueNode.class)) { for (Node usage : node.usages()) { if (usage instanceof AccessMonitorNode) { @@ -83,7 +91,7 @@ ValueNode argument = arguments.get(argc); if (argument == node) { ResolvedJavaType type = (ResolvedJavaType) signature.getParameterType(i, method.getDeclaringClass()); - verify((type.isClass(Word.class)) == isWord(argument), node, invoke.node(), "cannot pass word value to non-word parameter " + i + " or vice-versa"); + verify(type.equals(wordType) == isWord(argument), node, invoke.node(), "cannot pass word value to non-word parameter " + i + " or vice-versa"); } argc++; } diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/WordTypeRewriterPhase.java --- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/WordTypeRewriterPhase.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/WordTypeRewriterPhase.java Fri Nov 30 08:30:22 2012 +0100 @@ -99,7 +99,7 @@ switch (opcode) { case ZERO: { assert arguments.size() == 0; - replace(invoke, wordKind.isLong() ? ConstantNode.forLong(0L, graph) : ConstantNode.forInt(0, graph)); + replace(invoke, wordKind == Kind.Long ? ConstantNode.forLong(0L, graph) : ConstantNode.forInt(0, graph)); break; } @@ -261,12 +261,12 @@ private ValueNode asWordKind(StructuredGraph graph, ValueNode value) { if (value.kind() != wordKind) { Op op; - if (wordKind.isLong()) { - assert value.kind().isStackInt(); + if (wordKind == Kind.Long) { + assert value.kind().getStackKind() == Kind.Int; op = Op.I2L; } else { - assert wordKind.isStackInt(); - assert value.kind().isLong(); + assert wordKind.getStackKind() == Kind.Int; + assert value.kind() == Kind.Long; op = Op.L2I; } return graph.unique(new ConvertNode(op, value)); @@ -278,10 +278,10 @@ Kind from = value.kind(); if (from != to) { Op op; - if (from.isLong()) { + if (from == Kind.Long) { op = Op.L2I; } else { - assert from.isStackInt(); + assert from.getStackKind() == Kind.Int; op = Op.I2L; } return graph.unique(new ConvertNode(op, value)); @@ -296,7 +296,7 @@ if (node instanceof LoadIndexedNode) { return isWord(((LoadIndexedNode) node).array().objectStamp().type().getComponentType()); } - if (node.kind().isObject()) { + if (node.kind() == Kind.Object) { return isWord(node.objectStamp().type()); } return false; diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/BitScanForwardNode.java --- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/BitScanForwardNode.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/BitScanForwardNode.java Fri Nov 30 08:30:22 2012 +0100 @@ -44,9 +44,9 @@ public ValueNode canonical(CanonicalizerTool tool) { if (value.isConstant()) { long v = value.asConstant().asLong(); - if (value.kind().isStackInt()) { + if (value.kind().getStackKind() == Kind.Int) { return ConstantNode.forInt(Integer.numberOfTrailingZeros((int) v), graph()); - } else if (value.kind().isLong()) { + } else if (value.kind() == Kind.Long) { return ConstantNode.forInt(Long.numberOfTrailingZeros(v), graph()); } } diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/BitScanReverseNode.java --- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/BitScanReverseNode.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/BitScanReverseNode.java Fri Nov 30 08:30:22 2012 +0100 @@ -44,9 +44,9 @@ public ValueNode canonical(CanonicalizerTool tool) { if (value.isConstant()) { long v = value.asConstant().asLong(); - if (value.kind().isStackInt()) { + if (value.kind().getStackKind() == Kind.Int) { return ConstantNode.forInt(31 - Integer.numberOfLeadingZeros((int) v), graph()); - } else if (value.kind().isLong()) { + } else if (value.kind() == Kind.Long) { return ConstantNode.forInt(63 - Long.numberOfLeadingZeros(v), graph()); } } diff -r 9bd688f91d3f -r e0fcf7802786 graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/ReverseBytesNode.java --- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/ReverseBytesNode.java Thu Nov 29 17:19:13 2012 +0100 +++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/ReverseBytesNode.java Fri Nov 30 08:30:22 2012 +0100 @@ -22,6 +22,7 @@ */ package com.oracle.graal.snippets.nodes; +import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.gen.*; import com.oracle.graal.compiler.target.*; import com.oracle.graal.lir.*; @@ -36,7 +37,7 @@ public ReverseBytesNode(ValueNode value) { super(StampFactory.forKind(value.kind())); - assert kind().isStackInt() || kind().isLong(); + assert kind().getStackKind() == Kind.Int || kind() == Kind.Long; this.value = value; } @@ -44,9 +45,9 @@ public ValueNode canonical(CanonicalizerTool tool) { if (value.isConstant()) { long v = value.asConstant().asLong(); - if (kind().isStackInt()) { + if (kind().getStackKind() == Kind.Int) { return ConstantNode.forInt(Integer.reverseBytes((int) v), graph()); - } else if (kind().isLong()) { + } else if (kind() == Kind.Long) { return ConstantNode.forLong(Long.reverseBytes(v), graph()); } } diff -r 9bd688f91d3f -r e0fcf7802786 src/share/vm/code/dependencies.cpp --- a/src/share/vm/code/dependencies.cpp Thu Nov 29 17:19:13 2012 +0100 +++ b/src/share/vm/code/dependencies.cpp Fri Nov 30 08:30:22 2012 +0100 @@ -50,6 +50,9 @@ _oop_recorder = env->oop_recorder(); _log = env->log(); _dep_seen = new(arena) GrowableArray(arena, 500, 0, 0); +#ifdef GRAAL + _using_dep_values = false; +#endif // GRAAL DEBUG_ONLY(_deps[end_marker] = NULL); for (int i = (int)FIRST_TYPE; i < (int)TYPE_LIMIT; i++) { _deps[i] = new(arena) GrowableArray(arena, 10, 0, 0); @@ -119,6 +122,56 @@ assert_common_2(call_site_target_value, call_site, method_handle); } +#ifdef GRAAL + +Dependencies::Dependencies(Arena* arena, OopRecorder* oop_recorder) { + _oop_recorder = oop_recorder; + _log = NULL; + _dep_seen = new(arena) GrowableArray(arena, 500, 0, 0); + _using_dep_values = true; + DEBUG_ONLY(_dep_values[end_marker] = NULL); + for (int i = (int)FIRST_TYPE; i < (int)TYPE_LIMIT; i++) { + _dep_values[i] = new(arena) GrowableArray(arena, 10, 0, DepValue()); + } + _content_bytes = NULL; + _size_in_bytes = (size_t)-1; + + assert(TYPE_LIMIT <= (1<oop_is_array()) { + // As a special case, support this assertion on an array type, + // which reduces to an assertion on its element type. + // Note that this cannot be done with assertions that + // relate to concreteness or abstractness. + BasicType elemt = ArrayKlass::cast(ctxk)->element_type(); + if (is_java_primitive(elemt)) return; // Ex: int[][] + ctxk = ObjArrayKlass::cast(ctxk)->bottom_klass(); + //if (ctxk->is_final()) return; // Ex: String[][] + } + check_ctxk(ctxk); + assert_common_1(leaf_type, DepValue(_oop_recorder, ctxk)); +} + +void Dependencies::assert_abstract_with_unique_concrete_subtype(Klass* ctxk, Klass* conck) { + check_ctxk_abstract(ctxk); + DepValue ctxk_dv(_oop_recorder, ctxk); + DepValue conck_dv(_oop_recorder, conck, &ctxk_dv); + assert_common_2(abstract_with_unique_concrete_subtype, ctxk_dv, conck_dv); +} + +void Dependencies::assert_unique_concrete_method(Klass* ctxk, Method* uniqm) { + check_ctxk(ctxk); + assert_common_2(unique_concrete_method, DepValue(_oop_recorder, ctxk), DepValue(_oop_recorder, uniqm)); +} +#endif // GRAAL + + // Helper function. If we are adding a new dep. under ctxk2, // try to find an old dep. under a broader* ctxk1. If there is // @@ -230,6 +283,78 @@ deps->append(x2); } +#ifdef GRAAL +bool Dependencies::maybe_merge_ctxk(GrowableArray* deps, + int ctxk_i, DepValue ctxk2_dv) { + Klass* ctxk1 = deps->at(ctxk_i).as_klass(_oop_recorder); + Klass* ctxk2 = ctxk2_dv.as_klass(_oop_recorder); + if (ctxk2->is_subtype_of(ctxk1)) { + return true; // success, and no need to change + } else if (ctxk1->is_subtype_of(ctxk2)) { + // new context class fully subsumes previous one + deps->at_put(ctxk_i, ctxk2_dv); + return true; + } else { + return false; + } +} + +void Dependencies::assert_common_1(DepType dept, DepValue x) { + assert(dep_args(dept) == 1, "sanity"); + //log_dependency(dept, x); + GrowableArray* deps = _dep_values[dept]; + + // see if the same (or a similar) dep is already recorded + if (note_dep_seen(dept, x)) { + assert(deps->find(x) >= 0, "sanity"); + } else { + deps->append(x); + } +} + +void Dependencies::assert_common_2(DepType dept, + DepValue x0, DepValue x1) { + assert(dep_args(dept) == 2, "sanity"); + //log_dependency(dept, x0, x1); + GrowableArray* deps = _dep_values[dept]; + + // see if the same (or a similar) dep is already recorded + bool has_ctxk = has_explicit_context_arg(dept); + if (has_ctxk) { + assert(dep_context_arg(dept) == 0, "sanity"); + if (note_dep_seen(dept, x1)) { + // look in this bucket for redundant assertions + const int stride = 2; + for (int i = deps->length(); (i -= stride) >= 0; ) { + DepValue y1 = deps->at(i+1); + if (x1 == y1) { // same subject; check the context + if (maybe_merge_ctxk(deps, i+0, x0)) { + return; + } + } + } + } + } else { + assert(dep_implicit_context_arg(dept) == 0, "sanity"); + if (note_dep_seen(dept, x0) && note_dep_seen(dept, x1)) { + // look in this bucket for redundant assertions + const int stride = 2; + for (int i = deps->length(); (i -= stride) >= 0; ) { + DepValue y0 = deps->at(i+0); + DepValue y1 = deps->at(i+1); + if (x0 == y0 && x1 == y1) { + return; + } + } + } + } + + // append the assertion in the correct bucket: + deps->append(x0); + deps->append(x1); +} +#endif // GRAAL + /// Support for encoding dependencies into an nmethod: void Dependencies::copy_to(nmethod* nm) { @@ -256,7 +381,40 @@ static int sort_dep_arg_3(ciBaseObject** p1, ciBaseObject** p2) { return sort_dep(p1, p2, 3); } +#ifdef GRAAL +// metadata deps are sorted before object deps +static int sort_dep_value(Dependencies::DepValue* p1, Dependencies::DepValue* p2, int narg) { + for (int i = 0; i < narg; i++) { + int diff = p1[i].sort_key() - p2[i].sort_key(); + if (diff != 0) return diff; + } + return 0; +} +static int sort_dep_value_arg_1(Dependencies::DepValue* p1, Dependencies::DepValue* p2) +{ return sort_dep_value(p1, p2, 1); } +static int sort_dep_value_arg_2(Dependencies::DepValue* p1, Dependencies::DepValue* p2) +{ return sort_dep_value(p1, p2, 2); } +static int sort_dep_value_arg_3(Dependencies::DepValue* p1, Dependencies::DepValue* p2) +{ return sort_dep_value(p1, p2, 3); } +#endif // GRAAL + void Dependencies::sort_all_deps() { +#ifdef GRAAL + if (_using_dep_values) { + for (int deptv = (int)FIRST_TYPE; deptv < (int)TYPE_LIMIT; deptv++) { + DepType dept = (DepType)deptv; + GrowableArray* deps = _dep_values[dept]; + if (deps->length() <= 1) continue; + switch (dep_args(dept)) { + case 1: deps->sort(sort_dep_value_arg_1, 1); break; + case 2: deps->sort(sort_dep_value_arg_2, 2); break; + case 3: deps->sort(sort_dep_value_arg_3, 3); break; + default: ShouldNotReachHere(); + } + } + return; + } +#endif // GRAAL for (int deptv = (int)FIRST_TYPE; deptv < (int)TYPE_LIMIT; deptv++) { DepType dept = (DepType)deptv; GrowableArray* deps = _deps[dept]; @@ -272,6 +430,16 @@ size_t Dependencies::estimate_size_in_bytes() { size_t est_size = 100; +#ifdef GRAAL + if (_using_dep_values) { + for (int deptv = (int)FIRST_TYPE; deptv < (int)TYPE_LIMIT; deptv++) { + DepType dept = (DepType)deptv; + GrowableArray* deps = _dep_values[dept]; + est_size += deps->length() * 2; // tags and argument(s) + } + return est_size; + } +#endif // GRAAL for (int deptv = (int)FIRST_TYPE; deptv < (int)TYPE_LIMIT; deptv++) { DepType dept = (DepType)deptv; GrowableArray* deps = _deps[dept]; @@ -311,6 +479,37 @@ // cast is safe, no deps can overflow INT_MAX CompressedWriteStream bytes((int)estimate_size_in_bytes()); +#ifdef GRAAL + if (_using_dep_values) { + for (int deptv = (int)FIRST_TYPE; deptv < (int)TYPE_LIMIT; deptv++) { + DepType dept = (DepType)deptv; + GrowableArray* deps = _dep_values[dept]; + if (deps->length() == 0) continue; + int stride = dep_args(dept); + int ctxkj = dep_context_arg(dept); // -1 if no context arg + assert(stride > 0, "sanity"); + for (int i = 0; i < deps->length(); i += stride) { + jbyte code_byte = (jbyte)dept; + int skipj = -1; + if (ctxkj >= 0 && ctxkj+1 < stride) { + Klass* ctxk = deps->at(i+ctxkj+0).as_klass(_oop_recorder); + DepValue x = deps->at(i+ctxkj+1); // following argument + if (ctxk == ctxk_encoded_as_null(dept, x.as_metadata(_oop_recorder))) { + skipj = ctxkj; // we win: maybe one less oop to keep track of + code_byte |= default_context_type_bit; + } + } + bytes.write_byte(code_byte); + for (int j = 0; j < stride; j++) { + if (j == skipj) continue; + DepValue v = deps->at(i+j); + int idx = v.index(); + bytes.write_int(idx); + } + } + } + } else { +#endif // GRAAL for (int deptv = (int)FIRST_TYPE; deptv < (int)TYPE_LIMIT; deptv++) { DepType dept = (DepType)deptv; GrowableArray* deps = _deps[dept]; @@ -344,6 +543,9 @@ } } } +#ifdef GRAAL + } +#endif // GRAAL // write a sentinel byte to mark the end bytes.write_byte(end_marker); @@ -360,7 +562,6 @@ _size_in_bytes = bytes.position(); } - const char* Dependencies::_dep_name[TYPE_LIMIT] = { "end_marker", "evol_method", diff -r 9bd688f91d3f -r e0fcf7802786 src/share/vm/code/dependencies.hpp --- a/src/share/vm/code/dependencies.hpp Thu Nov 29 17:19:13 2012 +0100 +++ b/src/share/vm/code/dependencies.hpp Fri Nov 30 08:30:22 2012 +0100 @@ -200,10 +200,59 @@ static void check_valid_dependency_type(DepType dept); +#ifdef GRAAL + // A Metadata* or object value recorded in an OopRecorder + class DepValue VALUE_OBJ_CLASS_SPEC { + private: + // Unique identifier of the value within the associated OopRecorder that + // encodes both the category of the value (0: invalid, positive: metadata, negative: object) + // and the index within a category specific array (metadata: index + 1, object: -(index + 1)) + int _id; + + public: + DepValue() : _id(0) {} + DepValue(OopRecorder* rec, Metadata* metadata, DepValue* candidate = NULL) { + assert(candidate == NULL || candidate->is_metadata(), "oops"); + if (candidate != NULL && candidate->as_metadata(rec) == metadata) { + _id = candidate->_id; + } else { + _id = rec->find_index(metadata) + 1; + } + } + DepValue(OopRecorder* rec, jobject obj, DepValue* candidate = NULL) { + assert(candidate == NULL || candidate->is_object(), "oops"); + if (candidate != NULL && candidate->as_object(rec) == obj) { + _id = candidate->_id; + } else { + _id = -(rec->find_index(obj) + 1); + } + } + + // Used to sort values in ascending order of index() with metadata values preceding object values + int sort_key() const { return -_id; } + + bool operator == (const DepValue& other) const { return other._id == _id; } + + bool is_valid() const { return _id != 0; } + int index() const { assert(is_valid(), "oops"); return _id < 0 ? -(_id + 1) : _id - 1; } + bool is_metadata() const { assert(is_valid(), "oops"); return _id > 0; } + bool is_object() const { assert(is_valid(), "oops"); return _id < 0; } + + Metadata* as_metadata(OopRecorder* rec) const { assert(is_metadata(), "oops"); return rec->metadata_at(index()); } + Klass* as_klass(OopRecorder* rec) const { assert(as_metadata(rec)->is_klass(), "oops"); return (Klass*) as_metadata(rec); } + Method* as_method(OopRecorder* rec) const { assert(as_metadata(rec)->is_method(), "oops"); return (Method*) as_metadata(rec); } + jobject as_object(OopRecorder* rec) const { assert(is_object(), "oops"); return rec->oop_at(index()); } + }; +#endif + private: // State for writing a new set of dependencies: GrowableArray* _dep_seen; // (seen[h->ident] & (1<* _deps[TYPE_LIMIT]; +#ifdef GRAAL + bool _using_dep_values; + GrowableArray* _dep_values[TYPE_LIMIT]; +#endif static const char* _dep_name[TYPE_LIMIT]; static int _dep_args[TYPE_LIMIT]; @@ -222,8 +271,25 @@ return (seen & (1<at_grow(x_id, 0); + _dep_seen->at_put(x_id, seen | (1<* deps, int ctxk_i, ciKlass* ctxk); +#ifdef GRAAL + bool maybe_merge_ctxk(GrowableArray* deps, + int ctxk_i, DepValue ctxk); +#endif void sort_all_deps(); size_t estimate_size_in_bytes(); @@ -245,6 +311,9 @@ Dependencies(ciEnv* env) { initialize(env); } +#ifdef GRAAL + Dependencies(Arena* arena, OopRecorder* oop_recorder); +#endif // GRAAL private: // Check for a valid context type. @@ -277,6 +346,25 @@ void assert_has_no_finalizable_subclasses(ciKlass* ctxk); void assert_call_site_target_value(ciCallSite* call_site, ciMethodHandle* method_handle); +#ifdef GRAAL + private: + static void check_ctxk(Klass* ctxk) { + assert(ctxk->oop_is_instance(), "java types only"); + } + static void check_ctxk_abstract(Klass* ctxk) { + check_ctxk(ctxk); + assert(ctxk->is_abstract(), "must be abstract"); + } + void assert_common_1(DepType dept, DepValue x); + void assert_common_2(DepType dept, DepValue x0, DepValue x1); + + public: + void assert_evol_method(Method* m); + void assert_leaf_type(Klass* ctxk); + void assert_unique_concrete_method(Klass* ctxk, Method* uniqm); + void assert_abstract_with_unique_concrete_subtype(Klass* ctxk, Klass* conck); +#endif // GRAAL + // Define whether a given method or type is concrete. // These methods define the term "concrete" as used in this module. // For this module, an "abstract" class is one which is non-concrete. diff -r 9bd688f91d3f -r e0fcf7802786 src/share/vm/graal/graalCodeInstaller.cpp --- a/src/share/vm/graal/graalCodeInstaller.cpp Thu Nov 29 17:19:13 2012 +0100 +++ b/src/share/vm/graal/graalCodeInstaller.cpp Fri Nov 30 08:30:22 2012 +0100 @@ -264,10 +264,8 @@ } void CodeInstaller::initialize_assumptions(oop target_method) { - _oop_recorder = new OopRecorder(_env->arena()); - _env->set_oop_recorder(_oop_recorder); - _env->set_dependencies(_dependencies); - _dependencies = new Dependencies(_env); + _oop_recorder = new OopRecorder(&_arena); + _dependencies = new Dependencies(&_arena, _oop_recorder); Handle assumptions_handle = CompilationResult::assumptions(HotSpotCompilationResult::comp(target_method)); if (!assumptions_handle.is_null()) { objArrayHandle assumptions(Thread::current(), (objArrayOop)Assumptions::list(assumptions_handle())); @@ -292,7 +290,6 @@ // constructor used to create a method CodeInstaller::CodeInstaller(Handle& comp_result, methodHandle method, GraalEnv::CodeInstallResult& result, nmethod*& nm, Handle installed_code) { - _env = CURRENT_ENV; GraalCompiler::initialize_buffer_blob(); CodeBuffer buffer(JavaThread::current()->get_buffer_blob()); jobject comp_result_obj = JNIHandles::make_local(comp_result()); @@ -317,10 +314,8 @@ // constructor used to create a stub CodeInstaller::CodeInstaller(Handle& target_method, BufferBlob*& blob, jlong& id) { No_Safepoint_Verifier no_safepoint; - _env = CURRENT_ENV; - _oop_recorder = new OopRecorder(_env->arena()); - _env->set_oop_recorder(_oop_recorder); + _oop_recorder = new OopRecorder(&_arena); initialize_fields(target_method(), NULL); assert(_name != NULL, "installMethod needs NON-NULL name"); @@ -366,10 +361,9 @@ buffer.initialize_stubs_size(256); buffer.initialize_consts_size(_constants_size); - _debug_recorder = new DebugInformationRecorder(_env->oop_recorder()); + _debug_recorder = new DebugInformationRecorder(_oop_recorder); _debug_recorder->set_oopmaps(new OopMapSet()); - _env->set_debug_info(_debug_recorder); buffer.initialize_oop_recorder(_oop_recorder); _instructions = buffer.insts(); @@ -405,33 +399,30 @@ void CodeInstaller::assumption_MethodContents(Handle assumption) { Handle method_handle = Assumptions_MethodContents::method(assumption()); methodHandle method = getMethodFromHotSpotMethod(method_handle()); - ciMethod* m = (ciMethod*) CURRENT_ENV->get_method(method()); - - _dependencies->assert_evol_method(m); + _dependencies->assert_evol_method(method()); } void CodeInstaller::assumption_ConcreteSubtype(Handle assumption) { Handle context_handle = Assumptions_ConcreteSubtype::context(assumption()); - ciKlass* context = (ciKlass*) CURRENT_ENV->get_klass(java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(context_handle))); - - Handle type_handle = Assumptions_ConcreteSubtype::subtype(assumption()); - ciKlass* type = (ciKlass*) CURRENT_ENV->get_klass(java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(type_handle))); + Handle subtype_handle = Assumptions_ConcreteSubtype::subtype(assumption()); + Klass* context = asKlass(HotSpotResolvedObjectType::metaspaceKlass(context_handle)); + Klass* subtype = asKlass(HotSpotResolvedObjectType::metaspaceKlass(subtype_handle)); - _dependencies->assert_leaf_type(type); - if (context != type) { + _dependencies->assert_leaf_type(subtype); + if (context != subtype) { assert(context->is_abstract(), ""); - _dependencies->assert_abstract_with_unique_concrete_subtype(context, type); + _dependencies->assert_abstract_with_unique_concrete_subtype(context, subtype); } } void CodeInstaller::assumption_ConcreteMethod(Handle assumption) { Handle impl_handle = Assumptions_ConcreteMethod::impl(assumption()); + Handle context_handle = Assumptions_ConcreteMethod::context(assumption()); + methodHandle impl = getMethodFromHotSpotMethod(impl_handle()); - ciMethod* m = (ciMethod*) CURRENT_ENV->get_method(impl()); - - Handle context_handle = Assumptions_ConcreteMethod::context(assumption()); - ciKlass* context = (ciKlass*) CURRENT_ENV->get_klass(java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(context_handle))); - _dependencies->assert_unique_concrete_method(context, m); + Klass* context = asKlass(HotSpotResolvedObjectType::metaspaceKlass(context_handle)); + + _dependencies->assert_unique_concrete_method(context, impl()); } void CodeInstaller::process_exception_handlers() { diff -r 9bd688f91d3f -r e0fcf7802786 src/share/vm/graal/graalCodeInstaller.hpp --- a/src/share/vm/graal/graalCodeInstaller.hpp Thu Nov 29 17:19:13 2012 +0100 +++ b/src/share/vm/graal/graalCodeInstaller.hpp Fri Nov 30 08:30:22 2012 +0100 @@ -54,7 +54,7 @@ MARK_ACCESS_FIELD_PATCHING = 0x4002 }; - ciEnv* _env; + Arena _arena; oop _comp_result; oop _name; diff -r 9bd688f91d3f -r e0fcf7802786 src/share/vm/graal/graalCompiler.cpp --- a/src/share/vm/graal/graalCompiler.cpp Thu Nov 29 17:19:13 2012 +0100 +++ b/src/share/vm/graal/graalCompiler.cpp Fri Nov 30 08:30:22 2012 +0100 @@ -161,13 +161,11 @@ assert(_initialized, "must already be initialized"); ResourceMark rm; - ciEnv* current_env = JavaThread::current()->env(); - JavaThread::current()->set_env(NULL); + assert(JavaThread::current()->env() == NULL, "ciEnv should be null"); JavaThread::current()->set_compiling(true); Handle holder = GraalCompiler::createHotSpotResolvedObjectType(method, CHECK); jboolean success = VMToCompiler::compileMethod(method(), holder, entry_bci, blocking, method->graal_priority()); JavaThread::current()->set_compiling(false); - JavaThread::current()->set_env(current_env); if (success != JNI_TRUE) { method->clear_queued_for_compilation(); CompilationPolicy::policy()->delay_compilation(method()); diff -r 9bd688f91d3f -r e0fcf7802786 src/share/vm/graal/graalCompilerToVM.cpp --- a/src/share/vm/graal/graalCompilerToVM.cpp Thu Nov 29 17:19:13 2012 +0100 +++ b/src/share/vm/graal/graalCompilerToVM.cpp Fri Nov 30 08:30:22 2012 +0100 @@ -28,7 +28,6 @@ #include "oops/fieldStreams.hpp" #include "runtime/javaCalls.hpp" #include "c1/c1_Runtime1.hpp" -#include "ci/ciMethodData.hpp" #include "compiler/compileBroker.hpp" #include "compiler/compilerOracle.hpp" #include "graal/graalCompilerToVM.hpp" @@ -741,8 +740,6 @@ Handle compResultHandle = JNIHandles::resolve(compResult); nmethod* nm = NULL; methodHandle method = getMethodFromHotSpotMethod(HotSpotCompilationResult::method(compResult)); - Arena arena; - ciEnv env(&arena); Handle installed_code_handle = JNIHandles::resolve(installed_code); GraalEnv::CodeInstallResult result; CodeInstaller installer(compResultHandle, method, result, nm, installed_code_handle); diff -r 9bd688f91d3f -r e0fcf7802786 src/share/vm/graal/graalEnv.cpp --- a/src/share/vm/graal/graalEnv.cpp Thu Nov 29 17:19:13 2012 +0100 +++ b/src/share/vm/graal/graalEnv.cpp Fri Nov 30 08:30:22 2012 +0100 @@ -45,8 +45,6 @@ #include "c1/c1_Runtime1.hpp" // ------------------------------------------------------------------ -// ciEnv::check_klass_accessiblity -// // Note: the logic of this method should mirror the logic of // constantPoolOopDesc::verify_constant_pool_resolve. bool GraalEnv::check_klass_accessibility(KlassHandle accessing_klass, KlassHandle resolved_klass) { @@ -68,7 +66,6 @@ } // ------------------------------------------------------------------ -// ciEnv::get_klass_by_name_impl KlassHandle GraalEnv::get_klass_by_name_impl(KlassHandle& accessing_klass, constantPoolHandle& cpool, Symbol* sym, @@ -120,7 +117,7 @@ sym->utf8_length()-1, CHECK_(KlassHandle())); - // Get element ciKlass recursively. + // Get element Klass recursively. KlassHandle elem_klass = get_klass_by_name_impl(accessing_klass, cpool, @@ -148,7 +145,6 @@ } // ------------------------------------------------------------------ -// ciEnv::get_klass_by_name KlassHandle GraalEnv::get_klass_by_name(KlassHandle& accessing_klass, Symbol* klass_name, bool require_local) { @@ -161,8 +157,6 @@ } // ------------------------------------------------------------------ -// ciEnv::get_klass_by_index_impl -// // Implementation of get_klass_by_index. KlassHandle GraalEnv::get_klass_by_index_impl(constantPoolHandle& cpool, int index, @@ -222,8 +216,6 @@ } // ------------------------------------------------------------------ -// ciEnv::get_klass_by_index -// // Get a klass from the constant pool. KlassHandle GraalEnv::get_klass_by_index(constantPoolHandle& cpool, int index, @@ -235,8 +227,6 @@ } // ------------------------------------------------------------------ -// ciEnv::get_field_by_index_impl -// // Implementation of get_field_by_index. // // Implementation note: the results of field lookups are cached @@ -257,9 +247,6 @@ Symbol* signature = cpool->symbol_at(sig_index); // Get the field's declared holder. - // - // Note: we actually create a ciInstanceKlass for this klass, - // even though we may not need to. int holder_index = cpool->klass_ref_index_at(index); bool holder_is_accessible; KlassHandle declared_holder = get_klass_by_index(cpool, holder_index, @@ -284,8 +271,6 @@ } // ------------------------------------------------------------------ -// ciEnv::get_field_by_index -// // Get a field by index from a klass's constant pool. void GraalEnv::get_field_by_index(instanceKlassHandle& accessor, fieldDescriptor& fd, int index) { ResourceMark rm; @@ -293,8 +278,6 @@ } // ------------------------------------------------------------------ -// ciEnv::lookup_method -// // Perform an appropriate method lookup based on accessor, holder, // name, signature, and bytecode. methodHandle GraalEnv::lookup_method(instanceKlassHandle& h_accessor, @@ -332,7 +315,6 @@ // ------------------------------------------------------------------ -// ciEnv::get_method_by_index_impl methodHandle GraalEnv::get_method_by_index_impl(constantPoolHandle& cpool, int index, Bytecodes::Code bc, instanceKlassHandle& accessor) { @@ -360,23 +342,16 @@ } // Either the declared holder was not loaded, or the method could - // not be found. Create a dummy ciMethod to represent the failed - // lookup. + // not be found. return NULL; } // ------------------------------------------------------------------ -// ciEnv::get_instance_klass_for_declared_method_holder instanceKlassHandle GraalEnv::get_instance_klass_for_declared_method_holder(KlassHandle& method_holder) { - // For the case of .clone(), the method holder can be a ciArrayKlass - // instead of a ciInstanceKlass. For that case simply pretend that the + // For the case of .clone(), the method holder can be an ArrayKlass* + // instead of an InstanceKlass*. For that case simply pretend that the // declared holder is Object.clone since that's where the call will bottom out. - // A more correct fix would trickle out through many interfaces in CI, - // requiring ciInstanceKlass* to become ciKlass* and many more places would - // require checks to make sure the expected type was found. Given that this - // only occurs for clone() the more extensive fix seems like overkill so - // instead we simply smear the array type into Object. if (method_holder->oop_is_instance()) { return instanceKlassHandle(method_holder()); } else if (method_holder->oop_is_array()) { @@ -389,7 +364,6 @@ // ------------------------------------------------------------------ -// ciEnv::get_method_by_index methodHandle GraalEnv::get_method_by_index(constantPoolHandle& cpool, int index, Bytecodes::Code bc, instanceKlassHandle& accessor) { @@ -399,7 +373,6 @@ } // ------------------------------------------------------------------ -// ciEnv::check_for_system_dictionary_modification // Check for changes to the system dictionary during compilation // class loads, evolution, breakpoints bool GraalEnv::check_for_system_dictionary_modification(Dependencies* dependencies) { @@ -427,7 +400,6 @@ } // ------------------------------------------------------------------ -// ciEnv::register_method GraalEnv::CodeInstallResult GraalEnv::register_method( methodHandle& method, nmethod*& nm, diff -r 9bd688f91d3f -r e0fcf7802786 src/share/vm/graal/graalEnv.hpp --- a/src/share/vm/graal/graalEnv.hpp Thu Nov 29 17:19:13 2012 +0100 +++ b/src/share/vm/graal/graalEnv.hpp Fri Nov 30 08:30:22 2012 +0100 @@ -34,7 +34,6 @@ class CompileTask; -// ciEnv // // This class is the top level broker for requests from the compiler // to the VM. @@ -136,12 +135,8 @@ bool has_unsafe_access, Handle installed_code); - static ciKlass* find_system_klass(ciSymbol* klass_name); - // Note: To find a class from its name string, use ciSymbol::make, - // but consider adding to vmSymbols.hpp instead. - - // converts the ciKlass* representing the holder of a method into a - // ciInstanceKlass*. This is needed since the holder of a method in + // converts the Klass* representing the holder of a method into a + // InstanceKlass*. This is needed since the holder of a method in // the bytecodes could be an array type. Basically this converts // array types into java/lang/Object and other types stay as they are. static instanceKlassHandle get_instance_klass_for_declared_method_holder(KlassHandle& klass); diff -r 9bd688f91d3f -r e0fcf7802786 src/share/vm/prims/jni.cpp --- a/src/share/vm/prims/jni.cpp Thu Nov 29 17:19:13 2012 +0100 +++ b/src/share/vm/prims/jni.cpp Fri Nov 30 08:30:22 2012 +0100 @@ -5152,9 +5152,8 @@ *(JNIEnv**)penv = thread->jni_environment(); #ifdef GRAAL - GraalCompiler* compiler = GraalCompiler::instance(); - ciObjectFactory::initialize(); - compiler->initialize(); + GraalCompiler* compiler = GraalCompiler::instance(); + compiler->initialize(); #endif // Tracks the time application was running before GC