# HG changeset patch # User Christian Wimmer # Date 1396912157 25200 # Node ID db4254246f9a41de4a40b30d7d2ce57a6f348d99 # Parent ff56608229920a136c6290da807106bfeb6f0c37 Remove Constant.forObject and Constant.asObject to improve compiler/VM separation diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeCacheProvider.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeCacheProvider.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeCacheProvider.java Mon Apr 07 16:09:17 2014 -0700 @@ -79,9 +79,8 @@ int getMinimumOutgoingSize(); /** - * Determines if a {@link DataPatch} should be created for a given - * {@linkplain Constant#getPrimitiveAnnotation() annotated} primitive constant that part of a - * {@link CompilationResult}. A data patch is always created for an object constant. + * Determines if a {@link DataPatch} should be created for a given primitive constant that is + * part of a {@link CompilationResult}. A data patch is always created for an object constant. */ boolean needsDataPatch(Constant constant); diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/SpeculationLog.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/SpeculationLog.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/SpeculationLog.java Mon Apr 07 16:09:17 2014 -0700 @@ -31,7 +31,7 @@ * Manages a list of unique deoptimization reasons. * */ -public final class SpeculationLog { +public abstract class SpeculationLog { private volatile Object lastFailed; private volatile Collection speculations; private Set failedSpeculations; @@ -54,7 +54,7 @@ return true; } - public Constant speculate(Object reason) { + protected void addSpeculation(Object reason) { assert maySpeculate(reason); if (speculations == null) { synchronized (this) { @@ -64,6 +64,7 @@ } } speculations.add(reason); - return Constant.forObject(reason); } + + public abstract Constant speculate(Object reason); } diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestConstantReflectionProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestConstantReflectionProvider.java Mon Apr 07 16:09:17 2014 -0700 @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.api.meta.test; + +import static org.junit.Assert.*; + +import java.lang.reflect.*; + +import org.junit.*; + +import com.oracle.graal.api.meta.*; + +/** + * Tests for {@link ConstantReflectionProvider}. It assumes an implementation of the interface that + * actually returns non-null results for access operations that are possible, i.e., the tests will + * fail for an implementation that spuriously returns null (which is allowed by the specification). + */ +public class TestConstantReflectionProvider extends TypeUniverse { + + @Test + public void constantEqualsTest() { + for (Constant c1 : constants) { + for (Constant c2 : constants) { + // test symmetry + assertEquals(constantReflection.constantEquals(c1, c2), constantReflection.constantEquals(c2, c1)); + if (c1.getKind() != Kind.Object && c2.getKind() != Kind.Object) { + assertEquals(c1.equals(c2), constantReflection.constantEquals(c2, c1)); + } + } + } + } + + @Test + public void readArrayLengthTest() { + for (Constant c : constants) { + Integer actual = constantReflection.readArrayLength(c); + if (c.getKind() != Kind.Object || c.isNull() || !snippetReflection.asObject(c).getClass().isArray()) { + assertNull(actual); + } else { + assertNotNull(actual); + int actualInt = actual; + assertEquals(Array.getLength(snippetReflection.asObject(c)), actualInt); + } + } + } + + @Test + public void boxTest() { + for (Constant c : constants) { + Constant boxed = constantReflection.boxPrimitive(c); + if (c.getKind().isPrimitive()) { + assertTrue(boxed.getKind().isObject()); + assertFalse(boxed.isNull()); + } + } + + assertEquals(Long.valueOf(42), snippetReflection.asObject(constantReflection.boxPrimitive(Constant.forLong(42)))); + assertEquals(Integer.valueOf(666), snippetReflection.asObject(constantReflection.boxPrimitive(Constant.forInt(666)))); + assertEquals(Byte.valueOf((byte) 123), snippetReflection.asObject(constantReflection.boxPrimitive(Constant.forByte((byte) 123)))); + assertSame(Boolean.TRUE, snippetReflection.asObject(constantReflection.boxPrimitive(Constant.forBoolean(true)))); + + assertNull(constantReflection.boxPrimitive(Constant.NULL_OBJECT)); + assertNull(constantReflection.boxPrimitive(snippetReflection.forObject("abc"))); + } + + @Test + public void unboxTest() { + for (Constant c : constants) { + Constant unboxed = constantReflection.unboxPrimitive(c); + if (unboxed != null) { + assertFalse(unboxed.getKind().isObject()); + } + } + + assertEquals(Constant.forLong(42), constantReflection.unboxPrimitive(snippetReflection.forObject(Long.valueOf(42)))); + assertEquals(Constant.forInt(666), constantReflection.unboxPrimitive(snippetReflection.forObject(Integer.valueOf(666)))); + assertEquals(Constant.forByte((byte) 123), constantReflection.unboxPrimitive(snippetReflection.forObject(Byte.valueOf((byte) 123)))); + assertSame(Constant.forBoolean(true), constantReflection.unboxPrimitive(snippetReflection.forObject(Boolean.TRUE))); + + assertNull(constantReflection.unboxPrimitive(Constant.NULL_OBJECT)); + assertNull(constantReflection.unboxPrimitive(snippetReflection.forObject("abc"))); + } + + @Test + public void testAsJavaType() { + for (Constant c : constants) { + ResolvedJavaType type = constantReflection.asJavaType(c); + + Object o = snippetReflection.asBoxedValue(c); + if (o instanceof Class) { + assertEquals(metaAccess.lookupJavaType((Class) o), type); + } else { + assertNull(type); + } + } + + } +} diff -r ff5660822992 -r db4254246f9a 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 Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestMetaAccessProvider.java Mon Apr 07 16:09:17 2014 -0700 @@ -81,7 +81,7 @@ public void lookupJavaTypeConstantTest() { for (Constant c : constants) { if (c.getKind() == Kind.Object && !c.isNull()) { - Object o = c.asObject(); + Object o = snippetReflection.asObject(c); ResolvedJavaType type = metaAccess.lookupJavaType(c); assertNotNull(type); assertTrue(type.equals(metaAccess.lookupJavaType(o.getClass()))); @@ -90,31 +90,4 @@ } } } - - @Test - public void constantEqualsTest() { - for (Constant c1 : constants) { - for (Constant c2 : constants) { - // test symmetry - assertEquals(constantReflection.constantEquals(c1, c2), constantReflection.constantEquals(c2, c1)); - if (c1.getKind() != Kind.Object && c2.getKind() != Kind.Object) { - assertEquals(c1.equals(c2), constantReflection.constantEquals(c2, c1)); - } - } - } - } - - @Test - public void lookupArrayLengthTest() { - for (Constant c : constants) { - Integer actual = constantReflection.lookupArrayLength(c); - if (c.getKind() != Kind.Object || c.isNull() || !c.asObject().getClass().isArray()) { - assertNull(actual); - } else { - assertNotNull(actual); - int actualInt = actual; - assertEquals(Array.getLength(c.asObject()), actualInt); - } - } - } } diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaField.java --- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaField.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaField.java Mon Apr 07 16:09:17 2014 -0700 @@ -78,7 +78,7 @@ if (isStatic(field.getModifiers())) { try { Object expected = field.get(null); - Object actual = e.getValue().readConstantValue(null).asBoxedValue(); + Object actual = snippetReflection.asBoxedValue(e.getValue().readConstantValue(null)); assertEquals(expected, actual); } catch (IllegalArgumentException | IllegalAccessException e1) { } @@ -86,7 +86,7 @@ try { Object receiver = field.getDeclaringClass().newInstance(); Object expected = field.get(receiver); - Object actual = e.getValue().readConstantValue(Constant.forObject(receiver)).asBoxedValue(); + Object actual = snippetReflection.asBoxedValue(e.getValue().readConstantValue(snippetReflection.forObject(receiver))); assertEquals(expected, actual); } catch (InstantiationException | IllegalArgumentException | IllegalAccessException e1) { } @@ -95,16 +95,16 @@ ResolvedJavaField field = metaAccess.lookupJavaField(getClass().getDeclaredField("stringField")); for (Object receiver : new Object[]{this, null, new String()}) { - Constant value = field.readConstantValue(Constant.forObject(receiver)); + Constant value = field.readConstantValue(snippetReflection.forObject(receiver)); assertNull(value); } ResolvedJavaField constField = metaAccess.lookupJavaField(getClass().getDeclaredField("constantStringField")); for (Object receiver : new Object[]{this, null, new String()}) { - Constant value = constField.readConstantValue(Constant.forObject(receiver)); + Constant value = constField.readConstantValue(snippetReflection.forObject(receiver)); if (value != null) { Object expected = "constantField"; - assertTrue(value.asObject() == expected); + assertTrue(snippetReflection.asObject(value) == expected); } } } @@ -117,7 +117,7 @@ if (isStatic(field.getModifiers())) { try { Object expected = field.get(null); - Object actual = e.getValue().readValue(null).asBoxedValue(); + Object actual = snippetReflection.asBoxedValue(e.getValue().readValue(null)); assertEquals(expected, actual); } catch (IllegalArgumentException | IllegalAccessException e1) { } @@ -131,7 +131,7 @@ ResolvedJavaField rf = metaAccess.lookupJavaField(f); Object receiver = isStatic(f.getModifiers()) ? null : testString; Object expected = f.get(receiver); - Object actual = rf.readValue(receiver == null ? null : Constant.forObject(receiver)).asBoxedValue(); + Object actual = snippetReflection.asBoxedValue(rf.readValue(receiver == null ? null : snippetReflection.forObject(receiver))); assertEquals(expected, actual); } } diff -r ff5660822992 -r db4254246f9a 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 Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaType.java Mon Apr 07 16:09:17 2014 -0700 @@ -123,7 +123,7 @@ public void isInstanceTest() { for (Constant c : constants) { if (c.getKind() == Kind.Object && !c.isNull()) { - Object o = c.asObject(); + Object o = snippetReflection.asObject(c); Class cls = o.getClass(); while (cls != null) { ResolvedJavaType type = metaAccess.lookupJavaType(cls); diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TypeUniverse.java --- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TypeUniverse.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TypeUniverse.java Mon Apr 07 16:09:17 2014 -0700 @@ -32,6 +32,7 @@ import sun.misc.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.replacements.*; import com.oracle.graal.api.runtime.*; import com.oracle.graal.phases.util.*; import com.oracle.graal.runtime.*; @@ -46,6 +47,7 @@ public final MetaAccessProvider metaAccess; public final ConstantReflectionProvider constantReflection; + public final SnippetReflectionProvider snippetReflection; public final Collection> classes = new HashSet<>(); public final Map, Class> arrayClasses = new HashMap<>(); public final List constants = new ArrayList<>(); @@ -54,6 +56,7 @@ Providers providers = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getProviders(); metaAccess = providers.getMetaAccess(); constantReflection = providers.getConstantReflection(); + snippetReflection = Graal.getRequiredCapability(SnippetReflectionProvider.class); Unsafe theUnsafe = null; try { theUnsafe = Unsafe.getUnsafe(); @@ -88,17 +91,19 @@ } for (Class c : classes) { if (c != void.class && !c.isArray()) { - constants.add(Constant.forObject(Array.newInstance(c, 42))); + constants.add(snippetReflection.forObject(Array.newInstance(c, 42))); } } - constants.add(Constant.forObject(new ArrayList<>())); - constants.add(Constant.forObject(new IdentityHashMap<>())); - constants.add(Constant.forObject(new LinkedHashMap<>())); - constants.add(Constant.forObject(new TreeMap<>())); - constants.add(Constant.forObject(new ArrayDeque<>())); - constants.add(Constant.forObject(new LinkedList<>())); - constants.add(Constant.forObject("a string")); - constants.add(Constant.forObject(42)); + constants.add(snippetReflection.forObject(new ArrayList<>())); + constants.add(snippetReflection.forObject(new IdentityHashMap<>())); + constants.add(snippetReflection.forObject(new LinkedHashMap<>())); + constants.add(snippetReflection.forObject(new TreeMap<>())); + constants.add(snippetReflection.forObject(new ArrayDeque<>())); + constants.add(snippetReflection.forObject(new LinkedList<>())); + constants.add(snippetReflection.forObject("a string")); + constants.add(snippetReflection.forObject(42)); + constants.add(snippetReflection.forObject(String.class)); + constants.add(snippetReflection.forObject(String[].class)); } public synchronized Class getArrayClass(Class componentType) { diff -r ff5660822992 -r db4254246f9a 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 Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java Mon Apr 07 16:09:17 2014 -0700 @@ -22,42 +22,40 @@ */ package com.oracle.graal.api.meta; -import static com.oracle.graal.api.meta.MetaUtil.*; - /** * Represents a constant (boxed) value, such as an integer, floating point number, or object * reference, within the compiler and across the compiler/runtime interface. Exports a set of * {@code Constant} instances that represent frequently used constant values, such as * {@link #NULL_OBJECT}. */ -public final class Constant extends Value { +public abstract class Constant extends Value { private static final long serialVersionUID = -6355452536852663986L; 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, null, i); + INT_CONSTANT_CACHE[i] = new PrimitiveConstant(Kind.Int, i); } } - 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 NULL_OBJECT = new NullConstant(); + public static final Constant INT_MINUS_1 = new PrimitiveConstant(Kind.Int, -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, 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); + public static final Constant LONG_0 = new PrimitiveConstant(Kind.Long, 0L); + public static final Constant LONG_1 = new PrimitiveConstant(Kind.Long, 1L); + public static final Constant FLOAT_0 = new PrimitiveConstant(Kind.Float, Float.floatToRawIntBits(0.0F)); + public static final Constant FLOAT_1 = new PrimitiveConstant(Kind.Float, Float.floatToRawIntBits(1.0F)); + public static final Constant FLOAT_2 = new PrimitiveConstant(Kind.Float, Float.floatToRawIntBits(2.0F)); + public static final Constant DOUBLE_0 = new PrimitiveConstant(Kind.Double, Double.doubleToRawLongBits(0.0D)); + public static final Constant DOUBLE_1 = new PrimitiveConstant(Kind.Double, Double.doubleToRawLongBits(1.0D)); + public static final Constant TRUE = new PrimitiveConstant(Kind.Boolean, 1L); + public static final Constant FALSE = new PrimitiveConstant(Kind.Boolean, 0L); static { assert FLOAT_0 != forFloat(-0.0F) : "Constant for 0.0f must be different from -0.0f"; @@ -65,56 +63,82 @@ assert NULL_OBJECT.isNull(); } - /** - * The boxed object value if {@code !kind.isObject()} otherwise the (possibly null) - * {@link #getPrimitiveAnnotation() annotation} for a primitive value. - */ - private final Object object; - - /** - * The boxed primitive value as a {@code long}. This is ignored iff {@code kind.isObject()}. For - * {@code float} and {@code double} values, this value is the result of - * {@link Float#floatToRawIntBits(float)} and {@link Double#doubleToRawLongBits(double)} - * respectively. - */ - private final long primitive; - - private Constant(Kind kind, Object object, long primitive) { + protected Constant(Kind kind) { super(kind); - this.object = object; - this.primitive = primitive; - } - - /** - * Checks whether this constant is non-null. - * - * @return {@code true} if this constant is a primitive, or an object constant that is not null - */ - public boolean isNonNull() { - return getKind() != Kind.Object || object != null; } /** * Checks whether this constant is null. - * + * * @return {@code true} if this constant is the null constant */ - public boolean isNull() { - return getKind() == Kind.Object && object == null; + public abstract boolean isNull(); + + /** + * Checks whether this constant is non-null. + * + * @return {@code true} if this constant is a primitive, or an object constant that is not null + */ + public final boolean isNonNull() { + return !isNull(); } /** * Checks whether this constant is the default value for its kind (null, 0, 0.0, false). - * + * * @return {@code true} if this constant is the default value for its kind */ - public boolean isDefaultForKind() { - return object == null && primitive == 0; - } + public abstract boolean isDefaultForKind(); + + /** + * Returns the value of this constant as a boxed Java value. + * + * @return the value of this constant + */ + public abstract Object asBoxedPrimitive(); + + /** + * Returns the primitive int value this constant represents. The constant must have a + * {@link Kind#getStackKind()} of {@link Kind#Int}. + * + * @return the constant value + */ + public abstract int asInt(); + + /** + * Returns the primitive boolean value this constant represents. The constant must have kind + * {@link Kind#Boolean}. + * + * @return the constant value + */ + public abstract boolean asBoolean(); - public long getPrimitive() { - assert getKind().isPrimitive(); - return primitive; + /** + * Returns the primitive long value this constant represents. The constant must have kind + * {@link Kind#Long}, a {@link Kind#getStackKind()} of {@link Kind#Int}. + * + * @return the constant value + */ + public abstract long asLong(); + + /** + * Returns the primitive float value this constant represents. The constant must have kind + * {@link Kind#Float}. + * + * @return the constant value + */ + public abstract float asFloat(); + + /** + * Returns the primitive double value this constant represents. The constant must have kind + * {@link Kind#Double}. + * + * @return the constant value + */ + public abstract double asDouble(); + + public String toValueString() { + return getKind().format(asBoxedPrimitive()); } @Override @@ -122,165 +146,13 @@ if (getKind() == Kind.Illegal) { return "illegal"; } else { - String annotationSuffix = ""; - Object primitiveAnnotation = getPrimitiveAnnotation(); - if (getKind() != Kind.Object && primitiveAnnotation != null) { - try { - annotationSuffix = "{" + primitiveAnnotation + "}"; - } catch (Throwable t) { - annotationSuffix = "{" + getSimpleName(primitiveAnnotation.getClass(), true) + "@" + System.identityHashCode(primitiveAnnotation) + "}"; - } - } - return getKind().getJavaName() + "[" + getKind().format(asBoxedValue()) + (getKind() != Kind.Object ? "|0x" + Long.toHexString(primitive) : "") + "]" + annotationSuffix; + return getKind().getJavaName() + "[" + toValueString() + "]"; } } /** - * Returns the value of this constant as a boxed Java value. - * - * @return the value of this constant - */ - public Object asBoxedValue() { - switch (getKind()) { - case Byte: - return (byte) asInt(); - case Boolean: - return asInt() == 0 ? Boolean.FALSE : Boolean.TRUE; - case Short: - return (short) primitive; - case Char: - return (char) primitive; - case Int: - return (int) primitive; - case Long: - return primitive; - case Float: - return asFloat(); - case Double: - return asDouble(); - case Object: - return object; - case Illegal: - return this; - } - throw new IllegalArgumentException(); - } - - private boolean valueEqual(Constant other, boolean ignoreKind) { - // must have equivalent kinds to be equal - if (!ignoreKind && getKind() != other.getKind()) { - return false; - } - if (getKind() == Kind.Object) { - return object == other.object; - } - return primitive == other.primitive && getPrimitiveAnnotation() == other.getPrimitiveAnnotation(); - } - - /** - * Returns the primitive int value this constant represents. The constant must have a - * {@link Kind#getStackKind()} of {@link Kind#Int}. - * - * @return the constant value - */ - public int asInt() { - assert getKind().getStackKind() == Kind.Int; - return (int) primitive; - } - - /** - * Returns the primitive boolean value this constant represents. The constant must have kind - * {@link Kind#Boolean}. - * - * @return the constant value - */ - public boolean asBoolean() { - assert getKind() == Kind.Boolean; - return primitive != 0L; - } - - /** - * Returns the primitive long value this constant represents. The constant must have kind - * {@link Kind#Long}, a {@link Kind#getStackKind()} of {@link Kind#Int}. - * - * @return the constant value - */ - public long asLong() { - assert getKind().isNumericInteger(); - return primitive; - } - - /** - * Returns the primitive float value this constant represents. The constant must have kind - * {@link Kind#Float}. - * - * @return the constant value - */ - public float asFloat() { - assert getKind() == Kind.Float; - return Float.intBitsToFloat((int) primitive); - } - - /** - * Returns the primitive double value this constant represents. The constant must have kind - * {@link Kind#Double}. - * - * @return the constant value - */ - public double asDouble() { - assert getKind() == Kind.Double; - return Double.longBitsToDouble(primitive); - } - - /** - * Returns the object reference this constant represents. The constant must have kind - * {@link Kind#Object}. - * - * @return the constant value - */ - public Object asObject() { - assert getKind() == Kind.Object; - return object; - } - - /** - * Gets the annotation (if any) associated with this constant. - * - * @return null if this constant is not primitive or has no annotation - */ - public Object getPrimitiveAnnotation() { - return getKind() == Kind.Object ? null : object; - } - - /** - * Computes the hashcode of this constant. - * - * @return a suitable hashcode for this constant - */ - @Override - public int hashCode() { - if (getKind() == Kind.Object) { - return System.identityHashCode(object); - } - return (int) primitive * getKind().ordinal(); - } - - /** - * Checks whether this constant equals another object. This is only true if the other object is - * a constant that has the same {@linkplain #getKind() kind}, value and - * {@link #getPrimitiveAnnotation() annotation}. - * - * @param o the object to compare equality - * @return {@code true} if this constant is equivalent to the specified object - */ - @Override - public boolean equals(Object o) { - return o == this || o instanceof Constant && valueEqual((Constant) o, false); - } - - /** * Creates a boxed double constant. - * + * * @param d the double value to box * @return a boxed copy of {@code value} */ @@ -291,12 +163,12 @@ if (Double.compare(d, 1.0D) == 0) { return DOUBLE_1; } - return new Constant(Kind.Double, null, Double.doubleToRawLongBits(d)); + return new PrimitiveConstant(Kind.Double, Double.doubleToRawLongBits(d)); } /** * Creates a boxed float constant. - * + * * @param f the float value to box * @return a boxed copy of {@code value} */ @@ -310,22 +182,22 @@ if (Float.compare(f, 2.0F) == 0) { return FLOAT_2; } - return new Constant(Kind.Float, null, Float.floatToRawIntBits(f)); + return new PrimitiveConstant(Kind.Float, Float.floatToRawIntBits(f)); } /** * Creates a boxed long constant. - * + * * @param i the long value to box * @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, null, i); + return i == 0 ? LONG_0 : i == 1 ? LONG_1 : new PrimitiveConstant(Kind.Long, i); } /** * Creates a boxed integer constant. - * + * * @param i the integer value to box * @return a boxed copy of {@code value} */ @@ -336,22 +208,22 @@ if (i >= 0 && i < INT_CONSTANT_CACHE.length) { return INT_CONSTANT_CACHE[i]; } - return new Constant(Kind.Int, null, i); + return new PrimitiveConstant(Kind.Int, i); } /** * Creates a boxed byte constant. - * + * * @param i the byte value to box * @return a boxed copy of {@code value} */ public static Constant forByte(byte i) { - return new Constant(Kind.Byte, null, i); + return new PrimitiveConstant(Kind.Byte, i); } /** * Creates a boxed boolean constant. - * + * * @param i the boolean value to box * @return a boxed copy of {@code value} */ @@ -361,52 +233,33 @@ /** * Creates a boxed char constant. - * + * * @param i the char value to box * @return a boxed copy of {@code value} */ public static Constant forChar(char i) { - return new Constant(Kind.Char, null, i); + return new PrimitiveConstant(Kind.Char, i); } /** * Creates a boxed short constant. - * + * * @param i the short value to box * @return a boxed copy of {@code value} */ public static Constant forShort(short i) { - return new Constant(Kind.Short, null, i); + return new PrimitiveConstant(Kind.Short, i); } /** - * Creates a boxed object constant. - * - * @param o the object value to box - * @return a boxed copy of {@code value} + * Creates a {@link Constant} from a primitive integer of a certain kind. */ - public static Constant forObject(Object o) { - if (o == null) { - return NULL_OBJECT; - } - 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) { + public static Constant forIntegerKind(Kind kind, long i) { switch (kind) { case Int: - return new Constant(kind, annotation, (int) i); + return new PrimitiveConstant(kind, (int) i); case Long: - return new Constant(kind, annotation, i); + return new PrimitiveConstant(kind, i); default: throw new IllegalArgumentException("not an integer kind: " + kind); } @@ -418,47 +271,42 @@ public static Constant forPrimitiveInt(int bits, long i) { assert bits <= 64; if (bits > 32) { - return new Constant(Kind.Long, null, i); + return new PrimitiveConstant(Kind.Long, i); } else { - return new Constant(Kind.Int, null, (int) i); + return new PrimitiveConstant(Kind.Int, (int) i); } } /** - * Creates a boxed constant for the given kind from an Object. The object needs to be of the - * Java boxed type corresponding to the kind. - * - * @param kind the kind of the constant to create - * @param value the Java boxed value: a {@link Byte} instance for {@link Kind#Byte}, etc. - * @return the boxed copy of {@code value} + * Creates a boxed constant for the given boxed primitive value. + * + * @param value the Java boxed value + * @return the primitive constant holding the {@code value} */ - public static Constant forBoxed(Kind kind, Object value) { - switch (kind) { - case Boolean: - return forBoolean((Boolean) value); - case Byte: - return forByte((Byte) value); - case Char: - return forChar((Character) value); - case Short: - return forShort((Short) value); - case Int: - return forInt((Integer) value); - case Long: - return forLong((Long) value); - case Float: - return forFloat((Float) value); - case Double: - return forDouble((Double) value); - case Object: - return forObject(value); - default: - throw new RuntimeException("cannot create Constant for boxed " + kind + " value"); + public static Constant forBoxedPrimitive(Object value) { + if (value instanceof Boolean) { + return forBoolean((Boolean) value); + } else if (value instanceof Byte) { + return forByte((Byte) value); + } else if (value instanceof Character) { + return forChar((Character) value); + } else if (value instanceof Short) { + return forShort((Short) value); + } else if (value instanceof Integer) { + return forInt((Integer) value); + } else if (value instanceof Long) { + return forLong((Long) value); + } else if (value instanceof Float) { + return forFloat((Float) value); + } else if (value instanceof Double) { + return forDouble((Double) value); + } else { + return null; } } public static Constant forIllegal() { - return new Constant(Kind.Illegal, null, 0); + return new PrimitiveConstant(Kind.Illegal, 0); } /** diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ConstantPool.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ConstantPool.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ConstantPool.java Mon Apr 07 16:09:17 2014 -0700 @@ -117,5 +117,5 @@ * {@code -1} * @return the appendix if it exists and is resolved or {@code null} */ - Object lookupAppendix(int cpi, int opcode); + Constant lookupAppendix(int cpi, int opcode); } diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ConstantReflectionProvider.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ConstantReflectionProvider.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ConstantReflectionProvider.java Mon Apr 07 16:09:17 2014 -0700 @@ -23,34 +23,68 @@ package com.oracle.graal.api.meta; /** - * Reflection operations on values represented as {@linkplain Constant constants}. + * Reflection operations on values represented as {@linkplain Constant constants}. All methods in + * this interface require the VM to access the actual object encapsulated in {@link Kind#Object + * object} constants. This access is not always possible, depending on kind of VM and the state that + * the VM is in. Therefore, all methods can return {@code null} at any time, to indicate that the + * result is not available at this point. The caller is responsible to check for {@code null} + * results and handle them properly, e.g., not perform an optimization. */ public interface ConstantReflectionProvider { /** - * Compares two constants for equality. The equality relationship is symmetric. If the constants - * cannot be compared at this point, the return value is {@code null}; - * - * @return {@code true} if the two parameters represent the same runtime object, {@code false} - * if they are different, or {@code null} if the parameters cannot be compared. + * Compares two constants for equality. The equality relationship is symmetric. Returns + * {@link Boolean#TRUE true} if the two constants represent the same run time value, + * {@link Boolean#FALSE false} if they are different. Returns {@code null} if the constants + * cannot be compared at this point. */ Boolean constantEquals(Constant x, Constant y); /** - * Returns the length of an array that is wrapped in a {@link Constant} object. If {@code array} - * is not an array, or the array length is not available at this point, the return value is - * {@code null}. + * Returns the length of the array constant. Returns {@code null} if the constant is not an + * array, or if the array length is not available at this point. */ - Integer lookupArrayLength(Constant array); + Integer readArrayLength(Constant array); /** - * Reads a value of this kind using a base address and a displacement. - * - * @param base the base address from which the value is read + * Reads a value from the given array at the given index. Returns {@code null} if the constant + * is not an array, if the index is out of bounds, or if the value is not available at this + * point. + */ + Constant readArrayElement(Constant array, int index); + + /** + * Reads a value of this kind using a base address and a displacement. No bounds checking or + * type checking is performed. Returns {@code null} if the value is not available at this point. + * + * @param base the base address from which the value is read. * @param displacement the displacement within the object in bytes * @param compressible whether this is a read of a compressed or an uncompressed pointer * @return the read value encapsulated in a {@link Constant} object, or {@code null} if the * value cannot be read. */ - Constant readUnsafeConstant(Kind kind, Object base, long displacement, boolean compressible); + Constant readUnsafeConstant(Kind kind, Constant base, long displacement, boolean compressible); + + /** + * Converts the given {@link Kind#isPrimitive() primitive} constant to a boxed + * {@link Kind#Object object} constant, according to the Java boxing rules. Returns {@code null} + * if the source is is not a primitive constant, or the boxed value is not available at this + * point. + */ + Constant boxPrimitive(Constant source); + + /** + * Converts the given {@link Kind#Object object} constant to a {@link Kind#isPrimitive() + * primitive} constant, according to the Java unboxing rules. Returns {@code null} if the source + * is is not an object constant that can be unboxed, or the unboxed value is not available at + * this point. + */ + Constant unboxPrimitive(Constant source); + + /** + * Returns the {@link ResolvedJavaType} for a {@link Class} object (or any other object regarded + * as a class by the VM) encapsulated in the given constant. Returns {@code null} if the + * constant does not encapsulate a class, or if the type is not available at this point. + */ + ResolvedJavaType asJavaType(Constant constant); } diff -r ff5660822992 -r db4254246f9a 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 Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaUtil.java Mon Apr 07 16:09:17 2014 -0700 @@ -55,13 +55,13 @@ * @param printTopN print total size and instance count of the top n classes is desired * @return the number of bytes occupied by this constant */ - public static long getMemorySizeRecursive(MetaAccessProvider access, Constant constant, PrintStream out, int printTopN) { - IdentityHashMap marked = new IdentityHashMap<>(); + public static long getMemorySizeRecursive(MetaAccessProvider access, ConstantReflectionProvider constantReflection, Constant constant, PrintStream out, int printTopN) { + Set marked = new HashSet<>(); Stack stack = new Stack<>(); if (constant.getKind() == Kind.Object && constant.isNonNull()) { - marked.put(constant.asObject(), Boolean.TRUE); + marked.add(constant); } - final HashMap histogram = new HashMap<>(); + final HashMap histogram = new HashMap<>(); stack.push(constant); long sum = 0; while (!stack.isEmpty()) { @@ -69,7 +69,7 @@ long memorySize = access.getMemorySize(constant); sum += memorySize; if (c.getKind() == Kind.Object && c.isNonNull()) { - Class clazz = c.asObject().getClass(); + ResolvedJavaType clazz = access.lookupJavaType(c); if (!histogram.containsKey(clazz)) { histogram.put(clazz, new ClassInfo()); } @@ -79,10 +79,10 @@ ResolvedJavaType type = access.lookupJavaType(c); if (type.isArray()) { if (!type.getComponentType().isPrimitive()) { - Object[] array = (Object[]) c.asObject(); - for (Object value : array) { - Constant forObject = Constant.forObject(value); - pushConstant(marked, stack, forObject); + int length = constantReflection.readArrayLength(c); + for (int i = 0; i < length; i++) { + Constant value = constantReflection.readArrayElement(c, i); + pushConstant(marked, stack, value); } } } else { @@ -96,12 +96,12 @@ } } } - ArrayList clazzes = new ArrayList<>(); + ArrayList clazzes = new ArrayList<>(); clazzes.addAll(histogram.keySet()); - Collections.sort(clazzes, new Comparator() { + Collections.sort(clazzes, new Comparator() { @Override - public int compare(Class o1, Class o2) { + public int compare(ResolvedJavaType o1, ResolvedJavaType o2) { long l1 = histogram.get(o1).totalSize; long l2 = histogram.get(o2).totalSize; if (l1 > l2) { @@ -115,7 +115,7 @@ }); int z = 0; - for (Class c : clazzes) { + for (ResolvedJavaType c : clazzes) { if (z > printTopN) { break; } @@ -126,10 +126,10 @@ return sum; } - private static void pushConstant(IdentityHashMap marked, Stack stack, Constant value) { + private static void pushConstant(Set marked, Stack stack, Constant value) { if (value.isNonNull()) { - if (!marked.containsKey(value.asObject())) { - marked.put(value.asObject(), Boolean.TRUE); + if (!marked.contains(value)) { + marked.add(value); stack.push(value); } } diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/NullConstant.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/NullConstant.java Mon Apr 07 16:09:17 2014 -0700 @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.api.meta; + +/** + * The implementation type of the {@link Constant#NULL_OBJECT null constant}. + */ +final class NullConstant extends Constant { + + private static final long serialVersionUID = 8906209595800783961L; + + protected NullConstant() { + super(Kind.Object); + } + + @Override + public boolean isNull() { + return true; + } + + @Override + public boolean isDefaultForKind() { + return true; + } + + @Override + public Object asBoxedPrimitive() { + throw new IllegalArgumentException(); + } + + @Override + public int asInt() { + throw new IllegalArgumentException(); + } + + @Override + public boolean asBoolean() { + throw new IllegalArgumentException(); + } + + @Override + public long asLong() { + throw new IllegalArgumentException(); + } + + @Override + public float asFloat() { + throw new IllegalArgumentException(); + } + + @Override + public double asDouble() { + throw new IllegalArgumentException(); + } + + @Override + public String toValueString() { + return "null"; + } + + @Override + public int hashCode() { + return System.identityHashCode(this); + } + + @Override + public boolean equals(Object o) { + assert o == this || !(o instanceof NullConstant) : "null constant is a singleton"; + return o == this; + } +} diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ObjectLocationIdentity.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ObjectLocationIdentity.java Mon Apr 07 23:35:41 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2013, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.api.meta; - -import java.util.*; - -/** - * A {@link LocationIdentity} wrapping an object. - */ -public final class ObjectLocationIdentity implements LocationIdentity { - - private static IdentityHashMap map = new IdentityHashMap<>(); - - private Object object; - - public static LocationIdentity create(Object object) { - synchronized (map) { - if (map.containsKey(object)) { - return map.get(object); - } else { - ObjectLocationIdentity locationIdentity = new ObjectLocationIdentity(object); - map.put(object, locationIdentity); - return locationIdentity; - } - } - } - - private ObjectLocationIdentity(Object object) { - this.object = object; - } - - @Override - public String toString() { - return "Identity(" + object + ")"; - } -} diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/PrimitiveConstant.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/PrimitiveConstant.java Mon Apr 07 16:09:17 2014 -0700 @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.api.meta; + +/** + * Represents a primitive constant value, such as an integer or floating point number, within the + * compiler and across the compiler/runtime interface. + */ +public class PrimitiveConstant extends Constant { + + private static final long serialVersionUID = 8787949721295655376L; + + /** + * The boxed primitive value as a {@code long}. For {@code float} and {@code double} values, + * this value is the result of {@link Float#floatToRawIntBits(float)} and + * {@link Double#doubleToRawLongBits(double)} respectively. + */ + private final long primitive; + + protected PrimitiveConstant(Kind kind, long primitive) { + super(kind); + this.primitive = primitive; + + assert kind.isPrimitive() || kind == Kind.Illegal; + } + + @Override + public boolean isNull() { + return false; + } + + @Override + public boolean isDefaultForKind() { + return primitive == 0; + } + + @Override + public boolean asBoolean() { + assert getKind() == Kind.Boolean; + return primitive != 0L; + } + + @Override + public int asInt() { + assert getKind().getStackKind() == Kind.Int; + return (int) primitive; + } + + @Override + public long asLong() { + assert getKind().isNumericInteger(); + return primitive; + } + + @Override + public float asFloat() { + assert getKind() == Kind.Float; + return Float.intBitsToFloat((int) primitive); + } + + @Override + public double asDouble() { + assert getKind() == Kind.Double; + return Double.longBitsToDouble(primitive); + } + + @Override + public Object asBoxedPrimitive() { + switch (getKind()) { + case Byte: + return Byte.valueOf((byte) primitive); + case Boolean: + return Boolean.valueOf(asBoolean()); + case Short: + return Short.valueOf((short) primitive); + case Char: + return Character.valueOf((char) primitive); + case Int: + return Integer.valueOf(asInt()); + case Long: + return Long.valueOf(asLong()); + case Float: + return Float.valueOf(asFloat()); + case Double: + return Double.valueOf(asDouble()); + default: + throw new IllegalArgumentException(); + } + } + + @Override + public int hashCode() { + return (int) (primitive ^ (primitive >>> 32)) * (getKind().ordinal() + 31); + } + + @Override + public boolean equals(Object o) { + return o == this || (o instanceof PrimitiveConstant && super.equals(o) && primitive == ((PrimitiveConstant) o).primitive); + } + + @Override + public String toString() { + if (getKind() == Kind.Illegal) { + return "illegal"; + } else { + return getKind().getJavaName() + "[" + getKind().format(asBoxedPrimitive()) + "|0x" + Long.toHexString(primitive) + "]"; + } + } +} diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.api.replacements/src/com/oracle/graal/api/replacements/SnippetReflectionProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.api.replacements/src/com/oracle/graal/api/replacements/SnippetReflectionProvider.java Mon Apr 07 16:09:17 2014 -0700 @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.api.replacements; + +import com.oracle.graal.api.meta.*; + +/** + * Reflection operations on values represented as {@linkplain Constant constants} for the processing + * of snippets. Snippets need a direct access to the value of object constants, which is not allowed + * in other parts of Graal to enforce compiler-VM separation. + *

+ * This interface must not be used in Graal code that is not related to snippet processing. + */ +public interface SnippetReflectionProvider { + + /** + * Creates a boxed {@link Kind#Object object} constant. + * + * @param object the object value to box + * @return a constant containing {@code object} + */ + Constant forObject(Object object); + + /** + * Returns the object reference the given constant represents. The constant must have kind + * {@link Kind#Object}. + * + * @param constant the to access + * @return the object value of the constant + */ + Object asObject(Constant constant); + + /** + * Creates a boxed constant for the given kind from an Object. The object needs to be of the + * Java boxed type corresponding to the kind. + * + * @param kind the kind of the constant to create + * @param value the Java boxed value: a {@link Byte} instance for {@link Kind#Byte}, etc. + * @return the boxed copy of {@code value} + */ + Constant forBoxed(Kind kind, Object value); + + /** + * Returns the value of this constant as a boxed Java value. + * + * @param constant the constant to box + * @return the value of the constant + */ + Object asBoxedValue(Constant constant); +} diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.asm.hsail/src/com/oracle/graal/asm/hsail/HSAILAssembler.java --- a/graal/com.oracle.graal.asm.hsail/src/com/oracle/graal/asm/hsail/HSAILAssembler.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.asm.hsail/src/com/oracle/graal/asm/hsail/HSAILAssembler.java Mon Apr 07 16:09:17 2014 -0700 @@ -25,9 +25,6 @@ import static com.oracle.graal.api.code.MemoryBarriers.*; import static com.oracle.graal.api.code.ValueUtil.*; -import java.lang.reflect.*; - -import com.amd.okra.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; @@ -36,7 +33,7 @@ /** * This class contains routines to emit HSAIL assembly code. */ -public class HSAILAssembler extends AbstractHSAILAssembler { +public abstract class HSAILAssembler extends AbstractHSAILAssembler { /** * Stack size in bytes (used to keep track of spilling). @@ -87,35 +84,13 @@ * references get updated by the GC whenever the GC moves an Object. * * @param a the destination register - * @param obj the Object being moved + * @param src the Object Constant being moved */ - public final void mov(Register a, Object obj) { - String regName = "$d" + a.encoding(); - // For a null object simply move 0x0 into the destination register. - if (obj == null) { - emitString("mov_b64 " + regName + ", 0x0; // null object"); - } else { - // Get a JNI reference handle to the object. - long refHandle = OkraUtil.getRefHandle(obj); - // Get the clasname of the object for emitting a comment. - Class clazz = obj.getClass(); - String className = clazz.getName(); - String comment = "// handle for object of type " + className; - // If the object is an array note the array length in the comment. - if (className.startsWith("[")) { - comment += ", length " + Array.getLength(obj); - } - // First move the reference handle into a register. - emitString("mov_b64 " + regName + ", 0x" + Long.toHexString(refHandle) + "; " + comment); - // Next load the Object addressed by this reference handle into the destination reg. - emitString("ld_global_u64 " + regName + ", [" + regName + "];"); - } - - } + public abstract void mov(Register a, Constant src); public final void emitMov(Kind kind, Value dst, Value src) { if (isRegister(dst) && isConstant(src) && kind.getStackKind() == Kind.Object) { - mov(asRegister(dst), (asConstant(src)).asObject()); + mov(asRegister(dst), asConstant(src)); } else { String argtype = getArgTypeFromKind(kind).substring(1); emitString("mov_b" + argtype + " " + mapRegOrConstToString(dst) + ", " + mapRegOrConstToString(src) + ";"); @@ -127,7 +102,7 @@ if (reg instanceof RegisterValue) { storeValue = HSAIL.mapRegister(reg); } else if (reg instanceof Constant) { - storeValue = ((Constant) reg).asBoxedValue().toString(); + storeValue = ((Constant) reg).toValueString(); } emitString(instr + " " + storeValue + ", " + mapAddress(addr) + ";"); } @@ -320,7 +295,7 @@ String unorderedPrefix = (argType.startsWith("f") && unordered ? "u" : ""); String prefix = "cmp_" + condition + unorderedPrefix + "_b1_" + (isUnsignedCompare ? getArgTypeForceUnsigned(src1) : argType); // Generate a comment for debugging purposes - String comment = (isConstant(src1) && (src1.getKind() == Kind.Object) && (asConstant(src1).asObject() == null) ? " // null test " : ""); + String comment = (isConstant(src1) && (src1.getKind() == Kind.Object) && (asConstant(src1).isNull()) ? " // null test " : ""); // Emit the instruction. emitString(prefix + " $c0, " + mapRegOrConstToString(src0) + ", " + mapRegOrConstToString(src1) + ";" + comment); } @@ -367,8 +342,7 @@ case Long: return "0x" + Long.toHexString(consrc.asLong()); case Object: - Object obj = consrc.asObject(); - if (obj == null) { + if (consrc.isNull()) { return "0"; } else { throw GraalInternalError.shouldNotReachHere("unknown type: " + src); diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.asm.ptx/src/com/oracle/graal/asm/ptx/PTXAssembler.java --- a/graal/com.oracle.graal.asm.ptx/src/com/oracle/graal/asm/ptx/PTXAssembler.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.asm.ptx/src/com/oracle/graal/asm/ptx/PTXAssembler.java Mon Apr 07 16:09:17 2014 -0700 @@ -370,7 +370,7 @@ assert var instanceof Variable; assert val instanceof Constant; Constant constant = (Constant) val; - return ("[" + ((space == PTXStateSpace.Parameter) ? emitParameter((Variable) var) : emitRegister((Variable) var, false)) + " + " + constant.asBoxedValue() + "]"); + return ("[" + ((space == PTXStateSpace.Parameter) ? emitParameter((Variable) var) : emitRegister((Variable) var, false)) + " + " + constant.toValueString() + "]"); } @Override diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Mon Apr 07 16:09:17 2014 -0700 @@ -38,6 +38,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.code.CallingConvention.Type; import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.replacements.*; import com.oracle.graal.api.runtime.*; import com.oracle.graal.baseline.*; import com.oracle.graal.compiler.target.*; @@ -240,6 +241,10 @@ return providers; } + protected SnippetReflectionProvider getSnippetReflection() { + return Graal.getRequiredCapability(SnippetReflectionProvider.class); + } + protected TargetDescription getTarget() { return getProviders().getCodeCache().getTarget(); } diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java Mon Apr 07 16:09:17 2014 -0700 @@ -114,7 +114,7 @@ SchedulePhase schedule = null; try (Scope s = Debug.scope("FrontEnd")) { schedule = GraalCompiler.emitFrontEnd(getProviders(), getBackend().getTarget(), graph, assumptions, null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.NONE, - graph.method().getProfilingInfo(), new SpeculationLog(), getSuites()); + graph.method().getProfilingInfo(), null, getSuites()); } catch (Throwable e) { throw Debug.handle(e); } diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/deopt/CompiledMethodTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/deopt/CompiledMethodTest.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/deopt/CompiledMethodTest.java Mon Apr 07 16:09:17 2014 -0700 @@ -59,8 +59,8 @@ new DeadCodeEliminationPhase().apply(graph); for (ConstantNode node : ConstantNode.getConstantNodes(graph)) { - if (node.getKind() == Kind.Object && " ".equals(node.getValue().asObject())) { - node.replace(graph, ConstantNode.forObject("-", getMetaAccess(), graph)); + if (node.getKind() == Kind.Object && " ".equals(getSnippetReflection().asObject(node.getValue()))) { + node.replace(graph, ConstantNode.forConstant(getSnippetReflection().forObject("-"), getMetaAccess(), graph)); } } diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java Mon Apr 07 16:09:17 2014 -0700 @@ -62,7 +62,7 @@ @Test public void test3() { - testEscapeAnalysis("test3Snippet", Constant.forObject(null), false); + testEscapeAnalysis("test3Snippet", Constant.NULL_OBJECT, false); } public static Object test3Snippet() { @@ -257,7 +257,7 @@ @Test public void testCheckCast() { - testEscapeAnalysis("testCheckCastSnippet", Constant.forObject(TestClassObject.class), false); + testEscapeAnalysis("testCheckCastSnippet", getSnippetReflection().forObject(TestClassObject.class), false); } public Object testCheckCastSnippet() { diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java Mon Apr 07 16:09:17 2014 -0700 @@ -27,6 +27,7 @@ import com.oracle.graal.amd64.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.replacements.*; import com.oracle.graal.api.runtime.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.*; @@ -108,10 +109,11 @@ // to be valid for the entire run of the VM. Assumptions assumptions = new Assumptions(false); Providers p = new Providers(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, null); - Replacements replacements = createReplacements(runtime, assumptions, p); + HotSpotSnippetReflectionProvider snippetReflection = createSnippetReflection(); + Replacements replacements = createReplacements(runtime, assumptions, p, snippetReflection); HotSpotDisassemblerProvider disassembler = createDisassembler(runtime); HotSpotSuitesProvider suites = createSuites(runtime); - HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers); + HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers, snippetReflection); return createBackend(runtime, providers); } @@ -128,8 +130,8 @@ return new HotSpotDisassemblerProvider(runtime); } - protected Replacements createReplacements(HotSpotGraalRuntime runtime, Assumptions assumptions, Providers p) { - return new HotSpotReplacementsImpl(p, runtime.getConfig(), assumptions, p.getCodeCache().getTarget()); + protected Replacements createReplacements(HotSpotGraalRuntime runtime, Assumptions assumptions, Providers p, SnippetReflectionProvider snippetReflection) { + return new HotSpotReplacementsImpl(p, snippetReflection, runtime.getConfig(), assumptions, p.getCodeCache().getTarget()); } protected AMD64HotSpotForeignCallsProvider createForeignCalls(HotSpotGraalRuntime runtime, HotSpotMetaAccessProvider metaAccess, HotSpotCodeCacheProvider codeCache, @@ -153,6 +155,10 @@ return new HotSpotSuitesProvider(runtime); } + protected HotSpotSnippetReflectionProvider createSnippetReflection() { + return new HotSpotSnippetReflectionProvider(); + } + protected AMD64HotSpotLoweringProvider createLowerer(HotSpotGraalRuntime runtime, HotSpotMetaAccessProvider metaAccess, HotSpotForeignCallsProvider foreignCalls, HotSpotRegistersProvider registers) { return new AMD64HotSpotLoweringProvider(runtime, metaAccess, foreignCalls, registers); } @@ -183,15 +189,15 @@ } else { /* * System V Application Binary Interface, AMD64 Architecture Processor Supplement - * + * * Draft Version 0.96 - * + * * http://www.uclibc.org/docs/psABI-x86_64.pdf - * + * * 3.2.1 - * + * * ... - * + * * This subsection discusses usage of each register. Registers %rbp, %rbx and %r12 * through %r15 "belong" to the calling function and the called function is required to * preserve their values. In other words, a called function must preserve these diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Mon Apr 07 16:09:17 2014 -0700 @@ -344,7 +344,12 @@ */ protected static Constant compress(Constant c, CompressEncoding encoding) { if (c.getKind() == Kind.Long) { - return Constant.forIntegerKind(Kind.Int, (int) (((c.asLong() - encoding.base) >> encoding.shift) & 0xffffffffL), c.getPrimitiveAnnotation()); + int compressedValue = (int) (((c.asLong() - encoding.base) >> encoding.shift) & 0xffffffffL); + if (c instanceof HotSpotMetaspaceConstant) { + return HotSpotMetaspaceConstant.forMetaspaceObject(Kind.Int, compressedValue, HotSpotMetaspaceConstant.getMetaspaceObject(c)); + } else { + return Constant.forIntegerKind(Kind.Int, compressedValue); + } } else { throw GraalInternalError.shouldNotReachHere(); } diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLoweringProvider.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLoweringProvider.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLoweringProvider.java Mon Apr 07 16:09:17 2014 -0700 @@ -41,7 +41,7 @@ @Override public void initialize(HotSpotProviders providers, HotSpotVMConfig config) { - convertSnippets = new AMD64ConvertSnippets.Templates(providers, providers.getCodeCache().getTarget()); + convertSnippets = new AMD64ConvertSnippets.Templates(providers, providers.getSnippetReflection(), providers.getCodeCache().getTarget()); super.initialize(providers, config); } diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMemoryPeephole.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMemoryPeephole.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMemoryPeephole.java Mon Apr 07 16:09:17 2014 -0700 @@ -31,6 +31,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.data.*; +import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.amd64.*; import com.oracle.graal.lir.amd64.AMD64ControlFlow.BranchOp; @@ -63,9 +64,9 @@ masm.cmpl(x.toAddress(), 0); } else { if (y.getKind() == Kind.Object) { - crb.recordInlineDataInCode(new OopData(0, constant.asObject(), true)); + crb.recordInlineDataInCode(new OopData(0, HotSpotObjectConstant.asObject(constant), true)); } else if (y.getKind() == Kind.Long) { - crb.recordInlineDataInCode(new MetaspaceData(0, constant.asLong(), constant.getPrimitiveAnnotation(), true)); + crb.recordInlineDataInCode(new MetaspaceData(0, constant.asLong(), HotSpotMetaspaceConstant.getMetaspaceObject(constant), true)); } else { throw GraalInternalError.shouldNotReachHere(); } diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java Mon Apr 07 16:09:17 2014 -0700 @@ -34,6 +34,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.HotSpotVMConfig.CompressEncoding; import com.oracle.graal.hotspot.data.*; +import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.nodes.type.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.amd64.*; @@ -53,8 +54,8 @@ public void emitMemAccess(CompilationResultBuilder crb, AMD64MacroAssembler masm) { if (kind == Kind.Long) { if (NumUtil.isInt(input.asLong())) { - if (input.getPrimitiveAnnotation() != null) { - crb.recordInlineDataInCode(new MetaspaceData(0, input.asLong(), input.getPrimitiveAnnotation(), true)); + if (input instanceof HotSpotMetaspaceConstant) { + crb.recordInlineDataInCode(new MetaspaceData(0, input.asLong(), HotSpotMetaspaceConstant.getMetaspaceObject(input), true)); } masm.movl(address.toAddress(), (int) input.asLong()); } else { @@ -64,7 +65,7 @@ if (input.isNull()) { masm.movl(address.toAddress(), 0); } else if (crb.target.inlineObjects) { - crb.recordInlineDataInCode(new OopData(0, input.asObject(), true)); + crb.recordInlineDataInCode(new OopData(0, HotSpotObjectConstant.asObject(input), true)); masm.movl(address.toAddress(), 0xDEADDEAD); } else { throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to memory"); diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotSafepointOp.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotSafepointOp.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotSafepointOp.java Mon Apr 07 16:09:17 2014 -0700 @@ -77,7 +77,7 @@ if (ImmutableCode.getValue()) { Kind hostWordKind = HotSpotGraalRuntime.getHostWordKind(); int alignment = hostWordKind.getBitCount() / Byte.SIZE; - Constant pollingPageAddress = Constant.forIntegerKind(hostWordKind, config.safepointPollingAddress, null); + Constant pollingPageAddress = Constant.forIntegerKind(hostWordKind, config.safepointPollingAddress); // This move will be patched to load the safepoint page from a data segment // co-located with the immutable code. asm.movq(scratch, (AMD64Address) crb.recordDataReferenceInCode(pollingPageAddress, alignment)); diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotAssembler.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotAssembler.java Mon Apr 07 16:09:17 2014 -0700 @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.hotspot.hsail; + +import java.lang.reflect.*; + +import com.amd.okra.*; +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.hsail.*; +import com.oracle.graal.hotspot.meta.*; + +/** + * This class contains routines to emit HSAIL assembly code. + */ +public class HSAILHotSpotAssembler extends HSAILAssembler { + + public HSAILHotSpotAssembler(TargetDescription target) { + super(target); + } + + @Override + public final void mov(Register a, Constant src) { + String regName = "$d" + a.encoding(); + // For a null object simply move 0x0 into the destination register. + if (src.isNull()) { + emitString("mov_b64 " + regName + ", 0x0; // null object"); + } else { + Object obj = HotSpotObjectConstant.asObject(src); + // Get a JNI reference handle to the object. + long refHandle = OkraUtil.getRefHandle(obj); + // Get the clasname of the object for emitting a comment. + Class clazz = obj.getClass(); + String className = clazz.getName(); + String comment = "// handle for object of type " + className; + // If the object is an array note the array length in the comment. + if (className.startsWith("[")) { + comment += ", length " + Array.getLength(obj); + } + // First move the reference handle into a register. + emitString("mov_b64 " + regName + ", 0x" + Long.toHexString(refHandle) + "; " + comment); + // Next load the Object addressed by this reference handle into the destination reg. + emitString("ld_global_u64 " + regName + ", [" + regName + "];"); + } + } +} diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java --- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java Mon Apr 07 16:09:17 2014 -0700 @@ -412,7 +412,7 @@ @Override protected Assembler createAssembler(FrameMap frameMap) { - return new HSAILAssembler(getTarget()); + return new HSAILHotSpotAssembler(getTarget()); } @Override diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackendFactory.java --- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackendFactory.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackendFactory.java Mon Apr 07 16:09:17 2014 -0700 @@ -50,10 +50,10 @@ // to be valid for the entire run of the VM. Assumptions assumptions = new Assumptions(false); Providers p = new Providers(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, null); - Replacements replacements = new HSAILHotSpotReplacementsImpl(p, assumptions, codeCache.getTarget(), host.getReplacements()); + Replacements replacements = new HSAILHotSpotReplacementsImpl(p, host.getSnippetReflection(), assumptions, codeCache.getTarget(), host.getReplacements()); HotSpotDisassemblerProvider disassembler = host.getDisassembler(); SuitesProvider suites = new DefaultSuitesProvider(); - HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers); + HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers, host.getSnippetReflection()); return new HSAILHotSpotBackend(runtime, providers); } diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerator.java --- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerator.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerator.java Mon Apr 07 16:09:17 2014 -0700 @@ -252,7 +252,12 @@ */ protected static Constant compress(Constant c, CompressEncoding encoding) { if (c.getKind() == Kind.Long) { - return Constant.forIntegerKind(Kind.Int, (int) (((c.asLong() - encoding.base) >> encoding.shift) & 0xffffffffL), c.getPrimitiveAnnotation()); + int compressedValue = (int) (((c.asLong() - encoding.base) >> encoding.shift) & 0xffffffffL); + if (c instanceof HotSpotMetaspaceConstant) { + return HotSpotMetaspaceConstant.forMetaspaceObject(Kind.Int, compressedValue, HotSpotMetaspaceConstant.getMetaspaceObject(c)); + } else { + return Constant.forIntegerKind(Kind.Int, compressedValue); + } } else { throw GraalInternalError.shouldNotReachHere(); } diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotNodeLIRBuilder.java --- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotNodeLIRBuilder.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotNodeLIRBuilder.java Mon Apr 07 16:09:17 2014 -0700 @@ -30,6 +30,7 @@ import com.oracle.graal.compiler.hsail.*; import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.HotSpotVMConfig.CompressEncoding; +import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.nodes.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.hsail.*; @@ -102,7 +103,12 @@ */ protected static Constant compress(Constant c, CompressEncoding encoding) { if (c.getKind() == Kind.Long) { - return Constant.forIntegerKind(Kind.Int, (int) (((c.asLong() - encoding.base) >> encoding.shift) & 0xffffffffL), c.getPrimitiveAnnotation()); + int compressedValue = (int) (((c.asLong() - encoding.base) >> encoding.shift) & 0xffffffffL); + if (c instanceof HotSpotMetaspaceConstant) { + return HotSpotMetaspaceConstant.forMetaspaceObject(Kind.Int, compressedValue, HotSpotMetaspaceConstant.getMetaspaceObject(c)); + } else { + return Constant.forIntegerKind(Kind.Int, compressedValue); + } } else { throw GraalInternalError.shouldNotReachHere(); } diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotReplacementsImpl.java --- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotReplacementsImpl.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotReplacementsImpl.java Mon Apr 07 16:09:17 2014 -0700 @@ -27,6 +27,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.replacements.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.phases.util.*; @@ -41,8 +42,8 @@ private final Replacements host; private HashSet ignoredResolvedMethods = new HashSet<>(); - public HSAILHotSpotReplacementsImpl(Providers providers, Assumptions assumptions, TargetDescription target, Replacements host) { - super(providers, assumptions, target); + public HSAILHotSpotReplacementsImpl(Providers providers, SnippetReflectionProvider snippetReflection, Assumptions assumptions, TargetDescription target, Replacements host) { + super(providers, snippetReflection, assumptions, target); this.host = host; } diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackendFactory.java --- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackendFactory.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackendFactory.java Mon Apr 07 16:09:17 2014 -0700 @@ -47,7 +47,7 @@ HotSpotDisassemblerProvider disassembler = host.getDisassembler(); SuitesProvider suites = new DefaultSuitesProvider(); HotSpotRegistersProvider registers = new HotSpotRegisters(PTX.tid, Register.None, Register.None); - HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers); + HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers, host.getSnippetReflection()); return new PTXHotSpotBackend(runtime, providers); } diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXWrapperBuilder.java --- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXWrapperBuilder.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXWrapperBuilder.java Mon Apr 07 16:09:17 2014 -0700 @@ -192,7 +192,7 @@ } } - InvokeNode kernelStart = createInvoke(getClass(), "getKernelStart", ConstantNode.forObject(kernel, providers.getMetaAccess(), getGraph())); + InvokeNode kernelStart = createInvoke(getClass(), "getKernelStart", ConstantNode.forConstant(HotSpotObjectConstant.forObject(kernel), providers.getMetaAccess(), getGraph())); AllocaNode buf = append(new AllocaNode(bufSize / wordSize, new BitSet())); ValueNode objectParametersOffsets; @@ -290,8 +290,8 @@ Debug.dump(getGraph(), "Initial kernel launch graph"); } - rewriteWordTypes(); - inlineInvokes(); + rewriteWordTypes(providers.getSnippetReflection()); + inlineInvokes(providers.getSnippetReflection()); if (Debug.isDumpEnabled()) { Debug.dump(getGraph(), "Kernel launch graph before compilation"); diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot.server/src/com/oracle/graal/hotspot/server/ReplacingStreams.java --- a/graal/com.oracle.graal.hotspot.server/src/com/oracle/graal/hotspot/server/ReplacingStreams.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.server/src/com/oracle/graal/hotspot/server/ReplacingStreams.java Mon Apr 07 16:09:17 2014 -0700 @@ -28,6 +28,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.hotspot.logging.*; +import com.oracle.graal.hotspot.meta.*; public class ReplacingStreams { @@ -172,7 +173,7 @@ if (constant.getKind() != Kind.Object) { return obj; } - Object contents = constant.asObject(); + Object contents = HotSpotObjectConstant.asObject(constant); if (contents == null) { return obj; } @@ -182,12 +183,12 @@ } placeholder = objectMap.get(contents); if (placeholder != null) { - return Constant.forObject(placeholder); + return HotSpotObjectConstant.forObject(placeholder); } if (contents instanceof Remote) { - return Constant.forObject(createRemoteCallPlaceholder(contents)); + return HotSpotObjectConstant.forObject(createRemoteCallPlaceholder(contents)); } - return Constant.forObject(createDummyPlaceholder(contents)); + return HotSpotObjectConstant.forObject(createDummyPlaceholder(contents)); } return obj; } diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java Mon Apr 07 16:09:17 2014 -0700 @@ -60,10 +60,11 @@ // to be valid for the entire run of the VM. Assumptions assumptions = new Assumptions(false); Providers p = new Providers(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, null); - HotSpotReplacementsImpl replacements = new HotSpotReplacementsImpl(p, runtime.getConfig(), assumptions, target); + HotSpotSnippetReflectionProvider snippetReflection = new HotSpotSnippetReflectionProvider(); + HotSpotReplacementsImpl replacements = new HotSpotReplacementsImpl(p, snippetReflection, runtime.getConfig(), assumptions, target); HotSpotDisassemblerProvider disassembler = new HotSpotDisassemblerProvider(runtime); HotSpotSuitesProvider suites = new HotSpotSuitesProvider(runtime); - HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers); + HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers, snippetReflection); return new SPARCHotSpotBackend(runtime, providers); } diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java --- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java Mon Apr 07 16:09:17 2014 -0700 @@ -104,7 +104,7 @@ NodeIterable filter = getConstantNodes(result); assertEquals(1, filter.count()); - Object mirror = filter.first().asConstant().asObject(); + Object mirror = HotSpotObjectConstant.asObject(filter.first().asConstant()); assertEquals(Class.class, mirror.getClass()); assertEquals(AheadOfTimeCompilationTest.class, mirror); @@ -132,7 +132,7 @@ StructuredGraph result = compile("getPrimitiveClassObject", false); NodeIterable filter = getConstantNodes(result); assertEquals(1, filter.count()); - Object mirror = filter.first().asConstant().asObject(); + Object mirror = HotSpotObjectConstant.asObject(filter.first().asConstant()); assertEquals(Class.class, mirror.getClass()); assertEquals(Integer.TYPE, mirror); @@ -160,7 +160,7 @@ NodeIterable filter = getConstantNodes(result); assertEquals(1, filter.count()); - Object mirror = filter.first().asConstant().asObject(); + Object mirror = HotSpotObjectConstant.asObject(filter.first().asConstant()); assertEquals(String.class, mirror.getClass()); assertEquals("test string", mirror); @@ -193,7 +193,7 @@ assertEquals(1, getConstantNodes(result).count()); ConstantNode constant = getConstantNodes(result).first(); assertEquals(Kind.Object, constant.getKind()); - assertEquals(Boolean.TRUE, constant.asConstant().asObject()); + assertEquals(Boolean.TRUE, HotSpotObjectConstant.asObject(constant.asConstant())); } private StructuredGraph compile(String test, boolean compileAOT) { diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/InstalledCodeExecuteHelperTest.java --- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/InstalledCodeExecuteHelperTest.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/InstalledCodeExecuteHelperTest.java Mon Apr 07 16:09:17 2014 -0700 @@ -89,7 +89,7 @@ assert parameterTypes.length == args.length; for (int i = 0; i < argsToBind.length; i++) { ParameterNode param = graph.getParameter(i); - Constant c = Constant.forBoxed(parameterTypes[i].getKind(), argsToBind[i]); + Constant c = HotSpotObjectConstant.forBoxedValue(parameterTypes[i].getKind(), argsToBind[i]); ConstantNode replacement = ConstantNode.forConstant(c, getMetaAccess(), graph); param.replaceAtUsages(replacement); } diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java --- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java Mon Apr 07 16:09:17 2014 -0700 @@ -187,7 +187,7 @@ */ @Test public void test8() throws Exception { - test2("testUnsafeLoad", wr, new Long(32), null); + test2("testUnsafeLoad", wr, new Long(useCompressedOops() ? 20 : 32), null); } /** @@ -207,7 +207,7 @@ */ @Test public void test9() throws Exception { - test2("testUnsafeLoad", wr, new Long(16), new Integer(16)); + test2("testUnsafeLoad", wr, new Long(useCompressedOops() ? 10 : 16), new Integer(useCompressedOops() ? 10 : 16)); } static Object[] src = new Object[1]; diff -r ff5660822992 -r db4254246f9a 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 Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java Mon Apr 07 16:09:17 2014 -0700 @@ -34,6 +34,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.replacements.*; import com.oracle.graal.api.runtime.*; import com.oracle.graal.compiler.target.*; import com.oracle.graal.graph.*; @@ -362,6 +363,8 @@ public T getCapability(Class clazz) { if (clazz == RuntimeProvider.class) { return (T) this; + } else if (clazz == SnippetReflectionProvider.class) { + return (T) getHostProviders().getSnippetReflection(); } return null; } diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReplacementsImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReplacementsImpl.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReplacementsImpl.java Mon Apr 07 16:09:17 2014 -0700 @@ -26,6 +26,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.replacements.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.replacements.*; import com.oracle.graal.nodes.*; @@ -41,8 +42,8 @@ private final HotSpotVMConfig config; - public HotSpotReplacementsImpl(Providers providers, HotSpotVMConfig config, Assumptions assumptions, TargetDescription target) { - super(providers, assumptions, target); + public HotSpotReplacementsImpl(Providers providers, SnippetReflectionProvider snippetReflection, HotSpotVMConfig config, Assumptions assumptions, TargetDescription target) { + super(providers, snippetReflection, assumptions, target); this.config = config; } diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java Mon Apr 07 16:09:17 2014 -0700 @@ -251,14 +251,14 @@ } public boolean needsDataPatch(Constant constant) { - return constant.getPrimitiveAnnotation() != null; + return constant instanceof HotSpotMetaspaceConstant; } public Data createDataItem(Constant constant, int alignment) { - if (constant.getPrimitiveAnnotation() != null) { - return new MetaspaceData(alignment, constant.asLong(), constant.getPrimitiveAnnotation(), false); + if (constant instanceof HotSpotMetaspaceConstant) { + return new MetaspaceData(alignment, constant.asLong(), HotSpotMetaspaceConstant.getMetaspaceObject(constant), false); } else if (constant.getKind().isObject()) { - return new OopData(alignment, constant.asObject(), false); + return new OopData(alignment, HotSpotObjectConstant.asObject(constant), false); } else { return new PrimitiveData(constant, alignment); } diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantPool.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantPool.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantPool.java Mon Apr 07 16:09:17 2014 -0700 @@ -368,13 +368,13 @@ return lookupType(cpi, opcode); case String: Object string = runtime().getCompilerToVM().resolvePossiblyCachedConstantInPool(metaspaceConstantPool, cpi); - return Constant.forObject(string); + return HotSpotObjectConstant.forObject(string); case MethodHandle: case MethodHandleInError: case MethodType: case MethodTypeInError: Object obj = runtime().getCompilerToVM().resolveConstantInPool(metaspaceConstantPool, cpi); - return Constant.forObject(obj); + return HotSpotObjectConstant.forObject(obj); default: throw GraalInternalError.shouldNotReachHere("unknown constant pool tag " + tag); } @@ -394,10 +394,15 @@ } @Override - public Object lookupAppendix(int cpi, int opcode) { + public Constant lookupAppendix(int cpi, int opcode) { assert Bytecodes.isInvoke(opcode); final int index = toConstantPoolIndex(cpi, opcode); - return runtime().getCompilerToVM().lookupAppendixInPool(metaspaceConstantPool, index); + Object result = runtime().getCompilerToVM().lookupAppendixInPool(metaspaceConstantPool, index); + if (result == null) { + return null; + } else { + return HotSpotObjectConstant.forObject(result); + } } /** diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java Mon Apr 07 16:09:17 2014 -0700 @@ -48,15 +48,34 @@ } @Override - public Integer lookupArrayLength(Constant array) { - if (array.getKind() != Kind.Object || array.isNull() || !array.asObject().getClass().isArray()) { + public Integer readArrayLength(Constant array) { + if (array.getKind() != Kind.Object || array.isNull() || !HotSpotObjectConstant.asObject(array).getClass().isArray()) { return null; } - return Array.getLength(array.asObject()); + return Array.getLength(HotSpotObjectConstant.asObject(array)); } @Override - public Constant readUnsafeConstant(Kind kind, Object base, long displacement, boolean compressible) { + public Constant readUnsafeConstant(Kind kind, Constant baseConstant, long initialDisplacement, boolean compressible) { + Object base; + long displacement; + if (baseConstant.getKind() == Kind.Object) { + base = HotSpotObjectConstant.asObject(baseConstant); + displacement = initialDisplacement; + if (base == null) { + return null; + } + } else if (baseConstant.getKind().isNumericInteger()) { + long baseLong = baseConstant.asLong(); + if (baseLong == 0L) { + return null; + } + displacement = initialDisplacement + baseLong; + base = null; + } else { + throw GraalInternalError.shouldNotReachHere(); + } + switch (kind) { case Boolean: return Constant.forBoolean(base == null ? unsafe.getByte(displacement) != 0 : unsafe.getBoolean(base, displacement)); @@ -89,10 +108,55 @@ } else { o = runtime.getCompilerToVM().readUnsafeUncompressedPointer(base, displacement); } - return Constant.forObject(o); + return HotSpotObjectConstant.forObject(o); } default: throw GraalInternalError.shouldNotReachHere(); } } + + @Override + public Constant readArrayElement(Constant array, int index) { + if (array.getKind() != Kind.Object || array.isNull()) { + return null; + } + Object a = HotSpotObjectConstant.asObject(array); + + if (index < 0 || index >= Array.getLength(a)) { + return null; + } + + if (a instanceof Object[]) { + return HotSpotObjectConstant.forObject(((Object[]) a)[index]); + } else { + return Constant.forBoxedPrimitive(Array.get(a, index)); + } + } + + @Override + public Constant boxPrimitive(Constant source) { + if (!source.getKind().isPrimitive()) { + return null; + } + return HotSpotObjectConstant.forObject(source.asBoxedPrimitive()); + } + + @Override + public Constant unboxPrimitive(Constant source) { + if (!source.getKind().isObject()) { + return null; + } + return Constant.forBoxedPrimitive(HotSpotObjectConstant.asObject(source)); + } + + @Override + public ResolvedJavaType asJavaType(Constant constant) { + if (constant.getKind() == Kind.Object) { + Object obj = HotSpotObjectConstant.asObject(constant); + if (obj instanceof Class) { + return runtime.getHostProviders().getMetaAccess().lookupJavaType((Class) obj); + } + } + return null; + } } diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotHostForeignCallsProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotHostForeignCallsProvider.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotHostForeignCallsProvider.java Mon Apr 07 16:09:17 2014 -0700 @@ -42,7 +42,7 @@ import static com.oracle.graal.hotspot.stubs.NewInstanceStub.*; import static com.oracle.graal.hotspot.stubs.StubUtil.*; import static com.oracle.graal.hotspot.stubs.UnwindExceptionToCallerStub.*; -import static com.oracle.graal.java.GraphBuilderPhase.RuntimeCalls.*; +import static com.oracle.graal.hotspot.meta.HotSpotLoweringProvider.RuntimeCalls.*; import static com.oracle.graal.nodes.java.RegisterFinalizerNode.*; import static com.oracle.graal.replacements.Log.*; import static com.oracle.graal.replacements.MathSubstitutionsX86.*; diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoweringProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoweringProvider.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoweringProvider.java Mon Apr 07 16:09:17 2014 -0700 @@ -90,7 +90,7 @@ newObjectSnippets = new NewObjectSnippets.Templates(providers, target); monitorSnippets = new MonitorSnippets.Templates(providers, target, config.useFastLocking); writeBarrierSnippets = new WriteBarrierSnippets.Templates(providers, target, config.useCompressedOops ? config.getOopEncoding() : null); - boxingSnippets = new BoxingSnippets.Templates(providers, target); + boxingSnippets = new BoxingSnippets.Templates(providers, providers.getSnippetReflection(), target); exceptionObjectSnippets = new LoadExceptionObjectSnippets.Templates(providers, target); unsafeLoadSnippets = new UnsafeLoadSnippets.Templates(providers, target); providers.getReplacements().registerSnippetTemplateCache(new UnsafeArrayCopySnippets.Templates(providers, target)); @@ -134,8 +134,8 @@ lowerOSRStartNode((OSRStartNode) n); } else if (n instanceof DynamicCounterNode) { lowerDynamicCounterNode((DynamicCounterNode) n); - } else if (n instanceof DeferredForeignCallNode) { - lowerDeferredForeignCallNode((DeferredForeignCallNode) n); + } else if (n instanceof BytecodeExceptionNode) { + lowerBytecodeExceptionNode((BytecodeExceptionNode) n); } else if (n instanceof CheckCastDynamicNode) { checkcastDynamicSnippets.lower((CheckCastDynamicNode) n, tool); } else if (n instanceof InstanceOfNode) { @@ -307,7 +307,7 @@ private void lowerLoadFieldNode(LoadFieldNode loadField, LoweringTool tool) { StructuredGraph graph = loadField.graph(); HotSpotResolvedJavaField field = (HotSpotResolvedJavaField) loadField.field(); - ValueNode object = loadField.isStatic() ? ConstantNode.forObject(field.getDeclaringClass().mirror(), metaAccess, graph) : loadField.object(); + ValueNode object = loadField.isStatic() ? ConstantNode.forConstant(HotSpotObjectConstant.forObject(field.getDeclaringClass().mirror()), metaAccess, graph) : loadField.object(); assert loadField.getKind() != Kind.Illegal; BarrierType barrierType = getFieldLoadBarrierType(field); @@ -351,7 +351,7 @@ private void lowerStoreFieldNode(StoreFieldNode storeField, LoweringTool tool) { StructuredGraph graph = storeField.graph(); HotSpotResolvedJavaField field = (HotSpotResolvedJavaField) storeField.field(); - ValueNode object = storeField.isStatic() ? ConstantNode.forObject(field.getDeclaringClass().mirror(), metaAccess, graph) : storeField.object(); + ValueNode object = storeField.isStatic() ? ConstantNode.forConstant(HotSpotObjectConstant.forObject(field.getDeclaringClass().mirror()), metaAccess, graph) : storeField.object(); BarrierType barrierType = getFieldStoreBarrierType(storeField); ValueNode value = implicitStoreConvert(graph, storeField.field().getKind(), storeField.value()); @@ -661,11 +661,51 @@ } } - private void lowerDeferredForeignCallNode(DeferredForeignCallNode deferred) { - StructuredGraph graph = deferred.graph(); + static final class Exceptions { + protected static final ArrayIndexOutOfBoundsException cachedArrayIndexOutOfBoundsException; + protected static final NullPointerException cachedNullPointerException; + + static { + cachedArrayIndexOutOfBoundsException = new ArrayIndexOutOfBoundsException(); + cachedArrayIndexOutOfBoundsException.setStackTrace(new StackTraceElement[0]); + cachedNullPointerException = new NullPointerException(); + cachedNullPointerException.setStackTrace(new StackTraceElement[0]); + } + } + + public static final class RuntimeCalls { + public static final ForeignCallDescriptor CREATE_NULL_POINTER_EXCEPTION = new ForeignCallDescriptor("createNullPointerException", NullPointerException.class); + public static final ForeignCallDescriptor CREATE_OUT_OF_BOUNDS_EXCEPTION = new ForeignCallDescriptor("createOutOfBoundsException", ArrayIndexOutOfBoundsException.class, int.class); + } + + private void lowerBytecodeExceptionNode(BytecodeExceptionNode node) { + StructuredGraph graph = node.graph(); if (graph.getGuardsStage() == StructuredGraph.GuardsStage.FLOATING_GUARDS) { - ForeignCallNode foreignCallNode = graph.add(new ForeignCallNode(foreignCalls, deferred.getDescriptor(), deferred.stamp(), deferred.getArguments())); - graph.replaceFixedWithFixed(deferred, foreignCallNode); + if (OmitHotExceptionStacktrace.getValue()) { + Throwable exception; + if (node.getExceptionClass() == NullPointerException.class) { + exception = Exceptions.cachedNullPointerException; + } else if (node.getExceptionClass() == ArrayIndexOutOfBoundsException.class) { + exception = Exceptions.cachedArrayIndexOutOfBoundsException; + } else { + throw GraalInternalError.shouldNotReachHere(); + } + FloatingNode exceptionNode = ConstantNode.forConstant(HotSpotObjectConstant.forObject(exception), metaAccess, graph); + graph.replaceFixedWithFloating(node, exceptionNode); + + } else { + ForeignCallDescriptor descriptor; + if (node.getExceptionClass() == NullPointerException.class) { + descriptor = RuntimeCalls.CREATE_NULL_POINTER_EXCEPTION; + } else if (node.getExceptionClass() == ArrayIndexOutOfBoundsException.class) { + descriptor = RuntimeCalls.CREATE_OUT_OF_BOUNDS_EXCEPTION; + } else { + throw GraalInternalError.shouldNotReachHere(); + } + + ForeignCallNode foreignCallNode = graph.add(new ForeignCallNode(foreignCalls, descriptor, node.stamp(), node.getArguments())); + graph.replaceFixedWithFixed(node, foreignCallNode); + } } } diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaAccessProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaAccessProvider.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaAccessProvider.java Mon Apr 07 16:09:17 2014 -0700 @@ -54,7 +54,7 @@ if (constant.getKind() != Kind.Object || constant.isNull()) { return null; } - Object o = constant.asObject(); + Object o = HotSpotObjectConstant.asObject(constant); return HotSpotResolvedObjectType.fromClass(o.getClass()); } @@ -295,7 +295,7 @@ } else { if (lookupJavaType.isArray()) { // TODO(tw): Add compressed pointer support. - int length = Array.getLength(constant.asObject()); + int length = Array.getLength(HotSpotObjectConstant.asObject(constant)); ResolvedJavaType elementType = lookupJavaType.getComponentType(); Kind elementKind = elementType.getKind(); final int headerSize = HotSpotGraalRuntime.getArrayBaseOffset(elementKind); diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaspaceConstant.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaspaceConstant.java Mon Apr 07 16:09:17 2014 -0700 @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.hotspot.meta; + +import java.util.*; + +import com.oracle.graal.api.meta.*; + +public final class HotSpotMetaspaceConstant extends PrimitiveConstant { + + private static final long serialVersionUID = 1003463314013122983L; + + public static Constant forMetaspaceObject(Kind kind, long primitive, Object metaspaceObject) { + return new HotSpotMetaspaceConstant(kind, primitive, metaspaceObject); + } + + public static Object getMetaspaceObject(Constant constant) { + return ((HotSpotMetaspaceConstant) constant).metaspaceObject; + } + + private final Object metaspaceObject; + + private HotSpotMetaspaceConstant(Kind kind, long primitive, Object metaspaceObject) { + super(kind, primitive); + this.metaspaceObject = metaspaceObject; + } + + @Override + public int hashCode() { + return super.hashCode() ^ System.identityHashCode(metaspaceObject); + } + + @Override + public boolean equals(Object o) { + return o == this || (o instanceof HotSpotMetaspaceConstant && super.equals(o) && Objects.equals(metaspaceObject, ((HotSpotMetaspaceConstant) o).metaspaceObject)); + } + + @Override + public String toString() { + return super.toString() + "{" + metaspaceObject + "}"; + } +} diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotObjectConstant.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotObjectConstant.java Mon Apr 07 16:09:17 2014 -0700 @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.hotspot.meta; + +import com.oracle.graal.api.meta.*; + +/** + * Represents a constant non-{@code null} object reference, within the compiler and across the + * compiler/runtime interface. + */ +public final class HotSpotObjectConstant extends Constant { + + private static final long serialVersionUID = 3592151693708093496L; + + public static Constant forObject(Object object) { + if (object == null) { + return Constant.NULL_OBJECT; + } else { + return new HotSpotObjectConstant(object); + } + } + + public static Constant forBoxedValue(Kind kind, Object value) { + if (kind == Kind.Object) { + return HotSpotObjectConstant.forObject(value); + } else { + return Constant.forBoxedPrimitive(value); + } + } + + public static Object asObject(Constant constant) { + if (constant.isNull()) { + return null; + } else { + return ((HotSpotObjectConstant) constant).object; + } + } + + public static Object asBoxedValue(Constant constant) { + if (constant.isNull()) { + return null; + } else if (constant.getKind() == Kind.Object) { + return ((HotSpotObjectConstant) constant).object; + } else { + return constant.asBoxedPrimitive(); + } + } + + private final Object object; + + private HotSpotObjectConstant(Object object) { + super(Kind.Object); + this.object = object; + assert object != null; + } + + @Override + public boolean isNull() { + return false; + } + + @Override + public boolean isDefaultForKind() { + return false; + } + + @Override + public Object asBoxedPrimitive() { + throw new IllegalArgumentException(); + } + + @Override + public int asInt() { + throw new IllegalArgumentException(); + } + + @Override + public boolean asBoolean() { + throw new IllegalArgumentException(); + } + + @Override + public long asLong() { + throw new IllegalArgumentException(); + } + + @Override + public float asFloat() { + throw new IllegalArgumentException(); + } + + @Override + public double asDouble() { + throw new IllegalArgumentException(); + } + + @Override + public int hashCode() { + return System.identityHashCode(object); + } + + @Override + public boolean equals(Object o) { + return o == this || (o instanceof HotSpotObjectConstant && super.equals(o) && object == ((HotSpotObjectConstant) o).object); + } + + @Override + public String toValueString() { + if (object instanceof String) { + return (String) object; + } else { + return Kind.Object.format(object); + } + } + + @Override + public String toString() { + return getKind().getJavaName() + "[" + Kind.Object.format(object) + "]"; + } +} diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotProviders.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotProviders.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotProviders.java Mon Apr 07 16:09:17 2014 -0700 @@ -23,6 +23,7 @@ package com.oracle.graal.hotspot.meta; import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.replacements.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.phases.tiers.*; import com.oracle.graal.phases.util.*; @@ -36,13 +37,16 @@ private final HotSpotDisassemblerProvider disassembler; private final SuitesProvider suites; private final HotSpotRegistersProvider registers; + private final SnippetReflectionProvider snippetReflection; public HotSpotProviders(HotSpotMetaAccessProvider metaAccess, HotSpotCodeCacheProvider codeCache, ConstantReflectionProvider constantReflection, HotSpotForeignCallsProvider foreignCalls, - LoweringProvider lowerer, Replacements replacements, HotSpotDisassemblerProvider disassembler, SuitesProvider suites, HotSpotRegistersProvider registers) { + LoweringProvider lowerer, Replacements replacements, HotSpotDisassemblerProvider disassembler, SuitesProvider suites, HotSpotRegistersProvider registers, + SnippetReflectionProvider snippetReflection) { super(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements); this.disassembler = disassembler; this.suites = suites; this.registers = registers; + this.snippetReflection = snippetReflection; } @Override @@ -72,4 +76,7 @@ return registers; } + public SnippetReflectionProvider getSnippetReflection() { + return snippetReflection; + } } diff -r ff5660822992 -r db4254246f9a 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 Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java Mon Apr 07 16:09:17 2014 -0700 @@ -213,7 +213,7 @@ * have a non-default value. */ assert !isStatic(modifiers); - Object object = receiver.asObject(); + Object object = HotSpotObjectConstant.asObject(receiver); // Canonicalization may attempt to process an unsafe read before // processing a guard (e.g. a null check or a type check) for this read @@ -234,7 +234,7 @@ if (StableOptionValue.class.isAssignableFrom(clazz)) { assert getName().equals("value") : "Unexpected field in " + StableOptionValue.class.getName() + " hierarchy:" + this; StableOptionValue option = (StableOptionValue) object; - return Constant.forObject(option.getValue()); + return HotSpotObjectConstant.forObject(option.getValue()); } } } @@ -260,14 +260,13 @@ if (receiver == null) { assert isStatic(modifiers); if (holder.isInitialized()) { - return runtime().getHostProviders().getConstantReflection().readUnsafeConstant(getKind(), holder.mirror(), offset, getKind() == Kind.Object); + return runtime().getHostProviders().getConstantReflection().readUnsafeConstant(getKind(), HotSpotObjectConstant.forObject(holder.mirror()), offset, getKind() == Kind.Object); } return null; } else { assert !isStatic(modifiers); - Object object = receiver.asObject(); - assert object != null && isInObject(object); - return runtime().getHostProviders().getConstantReflection().readUnsafeConstant(getKind(), object, offset, getKind() == Kind.Object); + assert receiver.isNonNull() && isInObject(HotSpotObjectConstant.asObject(receiver)); + return runtime().getHostProviders().getConstantReflection().readUnsafeConstant(getKind(), receiver, offset, getKind() == Kind.Object); } } diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java Mon Apr 07 16:09:17 2014 -0700 @@ -59,7 +59,7 @@ /** * Gets the holder of a HotSpot metaspace method native object. - * + * * @param metaspaceMethod a metaspace Method object * @return the {@link ResolvedJavaType} corresponding to the holder of the * {@code metaspaceMethod} @@ -74,7 +74,7 @@ /** * Gets the {@link ResolvedJavaMethod} for a HotSpot metaspace method native object. - * + * * @param metaspaceMethod a metaspace Method object * @return the {@link ResolvedJavaMethod} corresponding to {@code metaspaceMethod} */ @@ -110,7 +110,7 @@ /** * Returns a pointer to this method's constant method data structure ( * {@code Method::_constMethod}). - * + * * @return pointer to this method's ConstMethod */ private long getConstMethod() { @@ -134,7 +134,7 @@ /** * Returns this method's flags ({@code Method::_flags}). - * + * * @return flags of this method */ private int getFlags() { @@ -143,7 +143,7 @@ /** * Returns this method's constant method flags ({@code ConstMethod::_flags}). - * + * * @return flags of this method's ConstMethod */ private int getConstMethodFlags() { @@ -159,7 +159,7 @@ * Gets the address of the C++ Method object for this method. */ public Constant getMetaspaceMethodConstant() { - return Constant.forIntegerKind(getHostWordKind(), metaspaceMethod, this); + return HotSpotMetaspaceConstant.forMetaspaceObject(getHostWordKind(), metaspaceMethod, this); } @Override @@ -248,7 +248,7 @@ /** * Returns true if this method has a {@code CallerSensitive} annotation. - * + * * @return true if CallerSensitive annotation present, false otherwise */ public boolean isCallerSensitive() { @@ -257,7 +257,7 @@ /** * Returns true if this method has a {@code ForceInline} annotation. - * + * * @return true if ForceInline annotation present, false otherwise */ public boolean isForceInline() { @@ -266,7 +266,7 @@ /** * Returns true if this method has a {@code DontInline} annotation. - * + * * @return true if DontInline annotation present, false otherwise */ public boolean isDontInline() { @@ -283,7 +283,7 @@ /** * Returns true if this method is one of the special methods that is ignored by security stack * walks. - * + * * @return true if special method ignored by security stack walks, false otherwise */ public boolean ignoredBySecurityStackWalk() { @@ -374,7 +374,7 @@ /** * Gets the value of {@code Method::_code}. - * + * * @return the value of {@code Method::_code} */ private long getCompiledCode() { @@ -384,7 +384,7 @@ /** * Returns whether this method has compiled code. - * + * * @return true if this method has compiled code, false otherwise */ public boolean hasCompiledCode() { @@ -589,7 +589,7 @@ /** * Returns the offset of this method into the v-table. The method must have a v-table entry as * indicated by {@link #isInVirtualMethodTable()}, otherwise an exception is thrown. - * + * * @return the offset of this method into the v-table */ public int vtableEntryOffset() { @@ -608,7 +608,7 @@ /** * Returns this method's virtual table index. - * + * * @return virtual table index */ private int getVtableIndex() { @@ -618,7 +618,7 @@ public SpeculationLog getSpeculationLog() { if (speculationLog == null) { - speculationLog = new SpeculationLog(); + speculationLog = new HotSpotSpeculationLog(); } return speculationLog; } @@ -636,13 +636,13 @@ Object[] objArguments = new Object[arguments.length]; for (int i = 0; i < arguments.length; i++) { - objArguments[i] = arguments[i].asBoxedValue(); + objArguments[i] = HotSpotObjectConstant.asBoxedValue(arguments[i]); } - Object objReceiver = receiver != null ? receiver.asObject() : null; + Object objReceiver = receiver != null ? HotSpotObjectConstant.asObject(receiver) : null; try { Object objResult = javaMethod.invoke(objReceiver, objArguments); - return javaMethod.getReturnType() == void.class ? null : Constant.forBoxed(getSignature().getReturnKind(), objResult); + return javaMethod.getReturnType() == void.class ? null : HotSpotObjectConstant.forBoxedValue(getSignature().getReturnKind(), objResult); } catch (IllegalAccessException | InvocationTargetException ex) { throw new IllegalArgumentException(ex); @@ -657,13 +657,13 @@ Object[] objArguments = new Object[arguments.length]; for (int i = 0; i < arguments.length; i++) { - objArguments[i] = arguments[i].asBoxedValue(); + objArguments[i] = HotSpotObjectConstant.asBoxedValue(arguments[i]); } try { Object objResult = javaConstructor.newInstance(objArguments); assert objResult != null; - return Constant.forObject(objResult); + return HotSpotObjectConstant.forObject(objResult); } catch (IllegalAccessException | InvocationTargetException | InstantiationException ex) { throw new IllegalArgumentException(ex); @@ -672,7 +672,7 @@ /** * Allocates a compile id for this method by asking the VM for one. - * + * * @param entryBCI entry bci * @return compile id */ diff -r ff5660822992 -r db4254246f9a 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 Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java Mon Apr 07 16:09:17 2014 -0700 @@ -267,7 +267,7 @@ public Constant getEncoding(Representation r) { switch (r) { case JavaClass: - return Constant.forObject(mirror()); + return HotSpotObjectConstant.forObject(mirror()); case ObjectHub: return klass(); default: @@ -330,7 +330,7 @@ @Override public boolean isInstance(Constant obj) { if (obj.getKind() == Kind.Object && !obj.isNull()) { - return mirror().isInstance(obj.asObject()); + return mirror().isInstance(HotSpotObjectConstant.asObject(obj)); } return false; } @@ -661,7 +661,7 @@ * Gets the metaspace Klass boxed in a {@link Constant}. */ public Constant klass() { - return Constant.forIntegerKind(runtime().getTarget().wordKind, metaspaceKlass(), this); + return HotSpotMetaspaceConstant.forMetaspaceObject(runtime().getTarget().wordKind, metaspaceKlass(), this); } public boolean isPrimaryType() { @@ -747,7 +747,7 @@ @Override public Constant newArray(int length) { - return Constant.forObject(Array.newInstance(mirror(), length)); + return HotSpotObjectConstant.forObject(Array.newInstance(mirror(), length)); } /** diff -r ff5660822992 -r db4254246f9a 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 Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedPrimitiveType.java Mon Apr 07 16:09:17 2014 -0700 @@ -253,6 +253,6 @@ @Override public Constant newArray(int length) { - return Constant.forObject(Array.newInstance(mirror(), length)); + return HotSpotObjectConstant.forObject(Array.newInstance(mirror(), length)); } } diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSnippetReflectionProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSnippetReflectionProvider.java Mon Apr 07 16:09:17 2014 -0700 @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.hotspot.meta; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.replacements.*; + +public class HotSpotSnippetReflectionProvider implements SnippetReflectionProvider { + + @Override + public Constant forObject(Object object) { + return HotSpotObjectConstant.forObject(object); + } + + @Override + public Object asObject(Constant constant) { + return HotSpotObjectConstant.asObject(constant); + } + + @Override + public Constant forBoxed(Kind kind, Object value) { + return HotSpotObjectConstant.forBoxedValue(kind, value); + } + + @Override + public Object asBoxedValue(Constant constant) { + return HotSpotObjectConstant.asBoxedValue(constant); + } +} diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSpeculationLog.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSpeculationLog.java Mon Apr 07 16:09:17 2014 -0700 @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.hotspot.meta; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; + +public class HotSpotSpeculationLog extends SpeculationLog { + + @Override + public Constant speculate(Object reason) { + addSpeculation(reason); + return HotSpotObjectConstant.forObject(reason); + } +} diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/NativeCallStubGraphBuilder.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/NativeCallStubGraphBuilder.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/NativeCallStubGraphBuilder.java Mon Apr 07 16:09:17 2014 -0700 @@ -91,7 +91,7 @@ ReturnNode returnNode = g.add(new ReturnNode(boxedResult)); callNode.setNext(returnNode); - (new WordTypeRewriterPhase(providers.getMetaAccess(), Kind.Long)).apply(g); + (new WordTypeRewriterPhase(providers.getMetaAccess(), providers.getSnippetReflection(), Kind.Long)).apply(g); return g; } catch (NoSuchMethodException e) { throw GraalInternalError.shouldNotReachHere("Call Stub method not found"); diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassCastNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassCastNode.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassCastNode.java Mon Apr 07 16:09:17 2014 -0700 @@ -54,7 +54,7 @@ ValueNode javaClass = getJavaClass(); if (javaClass.isConstant()) { ValueNode object = getObject(); - Class c = (Class) javaClass.asConstant().asObject(); + Class c = (Class) HotSpotObjectConstant.asObject(javaClass.asConstant()); if (c != null && !c.isPrimitive()) { HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) HotSpotResolvedObjectType.fromClass(c); CheckCastNode checkcast = graph().add(new CheckCastNode(type, object, null, false)); diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetComponentTypeNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetComponentTypeNode.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetComponentTypeNode.java Mon Apr 07 16:09:17 2014 -0700 @@ -24,13 +24,14 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; +import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.replacements.*; import com.oracle.graal.nodes.*; import com.oracle.graal.replacements.nodes.*; /** * {@link MacroNode Macro node} for {@link Class#getComponentType()}. - * + * * @see ClassSubstitutions#getComponentType(Class) */ public class ClassGetComponentTypeNode extends MacroNode implements Canonicalizable { @@ -47,10 +48,10 @@ public Node canonical(CanonicalizerTool tool) { ValueNode javaClass = getJavaClass(); if (javaClass.isConstant()) { - Class c = (Class) javaClass.asConstant().asObject(); + Class c = (Class) HotSpotObjectConstant.asObject(javaClass.asConstant()); if (c != null) { Class componentType = c.getComponentType(); - return ConstantNode.forObject(componentType, tool.getMetaAccess(), graph()); + return ConstantNode.forConstant(HotSpotObjectConstant.forObject(componentType), tool.getMetaAccess(), graph()); } } return this; diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetModifiersNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetModifiersNode.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetModifiersNode.java Mon Apr 07 16:09:17 2014 -0700 @@ -24,6 +24,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; +import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.replacements.*; import com.oracle.graal.nodes.*; import com.oracle.graal.replacements.nodes.*; @@ -47,7 +48,7 @@ public Node canonical(CanonicalizerTool tool) { ValueNode javaClass = getJavaClass(); if (javaClass.isConstant()) { - Class c = (Class) javaClass.asConstant().asObject(); + Class c = (Class) HotSpotObjectConstant.asObject(javaClass.asConstant()); if (c != null) { return ConstantNode.forInt(c.getModifiers(), graph()); } diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetSuperclassNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetSuperclassNode.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetSuperclassNode.java Mon Apr 07 16:09:17 2014 -0700 @@ -24,13 +24,14 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; +import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.replacements.*; import com.oracle.graal.nodes.*; import com.oracle.graal.replacements.nodes.*; /** * {@link MacroNode Macro node} for {@link Class#getSuperclass()}. - * + * * @see ClassSubstitutions#getSuperclass(Class) */ public class ClassGetSuperclassNode extends MacroNode implements Canonicalizable { @@ -47,10 +48,10 @@ public Node canonical(CanonicalizerTool tool) { ValueNode javaClass = getJavaClass(); if (javaClass.isConstant()) { - Class c = (Class) javaClass.asConstant().asObject(); + Class c = (Class) HotSpotObjectConstant.asObject(javaClass.asConstant()); if (c != null) { Class superclass = c.getSuperclass(); - return ConstantNode.forObject(superclass, tool.getMetaAccess(), graph()); + return ConstantNode.forConstant(HotSpotObjectConstant.forObject(superclass), tool.getMetaAccess(), graph()); } } return this; diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsArrayNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsArrayNode.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsArrayNode.java Mon Apr 07 16:09:17 2014 -0700 @@ -24,6 +24,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; +import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.replacements.*; import com.oracle.graal.nodes.*; import com.oracle.graal.replacements.nodes.*; @@ -47,7 +48,7 @@ public Node canonical(CanonicalizerTool tool) { ValueNode javaClass = getJavaClass(); if (javaClass.isConstant()) { - Class c = (Class) javaClass.asConstant().asObject(); + Class c = (Class) HotSpotObjectConstant.asObject(javaClass.asConstant()); if (c != null) { return ConstantNode.forBoolean(c.isArray(), graph()); } diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsInstanceNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsInstanceNode.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsInstanceNode.java Mon Apr 07 16:09:17 2014 -0700 @@ -55,13 +55,13 @@ ValueNode javaClass = getJavaClass(); if (javaClass.isConstant()) { ValueNode object = getObject(); - Class c = (Class) javaClass.asConstant().asObject(); + Class c = (Class) HotSpotObjectConstant.asObject(javaClass.asConstant()); if (c != null) { if (c.isPrimitive()) { return ConstantNode.forBoolean(false, graph()); } if (object.isConstant()) { - Object o = object.asConstant().asObject(); + Object o = HotSpotObjectConstant.asObject(object.asConstant()); return ConstantNode.forBoolean(o != null && c.isInstance(o), graph()); } HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) HotSpotResolvedObjectType.fromClass(c); diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsInterfaceNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsInterfaceNode.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsInterfaceNode.java Mon Apr 07 16:09:17 2014 -0700 @@ -24,6 +24,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; +import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.replacements.*; import com.oracle.graal.nodes.*; import com.oracle.graal.replacements.nodes.*; @@ -47,7 +48,7 @@ public Node canonical(CanonicalizerTool tool) { ValueNode javaClass = getJavaClass(); if (javaClass.isConstant()) { - Class c = (Class) javaClass.asConstant().asObject(); + Class c = (Class) HotSpotObjectConstant.asObject(javaClass.asConstant()); if (c != null) { return ConstantNode.forBoolean(c.isInterface(), graph()); } diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsPrimitiveNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsPrimitiveNode.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsPrimitiveNode.java Mon Apr 07 16:09:17 2014 -0700 @@ -24,6 +24,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; +import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.replacements.*; import com.oracle.graal.nodes.*; import com.oracle.graal.replacements.nodes.*; @@ -47,7 +48,7 @@ public Node canonical(CanonicalizerTool tool) { ValueNode javaClass = getJavaClass(); if (javaClass.isConstant()) { - Class c = (Class) javaClass.asConstant().asObject(); + Class c = (Class) HotSpotObjectConstant.asObject(javaClass.asConstant()); if (c != null) { return ConstantNode.forBoolean(c.isPrimitive(), graph()); } diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/AheadOfTimeVerificationPhase.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/AheadOfTimeVerificationPhase.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/AheadOfTimeVerificationPhase.java Mon Apr 07 16:09:17 2014 -0700 @@ -25,6 +25,7 @@ import static com.oracle.graal.nodes.ConstantNode.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.nodes.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.tiers.*; @@ -57,7 +58,7 @@ } private static boolean isNullReference(ConstantNode node) { - return isObject(node) && node.asConstant().asObject() == null; + return isObject(node) && node.asConstant().isNull(); } @SuppressFBWarnings(value = "ES_COMPARING_STRINGS_WITH_EQ", justification = "reference equality is what we want") @@ -66,7 +67,7 @@ return false; } - Object o = node.asConstant().asObject(); + Object o = HotSpotObjectConstant.asObject(node.asConstant()); if (!(o instanceof String)) { return false; } diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/LoadJavaMirrorWithKlassPhase.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/LoadJavaMirrorWithKlassPhase.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/LoadJavaMirrorWithKlassPhase.java Mon Apr 07 16:09:17 2014 -0700 @@ -54,9 +54,9 @@ } private FloatingReadNode getClassConstantReplacement(StructuredGraph graph, PhaseContext context, Constant constant) { - if (constant.getKind() == Kind.Object && constant.asObject() instanceof Class) { + if (constant.getKind() == Kind.Object && HotSpotObjectConstant.asObject(constant) instanceof Class) { MetaAccessProvider metaAccess = context.getMetaAccess(); - ResolvedJavaType type = metaAccess.lookupJavaType((Class) constant.asObject()); + ResolvedJavaType type = metaAccess.lookupJavaType((Class) HotSpotObjectConstant.asObject(constant)); assert type instanceof HotSpotResolvedObjectType; Constant klass = ((HotSpotResolvedObjectType) type).klass(); diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AbstractMethodHandleNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AbstractMethodHandleNode.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AbstractMethodHandleNode.java Mon Apr 07 16:09:17 2014 -0700 @@ -162,7 +162,7 @@ Constant vmtarget = memberNameVmtargetField.readValue(memberName); // Create a method from the vmtarget pointer - Class c = (Class) clazz.asObject(); + Class c = (Class) HotSpotObjectConstant.asObject(clazz); HotSpotResolvedObjectType holderClass = (HotSpotResolvedObjectType) HotSpotResolvedObjectType.fromClass(c); HotSpotResolvedJavaMethod targetMethod = HotSpotResolvedJavaMethod.fromMetaspace(vmtarget.asLong()); diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CallSiteTargetNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CallSiteTargetNode.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CallSiteTargetNode.java Mon Apr 07 16:09:17 2014 -0700 @@ -28,6 +28,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; +import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.replacements.nodes.*; @@ -44,7 +45,7 @@ private ConstantNode getConstantCallTarget(MetaAccessProvider metaAccess, Assumptions assumptions) { if (getCallSite().isConstant() && !getCallSite().isNullConstant()) { - CallSite callSite = (CallSite) getCallSite().asConstant().asObject(); + CallSite callSite = (CallSite) HotSpotObjectConstant.asObject(getCallSite().asConstant()); MethodHandle target = callSite.getTarget(); if (!(callSite instanceof ConstantCallSite)) { if (assumptions == null || !assumptions.useOptimisticAssumptions()) { @@ -52,7 +53,7 @@ } assumptions.record(new Assumptions.CallSiteTargetValue(callSite, target)); } - return ConstantNode.forObject(target, metaAccess, graph()); + return ConstantNode.forConstant(HotSpotObjectConstant.forObject(target), metaAccess, graph()); } return null; } diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CheckCastDynamicSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CheckCastDynamicSnippets.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CheckCastDynamicSnippets.java Mon Apr 07 16:09:17 2014 -0700 @@ -32,13 +32,13 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.debug.*; +import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.nodes.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; -import com.oracle.graal.phases.util.*; import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates; import com.oracle.graal.replacements.SnippetTemplate.Arguments; @@ -69,8 +69,8 @@ private final SnippetInfo dynamic = snippet(CheckCastDynamicSnippets.class, "checkcastDynamic"); - public Templates(Providers providers, TargetDescription target) { - super(providers, target); + public Templates(HotSpotProviders providers, TargetDescription target) { + super(providers, providers.getSnippetReflection(), target); } public void lower(CheckCastDynamicNode checkcast, LoweringTool tool) { diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CompositeValueClassSubstitutions.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CompositeValueClassSubstitutions.java Mon Apr 07 16:09:17 2014 -0700 @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.hotspot.replacements; + +import static com.oracle.graal.phases.GraalOptions.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.replacements.*; +import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.lir.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.replacements.nodes.*; + +/** + * Substitutions for improving the performance of {@link CompositeValueClass#getClass()}. + */ +@ClassSubstitution(CompositeValueClass.class) +public class CompositeValueClassSubstitutions { + + /** + * A macro node for calls to {@link CompositeValueClass#get(Class)}. It can use the compiler's + * knowledge about node classes to replace itself with a constant value for a constant + * {@link Class} parameter. + */ + public static class CompositeValueClassGetNode extends PureFunctionMacroNode { + + public CompositeValueClassGetNode(Invoke invoke) { + super(invoke); + } + + @SuppressWarnings("unchecked") + @Override + protected Constant evaluate(Constant param, MetaAccessProvider metaAccess) { + if (param.isNull() || ImmutableCode.getValue()) { + return null; + } + return HotSpotObjectConstant.forObject(CompositeValueClass.get((Class) HotSpotObjectConstant.asObject(param))); + } + } + + @MacroSubstitution(isStatic = true, forced = true, macro = CompositeValueClassGetNode.class) + private static native CompositeValueClass get(Class c); +} diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotSubstitutions.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotSubstitutions.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotSubstitutions.java Mon Apr 07 16:09:17 2014 -0700 @@ -42,5 +42,7 @@ replacements.registerSubstitutions(CipherBlockChainingSubstitutions.class); replacements.registerSubstitutions(CRC32Substitutions.class); replacements.registerSubstitutions(ReflectionSubstitutions.class); + replacements.registerSubstitutions(NodeClassSubstitutions.class); + replacements.registerSubstitutions(CompositeValueClassSubstitutions.class); } } diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java Mon Apr 07 16:09:17 2014 -0700 @@ -42,7 +42,6 @@ import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; import com.oracle.graal.options.*; -import com.oracle.graal.phases.util.*; import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.Snippet.ConstantParameter; import com.oracle.graal.replacements.Snippet.VarargsParameter; @@ -216,8 +215,8 @@ private final SnippetInfo instanceofSecondary = snippet(InstanceOfSnippets.class, "instanceofSecondary"); private final SnippetInfo instanceofDynamic = snippet(InstanceOfSnippets.class, "instanceofDynamic"); - public Templates(Providers providers, TargetDescription target) { - super(providers, target); + public Templates(HotSpotProviders providers, TargetDescription target) { + super(providers, providers.getSnippetReflection(), target); } @Override diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/LoadExceptionObjectSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/LoadExceptionObjectSnippets.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/LoadExceptionObjectSnippets.java Mon Apr 07 16:09:17 2014 -0700 @@ -66,7 +66,7 @@ private final SnippetInfo loadException = snippet(LoadExceptionObjectSnippets.class, "loadException"); public Templates(HotSpotProviders providers, TargetDescription target) { - super(providers, target); + super(providers, providers.getSnippetReflection(), target); } public void lower(LoadExceptionObjectNode loadExceptionObject, HotSpotRegistersProvider registers, LoweringTool tool) { diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java Mon Apr 07 16:09:17 2014 -0700 @@ -48,7 +48,6 @@ import com.oracle.graal.nodes.type.*; import com.oracle.graal.options.*; import com.oracle.graal.phases.common.*; -import com.oracle.graal.phases.util.*; import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.Snippet.ConstantParameter; import com.oracle.graal.replacements.Snippet.Fold; @@ -417,8 +416,8 @@ private final boolean useFastLocking; - public Templates(Providers providers, TargetDescription target, boolean useFastLocking) { - super(providers, target); + public Templates(HotSpotProviders providers, TargetDescription target, boolean useFastLocking) { + super(providers, providers.getSnippetReflection(), target); this.useFastLocking = useFastLocking; } @@ -508,7 +507,7 @@ for (ReturnNode ret : rets) { returnType = checkCounter.getMethod().getSignature().getReturnType(checkCounter.getMethod().getDeclaringClass()); String msg = "unbalanced monitors in " + MetaUtil.format("%H.%n(%p)", graph.method()) + ", count = %d"; - ConstantNode errMsg = ConstantNode.forObject(msg, providers.getMetaAccess(), graph); + ConstantNode errMsg = ConstantNode.forConstant(HotSpotObjectConstant.forObject(msg), providers.getMetaAccess(), graph); callTarget = graph.add(new MethodCallTargetNode(InvokeKind.Static, checkCounter.getMethod(), new ValueNode[]{errMsg}, returnType)); invoke = graph.add(new InvokeNode(callTarget, 0)); List stack = Collections.emptyList(); diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java Mon Apr 07 16:09:17 2014 -0700 @@ -48,7 +48,6 @@ import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; import com.oracle.graal.options.*; -import com.oracle.graal.phases.util.*; import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.Snippet.ConstantParameter; import com.oracle.graal.replacements.Snippet.Fold; @@ -382,8 +381,8 @@ private final SnippetInfo allocateInstanceDynamic = snippet(NewObjectSnippets.class, "allocateInstanceDynamic"); private final SnippetInfo newmultiarray = snippet(NewObjectSnippets.class, "newmultiarray"); - public Templates(Providers providers, TargetDescription target) { - super(providers, target); + public Templates(HotSpotProviders providers, TargetDescription target) { + super(providers, providers.getSnippetReflection(), target); } /** diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NodeClassSubstitutions.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NodeClassSubstitutions.java Mon Apr 07 16:09:17 2014 -0700 @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.hotspot.replacements; + +import static com.oracle.graal.phases.GraalOptions.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.replacements.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.replacements.nodes.*; + +/** + * Substitutions for improving the performance of some critical methods in {@link NodeClass} + * methods. + */ +@ClassSubstitution(NodeClass.class) +public class NodeClassSubstitutions { + + /** + * A macro node for calls to {@link NodeClass#get(Class)}. It can use the compiler's knowledge + * about node classes to replace itself with a constant value for a constant {@link Class} + * parameter. + */ + public static class NodeClassGetNode extends PureFunctionMacroNode { + + public NodeClassGetNode(Invoke invoke) { + super(invoke); + } + + @Override + protected Constant evaluate(Constant param, MetaAccessProvider metaAccess) { + if (param.isNull() || ImmutableCode.getValue()) { + return null; + } + return HotSpotObjectConstant.forObject(NodeClass.get((Class) HotSpotObjectConstant.asObject(param))); + } + } + + @MacroSubstitution(isStatic = true, forced = true, macro = NodeClassGetNode.class) + private static native NodeClass get(Class c); +} diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ReflectionGetCallerClassNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ReflectionGetCallerClassNode.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ReflectionGetCallerClassNode.java Mon Apr 07 16:09:17 2014 -0700 @@ -93,7 +93,7 @@ if (!method.ignoredBySecurityStackWalk()) { // We have reached the desired frame; return the holder class. HotSpotResolvedObjectType callerClass = method.getDeclaringClass(); - return ConstantNode.forObject(callerClass.mirror(), metaAccess, graph()); + return ConstantNode.forConstant(HotSpotObjectConstant.forObject(callerClass.mirror()), metaAccess, graph()); } break; } diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/SystemIdentityHashCodeNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/SystemIdentityHashCodeNode.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/SystemIdentityHashCodeNode.java Mon Apr 07 16:09:17 2014 -0700 @@ -25,6 +25,7 @@ import static com.oracle.graal.phases.GraalOptions.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.nodes.*; import com.oracle.graal.replacements.nodes.*; @@ -36,6 +37,6 @@ @Override protected Constant evaluate(Constant param, MetaAccessProvider metaAccess) { - return ImmutableCode.getValue() || param.isNull() ? null : Constant.forInt(System.identityHashCode(param.asObject())); + return ImmutableCode.getValue() || param.isNull() ? null : Constant.forInt(System.identityHashCode(HotSpotObjectConstant.asObject(param))); } } diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeArrayCopySnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeArrayCopySnippets.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeArrayCopySnippets.java Mon Apr 07 16:09:17 2014 -0700 @@ -31,10 +31,10 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.*; +import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.phases.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.phases.util.*; import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.Snippet.Fold; import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates; @@ -249,8 +249,8 @@ private final SnippetInfo[] arraycopySnippets; private final SnippetInfo genericPrimitiveSnippet; - public Templates(Providers providers, TargetDescription target) { - super(providers, target); + public Templates(HotSpotProviders providers, TargetDescription target) { + super(providers, providers.getSnippetReflection(), target); arraycopySnippets = new SnippetInfo[Kind.values().length]; arraycopySnippets[Kind.Boolean.ordinal()] = snippet(UnsafeArrayCopySnippets.class, "arraycopyBoolean"); diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeLoadSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeLoadSnippets.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeLoadSnippets.java Mon Apr 07 16:09:17 2014 -0700 @@ -26,10 +26,10 @@ import static com.oracle.graal.replacements.SnippetTemplate.*; import com.oracle.graal.api.code.*; +import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.nodes.HeapAccess.BarrierType; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.phases.util.*; import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates; import com.oracle.graal.replacements.SnippetTemplate.Arguments; @@ -52,8 +52,8 @@ private final SnippetInfo unsafeLoad = snippet(UnsafeLoadSnippets.class, "lowerUnsafeLoad"); - public Templates(Providers providers, TargetDescription target) { - super(providers, target); + public Templates(HotSpotProviders providers, TargetDescription target) { + super(providers, providers.getSnippetReflection(), target); } public void lower(UnsafeLoadNode load, LoweringTool tool) { diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java Mon Apr 07 16:09:17 2014 -0700 @@ -40,7 +40,6 @@ import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.phases.*; -import com.oracle.graal.phases.util.*; import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.Snippet.ConstantParameter; import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates; @@ -334,8 +333,8 @@ private final CompressEncoding oopEncoding; - public Templates(Providers providers, TargetDescription target, CompressEncoding oopEncoding) { - super(providers, target); + public Templates(HotSpotProviders providers, TargetDescription target, CompressEncoding oopEncoding) { + super(providers, providers.getSnippetReflection(), target); this.oopEncoding = oopEncoding; } diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java Mon Apr 07 16:09:17 2014 -0700 @@ -203,8 +203,8 @@ Debug.dump(graph, "Initial stub graph"); } - kit.rewriteWordTypes(); - kit.inlineInvokes(); + kit.rewriteWordTypes(providers.getSnippetReflection()); + kit.inlineInvokes(providers.getSnippetReflection()); if (Debug.isDumpEnabled()) { Debug.dump(graph, "Stub graph before compilation"); diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java Mon Apr 07 16:09:17 2014 -0700 @@ -65,7 +65,7 @@ // convert the hub (i.e., Klass*) for int[] to be a naked word. This should be safe since // the int[] class will never be unloaded. Constant intArrayHub = intArrayType.klass(); - intArrayHub = Constant.forIntegerKind(runtime().getTarget().wordKind, intArrayHub.asLong(), null); + intArrayHub = Constant.forIntegerKind(runtime().getTarget().wordKind, intArrayHub.asLong()); Arguments args = new Arguments(stub, GuardsStage.FLOATING_GUARDS, LoweringTool.StandardLoweringStage.HIGH_TIER); args.add("hub", null); diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java Mon Apr 07 16:09:17 2014 -0700 @@ -65,7 +65,7 @@ // convert the hub (i.e., Klass*) for int[] to be a naked word. This should be safe since // the int[] class will never be unloaded. Constant intArrayHub = intArrayType.klass(); - intArrayHub = Constant.forIntegerKind(runtime().getTarget().wordKind, intArrayHub.asLong(), null); + intArrayHub = Constant.forIntegerKind(runtime().getTarget().wordKind, intArrayHub.asLong()); Arguments args = new Arguments(stub, GuardsStage.FLOATING_GUARDS, LoweringTool.StandardLoweringStage.HIGH_TIER); args.add("hub", null); diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/SnippetStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/SnippetStub.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/SnippetStub.java Mon Apr 07 16:09:17 2014 -0700 @@ -32,7 +32,6 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.StructuredGraph.GuardsStage; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.phases.util.*; import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates; import com.oracle.graal.replacements.SnippetTemplate.Arguments; @@ -45,8 +44,8 @@ static class Template extends AbstractTemplates { - Template(Providers providers, TargetDescription target, Class declaringClass) { - super(providers, target); + Template(HotSpotProviders providers, TargetDescription target, Class declaringClass) { + super(providers, providers.getSnippetReflection(), target); this.info = snippet(declaringClass, null); } @@ -65,7 +64,7 @@ /** * Creates a new snippet stub. - * + * * @param linkage linkage details for a call to the stub */ public SnippetStub(HotSpotProviders providers, TargetDescription target, HotSpotForeignCallLinkage linkage) { diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.java.decompiler/src/com/oracle/graal/java/decompiler/lines/DecompilerSyntaxLine.java --- a/graal/com.oracle.graal.java.decompiler/src/com/oracle/graal/java/decompiler/lines/DecompilerSyntaxLine.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.java.decompiler/src/com/oracle/graal/java/decompiler/lines/DecompilerSyntaxLine.java Mon Apr 07 16:09:17 2014 -0700 @@ -48,7 +48,7 @@ protected static String getStringRepresentation(Node node) { if (node instanceof ConstantNode) { - return String.valueOf(((ConstantNode) node).asConstant().asBoxedValue()); + return ((ConstantNode) node).asConstant().toValueString(); } else if (node instanceof ParameterNode) { return "param_" + ((ParameterNode) node).index(); } else { diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java Mon Apr 07 16:09:17 2014 -0700 @@ -712,13 +712,6 @@ protected abstract void emitNullCheck(T receiver); - protected static final ArrayIndexOutOfBoundsException cachedArrayIndexOutOfBoundsException = new ArrayIndexOutOfBoundsException(); - protected static final NullPointerException cachedNullPointerException = new NullPointerException(); - static { - cachedArrayIndexOutOfBoundsException.setStackTrace(new StackTraceElement[0]); - cachedNullPointerException.setStackTrace(new StackTraceElement[0]); - } - protected abstract void emitBoundsCheck(T index, T length); private static final DebugMetric EXPLICIT_EXCEPTIONS = Debug.metric("ExplicitExceptions"); diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.java/src/com/oracle/graal/java/BytecodeDisassembler.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/BytecodeDisassembler.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/BytecodeDisassembler.java Mon Apr 07 16:09:17 2014 -0700 @@ -117,26 +117,7 @@ String desc = null; if (constant instanceof Constant) { Constant c = ((Constant) constant); - switch (c.getKind()) { - case Int : - desc = String.valueOf(c.asInt()); - break; - case Float: - desc = String.valueOf(c.asFloat()); - break; - case Object: - desc = Kind.Object.format(c.asObject()); - break; - case Double : - desc = String.valueOf(c.asDouble()); - break; - case Long : - desc = String.valueOf(c.asLong()); - break; - default: - desc = c.toString(); - break; - } + desc = c.toValueString(); } else { desc = constant.toString(); } diff -r ff5660822992 -r db4254246f9a 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 Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Mon Apr 07 16:09:17 2014 -0700 @@ -25,7 +25,6 @@ import static com.oracle.graal.api.meta.DeoptimizationAction.*; import static com.oracle.graal.api.meta.DeoptimizationReason.*; import static com.oracle.graal.bytecode.Bytecodes.*; -import static com.oracle.graal.java.GraphBuilderPhase.RuntimeCalls.*; import static com.oracle.graal.phases.GraalOptions.*; import static java.lang.reflect.Modifier.*; @@ -59,12 +58,6 @@ */ public class GraphBuilderPhase extends BasePhase { - public static final class RuntimeCalls { - - public static final ForeignCallDescriptor CREATE_NULL_POINTER_EXCEPTION = new ForeignCallDescriptor("createNullPointerException", NullPointerException.class); - public static final ForeignCallDescriptor CREATE_OUT_OF_BOUNDS_EXCEPTION = new ForeignCallDescriptor("createOutOfBoundsException", ArrayIndexOutOfBoundsException.class, int.class); - } - private final GraphBuilderConfiguration graphBuilderConfig; public GraphBuilderPhase(GraphBuilderConfiguration graphBuilderConfig) { @@ -650,16 +643,10 @@ append(new IfNode(currentGraph.unique(new IsNullNode(receiver)), trueSucc, falseSucc, 0.01)); lastInstr = falseSucc; - if (OmitHotExceptionStacktrace.getValue()) { - ValueNode exception = ConstantNode.forObject(cachedNullPointerException, metaAccess, currentGraph); - trueSucc.setNext(handleException(exception, bci())); - } else { - DeferredForeignCallNode call = currentGraph.add(new DeferredForeignCallNode(CREATE_NULL_POINTER_EXCEPTION)); - call.setStamp(StampFactory.exactNonNull(metaAccess.lookupJavaType(CREATE_NULL_POINTER_EXCEPTION.getResultType()))); - call.setStateAfter(frameState.create(bci())); - trueSucc.setNext(call); - call.setNext(handleException(call, bci())); - } + BytecodeExceptionNode exception = currentGraph.add(new BytecodeExceptionNode(metaAccess, NullPointerException.class)); + exception.setStateAfter(frameState.create(bci())); + trueSucc.setNext(exception); + exception.setNext(handleException(exception, bci())); } @Override @@ -669,16 +656,10 @@ append(new IfNode(currentGraph.unique(new IntegerBelowThanNode(index, length)), trueSucc, falseSucc, 0.99)); lastInstr = trueSucc; - if (OmitHotExceptionStacktrace.getValue()) { - ValueNode exception = ConstantNode.forObject(cachedArrayIndexOutOfBoundsException, metaAccess, currentGraph); - falseSucc.setNext(handleException(exception, bci())); - } else { - DeferredForeignCallNode call = currentGraph.add(new DeferredForeignCallNode(CREATE_OUT_OF_BOUNDS_EXCEPTION, index)); - call.setStamp(StampFactory.exactNonNull(metaAccess.lookupJavaType(CREATE_OUT_OF_BOUNDS_EXCEPTION.getResultType()))); - call.setStateAfter(frameState.create(bci())); - falseSucc.setNext(call); - call.setNext(handleException(call, bci())); - } + BytecodeExceptionNode exception = currentGraph.add(new BytecodeExceptionNode(metaAccess, ArrayIndexOutOfBoundsException.class, index)); + exception.setStateAfter(frameState.create(bci())); + falseSucc.setNext(exception); + exception.setNext(handleException(exception, bci())); } @Override @@ -720,9 +701,9 @@ @Override protected void genInvokeDynamic(JavaMethod target) { if (target instanceof ResolvedJavaMethod) { - Object appendix = constantPool.lookupAppendix(stream.readCPI4(), Bytecodes.INVOKEDYNAMIC); + Constant appendix = constantPool.lookupAppendix(stream.readCPI4(), Bytecodes.INVOKEDYNAMIC); if (appendix != null) { - frameState.apush(ConstantNode.forObject(appendix, metaAccess, currentGraph)); + frameState.apush(ConstantNode.forConstant(appendix, metaAccess, currentGraph)); } ValueNode[] args = frameState.popArguments(target.getSignature().getParameterSlots(false), target.getSignature().getParameterCount(false)); appendInvoke(InvokeKind.Static, (ResolvedJavaMethod) target, args); @@ -742,9 +723,9 @@ * +and+invokedynamic */ boolean hasReceiver = !isStatic(((ResolvedJavaMethod) target).getModifiers()); - Object appendix = constantPool.lookupAppendix(stream.readCPI(), Bytecodes.INVOKEVIRTUAL); + Constant appendix = constantPool.lookupAppendix(stream.readCPI(), Bytecodes.INVOKEVIRTUAL); if (appendix != null) { - frameState.apush(ConstantNode.forObject(appendix, metaAccess, currentGraph)); + frameState.apush(ConstantNode.forConstant(appendix, metaAccess, currentGraph)); } ValueNode[] args = frameState.popArguments(target.getSignature().getParameterSlots(hasReceiver), target.getSignature().getParameterCount(hasReceiver)); if (hasReceiver) { diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/JTTTest.java --- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/JTTTest.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/JTTTest.java Mon Apr 07 16:09:17 2014 -0700 @@ -64,7 +64,7 @@ assert parameterTypes.length == args.length; for (int i = 0; i < args.length; i++) { ParameterNode param = graph.getParameter(i); - Constant c = Constant.forBoxed(parameterTypes[i].getKind(), args[i]); + Constant c = getSnippetReflection().forBoxed(parameterTypes[i].getKind(), args[i]); ConstantNode replacement = ConstantNode.forConstant(c, getMetaAccess(), graph); param.replaceAtUsages(replacement); } diff -r ff5660822992 -r db4254246f9a 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 Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java Mon Apr 07 16:09:17 2014 -0700 @@ -262,18 +262,6 @@ return unique(graph, createPrimitive(Constant.forInt(i))); } - /** - * Returns a node for an object constant. - * - * @param o the object value for which to create the instruction - * @return a node representing the object - */ - public static ConstantNode forObject(Object o, MetaAccessProvider metaAccess, StructuredGraph graph) { - assert !(o instanceof Constant) : "wrapping a Constant into a Constant"; - Constant constant = Constant.forObject(o); - return unique(graph, new ConstantNode(constant, StampFactory.forConstant(constant, metaAccess))); - } - private static ConstantNode unique(StructuredGraph graph, ConstantNode node) { return graph.unique(node); } @@ -351,7 +339,7 @@ case Long: return ConstantNode.forLong(0L, graph); case Object: - return ConstantNode.forObject(null, null, graph); + return ConstantNode.forConstant(Constant.NULL_OBJECT, null, graph); default: return null; } @@ -360,14 +348,14 @@ @Override public Map getDebugProperties(Map map) { Map properties = super.getDebugProperties(map); - properties.put("rawvalue", value.getKind() == Kind.Object ? value.getKind().format(value.asBoxedValue()) : value.asBoxedValue()); + properties.put("rawvalue", value.toValueString()); return properties; } @Override public String toString(Verbosity verbosity) { if (verbosity == Verbosity.Name) { - return super.toString(Verbosity.Name) + "(" + value.getKind().format(value.asBoxedValue()) + ")"; + return super.toString(Verbosity.Name) + "(" + value.toValueString() + ")"; } else { return super.toString(verbosity); } diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ObjectEqualsNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ObjectEqualsNode.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ObjectEqualsNode.java Mon Apr 07 16:09:17 2014 -0700 @@ -75,9 +75,9 @@ private void virtualizeNonVirtualComparison(State state, ValueNode other, VirtualizerTool tool) { if (!state.getVirtualObject().hasIdentity() && state.getVirtualObject().entryKind(0) == Kind.Boolean) { if (other.isConstant()) { - Object otherValue = other.asConstant().asObject(); - if (otherValue == Boolean.TRUE || otherValue == Boolean.FALSE) { - int expectedValue = (otherValue == Boolean.TRUE) ? 1 : 0; + Constant otherUnboxed = tool.getConstantReflectionProvider().unboxPrimitive(other.asConstant()); + if (otherUnboxed != null && otherUnboxed.getKind() == Kind.Boolean) { + int expectedValue = otherUnboxed.asBoolean() ? 1 : 0; IntegerEqualsNode equals = new IntegerEqualsNode(state.getEntry(0), ConstantNode.forInt(expectedValue, graph())); tool.addNode(equals); tool.replaceWithValue(equals); diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BytecodeExceptionNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BytecodeExceptionNode.java Mon Apr 07 16:09:17 2014 -0700 @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.nodes.extended; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; + +/** + * A node that represents an exception thrown implicitly by a Java bytecode. It can be lowered to + * either a {@linkplain ForeignCallDescriptor foreign} call or a pre-allocated exception object. + */ +public class BytecodeExceptionNode extends AbstractMemoryCheckpoint implements Lowerable, MemoryCheckpoint.Single { + + private final Class exceptionClass; + @Input private final NodeInputList arguments; + @Input private FrameState deoptState; + + public BytecodeExceptionNode(MetaAccessProvider metaAccess, Class exceptionClass, ValueNode... arguments) { + super(StampFactory.exactNonNull(metaAccess.lookupJavaType(exceptionClass))); + this.exceptionClass = exceptionClass; + this.arguments = new NodeInputList<>(this, arguments); + } + + public Class getExceptionClass() { + return exceptionClass; + } + + @Override + public String toString(Verbosity verbosity) { + if (verbosity == Verbosity.Name) { + return super.toString(verbosity) + "#" + exceptionClass.getSimpleName(); + } + return super.toString(verbosity); + } + + public LocationIdentity getLocationIdentity() { + return LocationIdentity.ANY_LOCATION; + } + + public void lower(LoweringTool tool) { + tool.getLowerer().lower(this, tool); + } + + public NodeInputList getArguments() { + return arguments; + } +} diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/DeferredForeignCallNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/DeferredForeignCallNode.java Mon Apr 07 23:35:41 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.nodes.extended; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; - -/** - * A node that will be lowered to a {@linkplain ForeignCallDescriptor foreign} call. - */ -@NodeInfo(nameTemplate = "DeferredForeignCall#{p#descriptor/s}") -public class DeferredForeignCallNode extends AbstractMemoryCheckpoint implements Lowerable, MemoryCheckpoint.Single { - - @Input private final NodeInputList arguments; - @Input(InputType.State) private FrameState deoptState; - - private final ForeignCallDescriptor descriptor; - - public DeferredForeignCallNode(ForeignCallDescriptor descriptor, ValueNode... arguments) { - super(StampFactory.forKind(Kind.fromJavaClass(descriptor.getResultType()))); - this.arguments = new NodeInputList<>(this, arguments); - this.descriptor = descriptor; - } - - public ForeignCallDescriptor getDescriptor() { - return descriptor; - } - - @Override - public String toString(Verbosity verbosity) { - if (verbosity == Verbosity.Name) { - return super.toString(verbosity) + "#" + descriptor; - } - return super.toString(verbosity); - } - - public LocationIdentity getLocationIdentity() { - return LocationIdentity.ANY_LOCATION; - } - - public void lower(LoweringTool tool) { - tool.getLowerer().lower(this, tool); - } - - public NodeInputList getArguments() { - return arguments; - } -} diff -r ff5660822992 -r db4254246f9a 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 Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Mon Apr 07 16:09:17 2014 -0700 @@ -95,21 +95,11 @@ location instanceof ConstantLocationNode) { long displacement = ((ConstantLocationNode) location).getDisplacement(); Kind kind = location.getValueKind(); - if (object.getKind() == Kind.Object) { - Object base = object.asConstant().asObject(); - if (base != null) { - Constant constant = tool.getConstantReflection().readUnsafeConstant(kind, base, displacement, compressible); - if (constant != null) { - return ConstantNode.forConstant(constant, metaAccess, read.graph()); - } - } - } else if (object.getKind().isNumericInteger()) { - long base = object.asConstant().asLong(); - if (base != 0L) { - Constant constant = tool.getConstantReflection().readUnsafeConstant(kind, null, base + displacement, compressible); - if (constant != null) { - return ConstantNode.forConstant(constant, metaAccess, read.graph()); - } + Constant base = object.asConstant(); + if (base != null) { + Constant constant = tool.getConstantReflection().readUnsafeConstant(kind, base, displacement, compressible); + if (constant != null) { + return ConstantNode.forConstant(constant, metaAccess, read.graph()); } } } diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SnippetLocationNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SnippetLocationNode.java Mon Apr 07 23:35:41 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2013, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.nodes.extended; - -import static com.oracle.graal.api.meta.LocationIdentity.*; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; -import com.oracle.graal.graph.spi.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; - -/** - * Location node that can be used inside a snippet without having the elements (including the - * location identity and kind) as a snippet constant. Can represent locations in the form of [base + - * index * scale + disp]. When the location is created, all elements (base, index, scale, disp) are - * nodes. Both scale and disp must eventually canonicalize to {@link ConstantNode constants} so that - * this node can be canonicalized to a {@link IndexedLocationNode} or {@link ConstantLocationNode}. - */ -public final class SnippetLocationNode extends LocationNode implements Canonicalizable { - - @Input private ValueNode valueKind; - @Input(InputType.Association) private ValueNode locationIdentity; - @Input private ValueNode displacement; - @Input private ValueNode index; - @Input private ValueNode indexScaling; - - public static SnippetLocationNode create(ValueNode identity, ValueNode kind, ValueNode displacement, ValueNode index, ValueNode indexScaling, Graph graph) { - return graph.unique(new SnippetLocationNode(identity, kind, displacement, index, indexScaling)); - } - - private SnippetLocationNode(ValueNode locationIdentity, ValueNode kind, ValueNode displacement) { - this(locationIdentity, kind, displacement, null, null); - } - - private SnippetLocationNode(ValueNode locationIdentity, ValueNode kind, ValueNode displacement, ValueNode index, ValueNode indexScaling) { - super(StampFactory.object()); - this.valueKind = kind; - this.locationIdentity = locationIdentity; - this.displacement = displacement; - this.index = index; - this.indexScaling = indexScaling; - } - - @Override - public Kind getValueKind() { - if (valueKind.isConstant()) { - return (Kind) valueKind.asConstant().asObject(); - } - throw new GraalInternalError("Cannot access kind yet because it is not constant: " + valueKind); - } - - @Override - public LocationIdentity getLocationIdentity() { - if (locationIdentity.isConstant()) { - return (LocationIdentity) locationIdentity.asConstant().asObject(); - } - // We do not know our actual location identity yet, so be conservative. - return ANY_LOCATION; - } - - @Override - public Node canonical(CanonicalizerTool tool) { - if (valueKind.isConstant() && locationIdentity.isConstant() && displacement.isConstant() && (indexScaling == null || indexScaling.isConstant())) { - Kind constKind = (Kind) valueKind.asConstant().asObject(); - LocationIdentity constLocation = (LocationIdentity) locationIdentity.asConstant().asObject(); - long constDisplacement = displacement.asConstant().asLong(); - int constIndexScaling = indexScaling == null ? 0 : indexScaling.asConstant().asInt(); - - if (index == null || constIndexScaling == 0) { - return ConstantLocationNode.create(constLocation, constKind, constDisplacement, graph()); - } else if (index.isConstant()) { - return ConstantLocationNode.create(constLocation, constKind, index.asConstant().asLong() * constIndexScaling + constDisplacement, graph()); - } else { - return IndexedLocationNode.create(constLocation, constKind, constDisplacement, index, graph(), constIndexScaling); - } - } - return this; - } - - @Override - public Value generateAddress(NodeLIRBuilderTool gen, Value base) { - throw new GraalInternalError("locationIdentity must be a constant so that this node can be canonicalized: " + locationIdentity); - } - - @NodeIntrinsic - public static native Location constantLocation(LocationIdentity identity, Kind kind, long displacement); - - @NodeIntrinsic - public static native Location indexedLocation(LocationIdentity identity, Kind kind, long displacement, int index, int indexScaling); -} diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnboxNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnboxNode.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnboxNode.java Mon Apr 07 16:09:17 2014 -0700 @@ -70,28 +70,9 @@ public Node canonical(CanonicalizerTool tool) { if (value.isConstant()) { Constant constant = value.asConstant(); - Object o = constant.asObject(); - if (o != null) { - switch (boxingKind) { - case Boolean: - return ConstantNode.forBoolean((Boolean) o, graph()); - case Byte: - return ConstantNode.forByte((Byte) o, graph()); - case Char: - return ConstantNode.forChar((Character) o, graph()); - case Short: - return ConstantNode.forShort((Short) o, graph()); - case Int: - return ConstantNode.forInt((Integer) o, graph()); - case Long: - return ConstantNode.forLong((Long) o, graph()); - case Float: - return ConstantNode.forFloat((Float) o, graph()); - case Double: - return ConstantNode.forDouble((Double) o, graph()); - default: - ValueNodeUtil.shouldNotReachHere(); - } + Constant unboxed = tool.getConstantReflection().unboxPrimitive(constant); + if (unboxed != null && unboxed.getKind() == boxingKind) { + return ConstantNode.forConstant(unboxed, tool.getMetaAccess(), graph()); } } else if (value instanceof BoxNode) { BoxNode box = (BoxNode) value; diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ArrayLengthNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ArrayLengthNode.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ArrayLengthNode.java Mon Apr 07 16:09:17 2014 -0700 @@ -72,7 +72,7 @@ if (constantReflection != null && array.isConstant() && !array.isNullConstant()) { Constant constantValue = array.asConstant(); if (constantValue != null && constantValue.isNonNull()) { - Integer constantLength = constantReflection.lookupArrayLength(constantValue); + Integer constantLength = constantReflection.readArrayLength(constantValue); if (constantLength != null) { return ConstantNode.forInt(constantLength, graph); } diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastDynamicNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastDynamicNode.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastDynamicNode.java Mon Apr 07 16:09:17 2014 -0700 @@ -76,10 +76,11 @@ if (ObjectStamp.isObjectAlwaysNull(object())) { return object(); } - if (hub.isConstant() && hub.asConstant().getKind() == Kind.Object && hub.asConstant().asObject() instanceof Class) { - Class clazz = (Class) hub.asConstant().asObject(); - ResolvedJavaType t = tool.getMetaAccess().lookupJavaType(clazz); - return graph().add(new CheckCastNode(t, object(), null, forStoreCheck)); + if (hub.isConstant()) { + ResolvedJavaType t = tool.getConstantReflection().asJavaType(hub.asConstant()); + if (t != null) { + return graph().add(new CheckCastNode(t, object(), null, forStoreCheck)); + } } return this; } diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/DynamicNewArrayNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/DynamicNewArrayNode.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/DynamicNewArrayNode.java Mon Apr 07 16:09:17 2014 -0700 @@ -55,9 +55,8 @@ @Override public void simplify(SimplifierTool tool) { if (isAlive() && elementType.isConstant()) { - Class elementClass = (Class) elementType.asConstant().asObject(); - if (elementClass != null && !(elementClass.equals(void.class))) { - ResolvedJavaType javaType = tool.getMetaAccess().lookupJavaType(elementClass); + ResolvedJavaType javaType = tool.getConstantReflection().asJavaType(elementType.asConstant()); + if (javaType != null && !javaType.equals(tool.getMetaAccess().lookupJavaType(void.class))) { NewArrayNode newArray = graph().add(new NewArrayNode(javaType, length(), fillContents())); List snapshot = inputs().snapshot(); graph().replaceFixedWithFixed(this, newArray); diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/DynamicNewInstanceNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/DynamicNewInstanceNode.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/DynamicNewInstanceNode.java Mon Apr 07 16:09:17 2014 -0700 @@ -40,13 +40,9 @@ @Override public Node canonical(CanonicalizerTool tool) { if (clazz.isConstant()) { - Constant clazzConstant = clazz.asConstant(); - if (clazzConstant.getKind() == Kind.Object && clazzConstant.asObject() instanceof Class) { - Class staticClass = (Class) clazzConstant.asObject(); - ResolvedJavaType type = tool.getMetaAccess().lookupJavaType(staticClass); - if (type.isInitialized()) { - return graph().add(new NewInstanceNode(type, fillContents())); - } + ResolvedJavaType type = tool.getConstantReflection().asJavaType(clazz.asConstant()); + if (type != null && type.isInitialized()) { + return graph().add(new NewInstanceNode(type, fillContents())); } } return this; diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfDynamicNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfDynamicNode.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfDynamicNode.java Mon Apr 07 16:09:17 2014 -0700 @@ -60,12 +60,13 @@ public Node canonical(CanonicalizerTool tool) { assert object() != null : this; if (mirror().isConstant()) { - Class clazz = (Class) mirror().asConstant().asObject(); - ResolvedJavaType t = tool.getMetaAccess().lookupJavaType(clazz); - if (t.isPrimitive()) { - return LogicConstantNode.contradiction(graph()); - } else { - return graph().unique(new InstanceOfNode(t, object(), null)); + ResolvedJavaType t = tool.getConstantReflection().asJavaType(mirror().asConstant()); + if (t != null) { + if (t.isPrimitive()) { + return LogicConstantNode.contradiction(graph()); + } else { + return graph().unique(new InstanceOfNode(t, object(), null)); + } } } return this; diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/VirtualizerTool.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/VirtualizerTool.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/VirtualizerTool.java Mon Apr 07 16:09:17 2014 -0700 @@ -41,12 +41,17 @@ public interface VirtualizerTool { /** - * @return the {@link MetaAccessProvider} associated with the current compilation, which might - * be required for creating constants, etc. + * @return the {@link MetaAccessProvider} associated with the current compilation. */ MetaAccessProvider getMetaAccessProvider(); /** + * @return the {@link ConstantReflectionProvider} associated with the current compilation, which + * can be used to access {@link Constant}s. + */ + ConstantReflectionProvider getConstantReflectionProvider(); + + /** * @return the {@link Assumptions} associated with the current compilation, which can be used to * make type assumptions during virtualization. */ diff -r ff5660822992 -r db4254246f9a 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 Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java Mon Apr 07 16:09:17 2014 -0700 @@ -710,7 +710,7 @@ replacementAnchor = BeginNode.prevBegin(checkCast); PiNode piNode; if (isNull) { - ConstantNode nullObject = ConstantNode.forObject(null, metaAccess, graph); + ConstantNode nullObject = ConstantNode.defaultForKind(Kind.Object, graph); piNode = graph.unique(new PiNode(nullObject, StampFactory.forConstant(nullObject.getValue(), metaAccess), replacementAnchor.asNode())); } else { piNode = graph.unique(new PiNode(object, StampFactory.declared(type, nonNull), replacementAnchor.asNode())); diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64ConvertSnippets.java --- a/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64ConvertSnippets.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64ConvertSnippets.java Mon Apr 07 16:09:17 2014 -0700 @@ -26,6 +26,7 @@ import static com.oracle.graal.replacements.SnippetTemplate.*; import com.oracle.graal.api.code.*; +import com.oracle.graal.api.replacements.*; import com.oracle.graal.debug.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; @@ -49,7 +50,7 @@ * conversion. If the float value is a NaN, infinity or if the result of the conversion is * larger than {@link Integer#MAX_VALUE} then CVTTSS2SI returns {@link Integer#MIN_VALUE} and * extra tests are required on the float value to return the correct int value. - * + * * @param input the float being converted * @param result the result produced by the CVTTSS2SI instruction */ @@ -74,7 +75,7 @@ * conversion. If the float value is a NaN or infinity then CVTTSS2SI returns * {@link Long#MIN_VALUE} and extra tests are required on the float value to return the correct * long value. - * + * * @param input the float being converted * @param result the result produced by the CVTTSS2SI instruction */ @@ -99,7 +100,7 @@ * conversion. If the double value is a NaN, infinity or if the result of the conversion is * larger than {@link Integer#MAX_VALUE} then CVTTSD2SI returns {@link Integer#MIN_VALUE} and * extra tests are required on the double value to return the correct int value. - * + * * @param input the double being converted * @param result the result produced by the CVTTSS2SI instruction */ @@ -124,7 +125,7 @@ * conversion. If the double value is a NaN, infinity or if the result of the conversion is * larger than {@link Long#MAX_VALUE} then CVTTSD2SI returns {@link Long#MIN_VALUE} and extra * tests are required on the double value to return the correct long value. - * + * * @param input the double being converted * @param result the result produced by the CVTTSS2SI instruction */ @@ -149,8 +150,8 @@ private final SnippetInfo d2i; private final SnippetInfo d2l; - public Templates(Providers providers, TargetDescription target) { - super(providers, target); + public Templates(Providers providers, SnippetReflectionProvider snippetReflection, TargetDescription target) { + super(providers, snippetReflection, target); f2i = snippet(AMD64ConvertSnippets.class, "f2i"); f2l = snippet(AMD64ConvertSnippets.class, "f2l"); diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ObjectAccessTest.java --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ObjectAccessTest.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ObjectAccessTest.java Mon Apr 07 16:09:17 2014 -0700 @@ -47,7 +47,7 @@ private final ReplacementsImpl installer; public ObjectAccessTest() { - installer = new ReplacementsImpl(getProviders(), new Assumptions(false), getTarget()); + installer = new ReplacementsImpl(getProviders(), getSnippetReflection(), new Assumptions(false), getTarget()); } private static final ThreadLocal inliningPolicy = new ThreadLocal<>(); diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java Mon Apr 07 16:09:17 2014 -0700 @@ -53,7 +53,7 @@ public PointerTest() { target = getCodeCache().getTarget(); - installer = new ReplacementsImpl(getProviders(), new Assumptions(false), getTarget()); + installer = new ReplacementsImpl(getProviders(), getSnippetReflection(), new Assumptions(false), getTarget()); } private static final ThreadLocal inliningPolicy = new ThreadLocal<>(); diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/WordTest.java --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/WordTest.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/WordTest.java Mon Apr 07 16:09:17 2014 -0700 @@ -42,7 +42,7 @@ private final ReplacementsImpl installer; public WordTest() { - installer = new ReplacementsImpl(getProviders(), new Assumptions(false), getTarget()); + installer = new ReplacementsImpl(getProviders(), getSnippetReflection(), new Assumptions(false), getTarget()); } private static final ThreadLocal inliningPolicy = new ThreadLocal<>(); diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/BoxingSnippets.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/BoxingSnippets.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/BoxingSnippets.java Mon Apr 07 16:09:17 2014 -0700 @@ -30,6 +30,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.replacements.*; import com.oracle.graal.debug.*; import com.oracle.graal.graph.Node.NodeIntrinsic; import com.oracle.graal.nodes.*; @@ -173,30 +174,13 @@ return value.shortValue(); } - public static FloatingNode canonicalizeBoxing(BoxNode box, MetaAccessProvider metaAccess) { + public static FloatingNode canonicalizeBoxing(BoxNode box, MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection) { ValueNode value = box.getValue(); if (value.isConstant()) { Constant sourceConstant = value.asConstant(); - switch (box.getBoxingKind()) { - case Boolean: - return ConstantNode.forObject(Boolean.valueOf(sourceConstant.asInt() != 0), metaAccess, box.graph()); - case Byte: - return ConstantNode.forObject(Byte.valueOf((byte) sourceConstant.asInt()), metaAccess, box.graph()); - case Char: - return ConstantNode.forObject(Character.valueOf((char) sourceConstant.asInt()), metaAccess, box.graph()); - case Short: - return ConstantNode.forObject(Short.valueOf((short) sourceConstant.asInt()), metaAccess, box.graph()); - case Int: - return ConstantNode.forObject(Integer.valueOf(sourceConstant.asInt()), metaAccess, box.graph()); - case Long: - return ConstantNode.forObject(Long.valueOf(sourceConstant.asLong()), metaAccess, box.graph()); - case Float: - return ConstantNode.forObject(Float.valueOf(sourceConstant.asFloat()), metaAccess, box.graph()); - case Double: - return ConstantNode.forObject(Double.valueOf(sourceConstant.asDouble()), metaAccess, box.graph()); - default: - assert false : "Unexpected source kind for boxing"; - break; + Constant boxedConstant = constantReflection.boxPrimitive(sourceConstant); + if (boxedConstant != null && boxedConstant.getKind() == box.getBoxingKind()) { + return ConstantNode.forConstant(boxedConstant, metaAccess, box.graph()); } } return null; @@ -207,8 +191,8 @@ private final EnumMap boxSnippets = new EnumMap<>(Kind.class); private final EnumMap unboxSnippets = new EnumMap<>(Kind.class); - public Templates(Providers providers, TargetDescription target) { - super(providers, target); + public Templates(Providers providers, SnippetReflectionProvider snippetReflection, TargetDescription target) { + super(providers, snippetReflection, target); for (Kind kind : new Kind[]{Kind.Boolean, Kind.Byte, Kind.Char, Kind.Double, Kind.Float, Kind.Int, Kind.Long, Kind.Short}) { boxSnippets.put(kind, snippet(BoxingSnippets.class, kind.getJavaName() + "ValueOf")); unboxSnippets.put(kind, snippet(BoxingSnippets.class, kind.getJavaName() + "Value")); @@ -216,7 +200,7 @@ } public void lower(BoxNode box, LoweringTool tool) { - FloatingNode canonical = canonicalizeBoxing(box, providers.getMetaAccess()); + FloatingNode canonical = canonicalizeBoxing(box, providers.getMetaAccess(), providers.getConstantReflection()); // if in AOT mode, we don't want to embed boxed constants. if (canonical != null && !ImmutableCode.getValue()) { box.graph().replaceFloating(box, canonical); diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/CompositeValueClassSubstitutions.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/CompositeValueClassSubstitutions.java Mon Apr 07 23:35:41 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.replacements; - -import static com.oracle.graal.phases.GraalOptions.*; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.replacements.*; -import com.oracle.graal.lir.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.replacements.nodes.*; - -/** - * Substitutions for improving the performance of {@link CompositeValueClass#getClass()}. - */ -@ClassSubstitution(CompositeValueClass.class) -public class CompositeValueClassSubstitutions { - - /** - * A macro node for calls to {@link CompositeValueClass#get(Class)}. It can use the compiler's - * knowledge about node classes to replace itself with a constant value for a constant - * {@link Class} parameter. - */ - public static class CompositeValueClassGetNode extends PureFunctionMacroNode { - - public CompositeValueClassGetNode(Invoke invoke) { - super(invoke); - } - - @SuppressWarnings("unchecked") - @Override - protected Constant evaluate(Constant param, MetaAccessProvider metaAccess) { - if (param.isNull() || ImmutableCode.getValue()) { - return null; - } - return Constant.forObject(CompositeValueClass.get((Class) param.asObject())); - } - } - - @MacroSubstitution(isStatic = true, forced = true, macro = CompositeValueClassGetNode.class) - private static native CompositeValueClass get(Class c); -} diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraalMethodSubstitutions.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraalMethodSubstitutions.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraalMethodSubstitutions.java Mon Apr 07 16:09:17 2014 -0700 @@ -50,8 +50,6 @@ replacements.registerSubstitutions(CharacterSubstitutions.class); replacements.registerSubstitutions(ShortSubstitutions.class); replacements.registerSubstitutions(UnsignedMathSubstitutions.class); - replacements.registerSubstitutions(NodeClassSubstitutions.class); - replacements.registerSubstitutions(CompositeValueClassSubstitutions.class); } } } diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraphKit.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraphKit.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraphKit.java Mon Apr 07 16:09:17 2014 -0700 @@ -27,6 +27,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.replacements.*; import com.oracle.graal.graph.*; import com.oracle.graal.java.*; import com.oracle.graal.nodes.*; @@ -179,16 +180,16 @@ /** * Rewrite all word types in the graph. */ - public void rewriteWordTypes() { - new WordTypeRewriterPhase(providers.getMetaAccess(), providers.getCodeCache().getTarget().wordKind).apply(graph); + public void rewriteWordTypes(SnippetReflectionProvider snippetReflection) { + new WordTypeRewriterPhase(providers.getMetaAccess(), snippetReflection, providers.getCodeCache().getTarget().wordKind).apply(graph); } /** - * {@linkplain #inline(InvokeNode) Inlines} all invocations currently in the graph. + * {@linkplain #inline Inlines} all invocations currently in the graph. */ - public void inlineInvokes() { + public void inlineInvokes(SnippetReflectionProvider snippetReflection) { for (InvokeNode invoke : graph.getNodes().filter(InvokeNode.class).snapshot()) { - inline(invoke); + inline(invoke, snippetReflection); } // Clean up all code that is now dead after inlining. @@ -201,9 +202,9 @@ * {@linkplain ReplacementsImpl#makeGraph processed} in the same manner as for snippets and * method substitutions. */ - public void inline(InvokeNode invoke) { + public void inline(InvokeNode invoke, SnippetReflectionProvider snippetReflection) { ResolvedJavaMethod method = ((MethodCallTargetNode) invoke.callTarget()).targetMethod(); - ReplacementsImpl repl = new ReplacementsImpl(providers, new Assumptions(false), providers.getCodeCache().getTarget()); + ReplacementsImpl repl = new ReplacementsImpl(providers, snippetReflection, new Assumptions(false), providers.getCodeCache().getTarget()); StructuredGraph calleeGraph = repl.makeGraph(method, null, method, null, FrameStateProcessing.CollapseFrameForSingleSideEffect); InliningUtil.inline(invoke, calleeGraph, false); } diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java Mon Apr 07 16:09:17 2014 -0700 @@ -27,6 +27,7 @@ import java.util.*; import com.oracle.graal.api.code.*; +import com.oracle.graal.api.replacements.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; @@ -53,8 +54,8 @@ */ public abstract class InstanceOfSnippetsTemplates extends AbstractTemplates { - public InstanceOfSnippetsTemplates(Providers providers, TargetDescription target) { - super(providers, target); + public InstanceOfSnippetsTemplates(Providers providers, SnippetReflectionProvider snippetReflection, TargetDescription target) { + super(providers, snippetReflection, target); } /** @@ -130,7 +131,7 @@ /** * Gets the result of this instantiation as a condition. - * + * * @param testValue the returned condition is true if the result is equal to this value */ LogicNode asCondition(ValueNode testValue) { @@ -148,7 +149,7 @@ /** * Gets the result of the instantiation as a materialized value. - * + * * @param t the true value for the materialization * @param f the false value for the materialization */ diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeClassSubstitutions.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeClassSubstitutions.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeClassSubstitutions.java Mon Apr 07 16:09:17 2014 -0700 @@ -22,15 +22,11 @@ */ package com.oracle.graal.replacements; -import static com.oracle.graal.phases.GraalOptions.*; - import com.oracle.graal.api.meta.*; import com.oracle.graal.api.replacements.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.replacements.nodes.*; /** * Substitutions for improving the performance of some critical methods in {@link NodeClass} @@ -42,26 +38,6 @@ @ClassSubstitution(NodeClass.class) public class NodeClassSubstitutions { - /** - * A macro node for calls to {@link NodeClass#get(Class)}. It can use the compiler's knowledge - * about node classes to replace itself with a constant value for a constant {@link Class} - * parameter. - */ - public static class NodeClassGetNode extends PureFunctionMacroNode { - - public NodeClassGetNode(Invoke invoke) { - super(invoke); - } - - @Override - protected Constant evaluate(Constant param, MetaAccessProvider metaAccess) { - return param.isNull() || ImmutableCode.getValue() ? null : Constant.forObject(NodeClass.get((Class) param.asObject())); - } - } - - @MacroSubstitution(isStatic = true, forced = true, macro = NodeClassGetNode.class) - private static native NodeClass get(Class c); - @MethodSubstitution private static Node getNode(Node node, long offset) { return PiNode.piCast(UnsafeLoadNode.load(node, offset, Kind.Object, LocationIdentity.ANY_LOCATION), Node.class); diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java Mon Apr 07 16:09:17 2014 -0700 @@ -29,6 +29,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.replacements.*; import com.oracle.graal.debug.*; import com.oracle.graal.debug.internal.*; import com.oracle.graal.graph.*; @@ -52,9 +53,11 @@ public class NodeIntrinsificationPhase extends Phase { private final Providers providers; + private final SnippetReflectionProvider snippetReflection; - public NodeIntrinsificationPhase(Providers providers) { + public NodeIntrinsificationPhase(Providers providers, SnippetReflectionProvider snippetReflection) { this.providers = providers; + this.snippetReflection = snippetReflection; } @Override @@ -167,25 +170,25 @@ } ConstantNode constantNode = (ConstantNode) argument; Constant constant = constantNode.asConstant(); - Object o = constant.asBoxedValue(); - if (o instanceof Class) { - reflectionCallArguments[i] = Constant.forObject(providers.getMetaAccess().lookupJavaType((Class) o)); + ResolvedJavaType type = providers.getConstantReflection().asJavaType(constant); + if (type != null) { + reflectionCallArguments[i] = snippetReflection.forObject(type); parameterTypes[i] = providers.getMetaAccess().lookupJavaType(ResolvedJavaType.class); } else { if (parameterTypes[i].getKind() == Kind.Boolean) { - reflectionCallArguments[i] = Constant.forObject(Boolean.valueOf(constant.asInt() != 0)); + reflectionCallArguments[i] = snippetReflection.forObject(Boolean.valueOf(constant.asInt() != 0)); } else if (parameterTypes[i].getKind() == Kind.Byte) { - reflectionCallArguments[i] = Constant.forObject(Byte.valueOf((byte) constant.asInt())); + reflectionCallArguments[i] = snippetReflection.forObject(Byte.valueOf((byte) constant.asInt())); } else if (parameterTypes[i].getKind() == Kind.Short) { - reflectionCallArguments[i] = Constant.forObject(Short.valueOf((short) constant.asInt())); + reflectionCallArguments[i] = snippetReflection.forObject(Short.valueOf((short) constant.asInt())); } else if (parameterTypes[i].getKind() == Kind.Char) { - reflectionCallArguments[i] = Constant.forObject(Character.valueOf((char) constant.asInt())); + reflectionCallArguments[i] = snippetReflection.forObject(Character.valueOf((char) constant.asInt())); } else { reflectionCallArguments[i] = constant; } } } else { - reflectionCallArguments[i] = Constant.forObject(argument); + reflectionCallArguments[i] = snippetReflection.forObject(argument); parameterTypes[i] = providers.getMetaAccess().lookupJavaType(ValueNode.class); } } @@ -226,7 +229,7 @@ } try { - ValueNode intrinsicNode = (ValueNode) constructor.newInstance(arguments).asObject(); + ValueNode intrinsicNode = (ValueNode) snippetReflection.asObject(constructor.newInstance(arguments)); if (setStampFromReturnType) { intrinsicNode.setStamp(invokeStamp); @@ -267,11 +270,13 @@ if (getParameterAnnotation(InjectedNodeParameter.class, i, c) != null) { injected = injected == null ? new Constant[1] : Arrays.copyOf(injected, injected.length + 1); if (signature[i].equals(metaAccess.lookupJavaType(MetaAccessProvider.class))) { - injected[injected.length - 1] = Constant.forObject(metaAccess); + injected[injected.length - 1] = snippetReflection.forObject(metaAccess); } else if (signature[i].equals(metaAccess.lookupJavaType(StructuredGraph.class))) { - injected[injected.length - 1] = Constant.forObject(graph); + injected[injected.length - 1] = snippetReflection.forObject(graph); } else if (signature[i].equals(metaAccess.lookupJavaType(ForeignCallsProvider.class))) { - injected[injected.length - 1] = Constant.forObject(providers.getForeignCalls()); + injected[injected.length - 1] = snippetReflection.forObject(providers.getForeignCalls()); + } else if (signature[i].equals(metaAccess.lookupJavaType(SnippetReflectionProvider.class))) { + injected[injected.length - 1] = snippetReflection.forObject(snippetReflection); } else { throw new GraalInternalError("Cannot handle injected argument of type %s in %s", toJavaName(signature[i]), format("%H.%n(%p)", c)); } @@ -311,9 +316,9 @@ arguments = Arrays.copyOf(nodeConstructorArguments, fixedArgs + 1); arguments[fixedArgs] = componentType.newArray(nodeConstructorArguments.length - fixedArgs); - Object varargs = arguments[fixedArgs].asObject(); + Object varargs = snippetReflection.asObject(arguments[fixedArgs]); for (int i = fixedArgs; i < nodeConstructorArguments.length; i++) { - Array.set(varargs, i - fixedArgs, nodeConstructorArguments[i].asBoxedValue()); + Array.set(varargs, i - fixedArgs, snippetReflection.asBoxedValue(nodeConstructorArguments[i])); } } else { return null; diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Mon Apr 07 16:09:17 2014 -0700 @@ -56,6 +56,7 @@ public class ReplacementsImpl implements Replacements { protected final Providers providers; + protected final SnippetReflectionProvider snippetReflection; protected final TargetDescription target; protected final Assumptions assumptions; @@ -71,8 +72,9 @@ private final Set forcedSubstitutions; private final Map, SnippetTemplateCache> snippetTemplateCache; - public ReplacementsImpl(Providers providers, Assumptions assumptions, TargetDescription target) { + public ReplacementsImpl(Providers providers, SnippetReflectionProvider snippetReflection, Assumptions assumptions, TargetDescription target) { this.providers = providers.copyWith(this); + this.snippetReflection = snippetReflection; this.target = target; this.assumptions = assumptions; this.graphs = new ConcurrentHashMap<>(); @@ -121,7 +123,7 @@ // Do deferred intrinsification of node intrinsics - new NodeIntrinsificationPhase(providers).apply(specializedSnippet); + new NodeIntrinsificationPhase(providers, snippetReflection).apply(specializedSnippet); new CanonicalizerPhase(true).apply(specializedSnippet, new PhaseContext(providers, assumptions)); NodeIntrinsificationVerificationPhase.verify(specializedSnippet); } @@ -364,7 +366,7 @@ * Does final processing of a snippet graph. */ protected void finalizeGraph(StructuredGraph graph) { - new NodeIntrinsificationPhase(providers).apply(graph); + new NodeIntrinsificationPhase(providers, snippetReflection).apply(graph); if (!SnippetTemplate.hasConstantParameter(method)) { NodeIntrinsificationVerificationPhase.verify(graph); } @@ -412,8 +414,8 @@ try (Scope s = Debug.scope("buildInitialGraph", graph)) { MetaAccessProvider metaAccess = providers.getMetaAccess(); createGraphBuilder(metaAccess, GraphBuilderConfiguration.getSnippetDefault(), OptimisticOptimizations.NONE).apply(graph); - new WordTypeVerificationPhase(metaAccess, target.wordKind).apply(graph); - new WordTypeRewriterPhase(metaAccess, target.wordKind).apply(graph); + new WordTypeVerificationPhase(metaAccess, snippetReflection, target.wordKind).apply(graph); + new WordTypeRewriterPhase(metaAccess, snippetReflection, target.wordKind).apply(graph); if (OptCanonicalizer.getValue()) { new CanonicalizerPhase(true).apply(graph, new PhaseContext(providers, assumptions)); @@ -449,7 +451,7 @@ * Called after all inlining for a given graph is complete. */ protected void afterInlining(StructuredGraph graph) { - new NodeIntrinsificationPhase(providers).apply(graph); + new NodeIntrinsificationPhase(providers, snippetReflection).apply(graph); new DeadCodeEliminationPhase().apply(graph); if (OptCanonicalizer.getValue()) { new CanonicalizerPhase(true).apply(graph, new PhaseContext(providers, assumptions)); diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Mon Apr 07 16:09:17 2014 -0700 @@ -399,11 +399,13 @@ public abstract static class AbstractTemplates implements SnippetTemplateCache { protected final Providers providers; + protected final SnippetReflectionProvider snippetReflection; protected final TargetDescription target; private final ConcurrentHashMap templates; - protected AbstractTemplates(Providers providers, TargetDescription target) { + protected AbstractTemplates(Providers providers, SnippetReflectionProvider snippetReflection, TargetDescription target) { this.providers = providers; + this.snippetReflection = snippetReflection; this.target = target; if (UseSnippetTemplateCache) { this.templates = new ConcurrentHashMap<>(); @@ -443,7 +445,7 @@ if (template == null) { SnippetTemplates.increment(); try (TimerCloseable a = SnippetTemplateCreationTime.start(); Scope s = Debug.scope("SnippetSpecialization", args.info.method)) { - template = new SnippetTemplate(providers, args); + template = new SnippetTemplate(providers, snippetReflection, args); if (UseSnippetTemplateCache) { templates.put(args.cacheKey, template); } @@ -470,10 +472,14 @@ return false; } + private final SnippetReflectionProvider snippetReflection; + /** * Creates a snippet template. */ - protected SnippetTemplate(final Providers providers, Arguments args) { + protected SnippetTemplate(final Providers providers, SnippetReflectionProvider snippetReflection, Arguments args) { + this.snippetReflection = snippetReflection; + StructuredGraph snippetGraph = providers.getReplacements().getSnippet(args.info.method); instantiationTimer = Debug.timer("SnippetTemplateInstantiationTime[%#s]", args); instantiationCounter = Debug.metric("SnippetTemplateInstantiationCount[%#s]", args); @@ -502,7 +508,7 @@ if (arg instanceof Constant) { constantArg = (Constant) arg; } else { - constantArg = Constant.forBoxed(kind, arg); + constantArg = snippetReflection.forBoxed(kind, arg); } nodeReplacements.put(snippetGraph.getParameter(i), ConstantNode.forConstant(constantArg, metaAccess, snippetCopy)); } else if (args.info.isVarargsParameter(i)) { @@ -702,9 +708,7 @@ assert arg instanceof Constant : method + ": word constant parameters must be passed boxed in a Constant value: " + arg; return true; } - if (kind == Kind.Object) { - assert arg == null || type.isInstance(Constant.forObject(arg)) : method + ": wrong value type for " + name + ": expected " + type.getName() + ", got " + arg.getClass().getName(); - } else { + if (kind != Kind.Object) { assert arg != null && kind.toBoxedJavaClass() == arg.getClass() : method + ": wrong value kind for " + name + ": expected " + kind + ", got " + (arg == null ? "null" : arg.getClass().getSimpleName()); } @@ -843,20 +847,10 @@ */ protected Constant forBoxed(Object argument, Kind localKind) { assert localKind == localKind.getStackKind(); - if (localKind == Kind.Int && !(argument instanceof Integer)) { - if (argument instanceof Boolean) { - return Constant.forBoxed(Kind.Boolean, argument); - } - if (argument instanceof Byte) { - return Constant.forBoxed(Kind.Byte, argument); - } - if (argument instanceof Short) { - return Constant.forBoxed(Kind.Short, argument); - } - assert argument instanceof Character; - return Constant.forBoxed(Kind.Char, argument); + if (localKind == Kind.Int) { + return Constant.forBoxedPrimitive(argument); } - return Constant.forBoxed(localKind, argument); + return snippetReflection.forBoxed(localKind, argument); } /** diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotOptimizedCallTarget.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotOptimizedCallTarget.java Mon Apr 07 16:09:17 2014 -0700 @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.truffle.hotspot; + +import static com.oracle.graal.truffle.TruffleCompilerOptions.*; + +import java.util.concurrent.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.truffle.*; +import com.oracle.truffle.api.*; +import com.oracle.truffle.api.nodes.*; + +/** + * Call target for running truffle on a standard VM (and not in SubstrateVM). + */ +public final class HotSpotOptimizedCallTarget extends OptimizedCallTarget { + + protected final TruffleCompiler compiler; + private Future installedCodeTask; + private SpeculationLog speculationLog = new HotSpotSpeculationLog(); + + HotSpotOptimizedCallTarget(RootNode rootNode, TruffleCompiler compiler, int invokeCounter, int compilationThreshold, boolean compilationEnabled) { + super(rootNode, invokeCounter, compilationThreshold, compilationEnabled, TruffleUseTimeForCompilationDecision.getValue() ? new TimedCompilationPolicy() : new DefaultCompilationPolicy()); + this.compiler = compiler; + } + + @Override + public SpeculationLog getSpeculationLog() { + return speculationLog; + } + + public boolean isOptimized() { + return installedCode != null || installedCodeTask != null; + } + + @CompilerDirectives.SlowPath + @Override + public Object call(Object[] args) { + return CompilerDirectives.inInterpreter() ? callHelper(args) : executeHelper(args); + } + + private Object callHelper(Object[] args) { + if (installedCode != null && installedCode.isValid()) { + reinstallCallMethodShortcut(); + } + if (TruffleCallTargetProfiling.getValue()) { + callCount++; + } + if (CompilerDirectives.injectBranchProbability(CompilerDirectives.FASTPATH_PROBABILITY, installedCode != null)) { + try { + return installedCode.executeVarargs(new Object[]{this, args}); + } catch (InvalidInstalledCodeException ex) { + return compiledCodeInvalidated(args); + } + } else { + return interpreterCall(args); + } + } + + private static void reinstallCallMethodShortcut() { + if (TraceTruffleCompilation.getValue()) { + OUT.println("[truffle] reinstall OptimizedCallTarget.call code with frame prolog shortcut."); + } + HotSpotTruffleRuntime.installOptimizedCallTargetCallMethod(); + } + + private Object compiledCodeInvalidated(Object[] args) { + invalidate(null, null, "Compiled code invalidated"); + return call(args); + } + + @Override + protected void invalidate(Node oldNode, Node newNode, CharSequence reason) { + InstalledCode m = this.installedCode; + if (m != null) { + CompilerAsserts.neverPartOfCompilation(); + installedCode = null; + inliningResult = null; + compilationProfile.reportInvalidated(); + logOptimizedInvalidated(this, oldNode, newNode, reason); + } + cancelInstalledTask(oldNode, newNode, reason); + } + + @Override + protected void cancelInstalledTask(Node oldNode, Node newNode, CharSequence reason) { + Future task = this.installedCodeTask; + if (task != null) { + task.cancel(true); + this.installedCodeTask = null; + logOptimizingUnqueued(this, oldNode, newNode, reason); + compilationProfile.reportInvalidated(); + } + } + + private Object interpreterCall(Object[] args) { + CompilerAsserts.neverPartOfCompilation(); + compilationProfile.reportInterpreterCall(); + + if (compilationEnabled && compilationPolicy.shouldCompile(compilationProfile)) { + InstalledCode code = compile(); + if (code != null && code.isValid()) { + this.installedCode = code; + try { + return code.executeVarargs(new Object[]{this, args}); + } catch (InvalidInstalledCodeException ex) { + return compiledCodeInvalidated(args); + } + } + } + return executeHelper(args); + } + + private boolean isCompiling() { + Future codeTask = this.installedCodeTask; + if (codeTask != null) { + if (codeTask.isCancelled()) { + installedCodeTask = null; + return false; + } + return true; + } + return false; + } + + @Override + public InstalledCode compile() { + if (isCompiling()) { + if (installedCodeTask.isDone()) { + return receiveInstalledCode(); + } + return null; + } else { + performInlining(); + cancelInlinedCallOptimization(); + logOptimizingQueued(this); + this.installedCodeTask = compiler.compile(this); + if (!TruffleBackgroundCompilation.getValue()) { + return receiveInstalledCode(); + } + return null; + } + } + + private InstalledCode receiveInstalledCode() { + try { + return installedCodeTask.get(); + } catch (InterruptedException | ExecutionException e) { + compilationEnabled = false; + logOptimizingFailed(this, e.getMessage()); + if (e.getCause() instanceof BailoutException) { + // Bailout => move on. + } else { + if (TraceTruffleCompilationExceptions.getValue()) { + e.printStackTrace(OUT); + } + if (TruffleCompilationExceptionsAreFatal.getValue()) { + System.exit(-1); + } + } + return null; + } finally { + onCompilationDone(); + } + } + +} diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleReplacements.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleReplacements.java Mon Apr 07 16:09:17 2014 -0700 @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.truffle.hotspot; + +import com.oracle.graal.api.replacements.*; +import com.oracle.graal.api.runtime.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.phases.util.*; +import com.oracle.graal.runtime.*; +import com.oracle.graal.truffle.*; +import com.oracle.graal.truffle.hotspot.substitutions.*; + +public final class HotSpotTruffleReplacements extends TruffleReplacements { + + private HotSpotTruffleReplacements(Providers providers, SnippetReflectionProvider snippetReflection) { + super(providers, snippetReflection); + } + + public static Replacements makeInstance() { + Providers providers = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getProviders(); + SnippetReflectionProvider snippetReflection = Graal.getRequiredCapability(SnippetReflectionProvider.class); + return new HotSpotTruffleReplacements(providers, snippetReflection); + } + + @Override + protected void registerTruffleSubstitutions() { + super.registerTruffleSubstitutions(); + registerSubstitutions(HotSpotOptimizedCallTargetSubstitutions.class); + } +} diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java Mon Apr 07 16:09:17 2014 -0700 @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.truffle.hotspot; + +import static com.oracle.graal.api.code.CodeUtil.*; +import static com.oracle.graal.compiler.GraalCompiler.*; +import static com.oracle.graal.truffle.TruffleCompilerOptions.*; + +import java.lang.reflect.*; +import java.util.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.code.CallingConvention.Type; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.runtime.*; +import com.oracle.graal.compiler.target.*; +import com.oracle.graal.debug.*; +import com.oracle.graal.debug.Debug.Scope; +import com.oracle.graal.graph.*; +import com.oracle.graal.java.*; +import com.oracle.graal.lir.asm.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.phases.*; +import com.oracle.graal.phases.common.*; +import com.oracle.graal.phases.tiers.*; +import com.oracle.graal.phases.util.*; +import com.oracle.graal.runtime.*; +import com.oracle.graal.truffle.*; +import com.oracle.truffle.api.*; +import com.oracle.truffle.api.frame.*; +import com.oracle.truffle.api.impl.*; +import com.oracle.truffle.api.nodes.*; + +/** + * Implementation of the Truffle runtime when running on top of Graal. + */ +public final class HotSpotTruffleRuntime implements GraalTruffleRuntime { + + public static HotSpotTruffleRuntime makeInstance() { + return new HotSpotTruffleRuntime(); + } + + private TruffleCompiler truffleCompiler; + private Replacements truffleReplacements; + private ArrayList includes; + private ArrayList excludes; + + private HotSpotTruffleRuntime() { + installOptimizedCallTargetCallMethod(); + } + + public String getName() { + return "Graal Truffle Runtime"; + } + + public RootCallTarget createCallTarget(RootNode rootNode) { + if (truffleCompiler == null) { + truffleCompiler = new TruffleCompilerImpl(); + } + return new HotSpotOptimizedCallTarget(rootNode, truffleCompiler, TruffleMinInvokeThreshold.getValue(), TruffleCompilationThreshold.getValue(), acceptForCompilation(rootNode)); + } + + public CallNode createCallNode(CallTarget target) { + if (target instanceof OptimizedCallTarget) { + return OptimizedCallNode.create((OptimizedCallTarget) target); + } else { + return new DefaultCallNode(target); + } + } + + @Override + public VirtualFrame createVirtualFrame(Object[] arguments, FrameDescriptor frameDescriptor) { + return OptimizedCallTarget.createFrame(frameDescriptor, arguments); + } + + @Override + public MaterializedFrame createMaterializedFrame(Object[] arguments) { + return createMaterializedFrame(arguments, new FrameDescriptor()); + } + + @Override + public MaterializedFrame createMaterializedFrame(Object[] arguments, FrameDescriptor frameDescriptor) { + return new FrameWithoutBoxing(frameDescriptor, arguments); + } + + @Override + public Assumption createAssumption() { + return createAssumption(null); + } + + @Override + public Assumption createAssumption(String name) { + return new OptimizedAssumption(name); + } + + public Replacements getReplacements() { + if (truffleReplacements == null) { + truffleReplacements = HotSpotTruffleReplacements.makeInstance(); + } + return truffleReplacements; + } + + private boolean acceptForCompilation(RootNode rootNode) { + if (TruffleCompileOnly.getValue() != null) { + if (includes == null) { + parseCompileOnly(); + } + + String name = rootNode.toString(); + boolean included = includes.isEmpty(); + for (int i = 0; !included && i < includes.size(); i++) { + if (name.contains(includes.get(i))) { + included = true; + } + } + if (!included) { + return false; + } + for (String exclude : excludes) { + if (name.contains(exclude)) { + return false; + } + } + } + return true; + } + + private void parseCompileOnly() { + includes = new ArrayList<>(); + excludes = new ArrayList<>(); + + String[] items = TruffleCompileOnly.getValue().split(","); + for (String item : items) { + if (item.startsWith("~")) { + excludes.add(item.substring(1)); + } else { + includes.add(item); + } + } + } + + public static void installOptimizedCallTargetCallMethod() { + Providers providers = getGraalProviders(); + MetaAccessProvider metaAccess = providers.getMetaAccess(); + CodeCacheProvider codeCache = providers.getCodeCache(); + ResolvedJavaMethod resolvedCallMethod = metaAccess.lookupJavaMethod(getCallMethod()); + CompilationResult compResult = compileMethod(resolvedCallMethod); + try (Scope s = Debug.scope("CodeInstall", codeCache, resolvedCallMethod)) { + codeCache.setDefaultMethod(resolvedCallMethod, compResult); + } + } + + private static Method getCallMethod() { + Method method; + try { + method = HotSpotOptimizedCallTarget.class.getDeclaredMethod("call", new Class[]{Object[].class}); + } catch (NoSuchMethodException | SecurityException e) { + throw GraalInternalError.shouldNotReachHere(); + } + return method; + } + + private static CompilationResultBuilderFactory getOptimizedCallTargetInstrumentationFactory(String arch, ResolvedJavaMethod method) { + for (OptimizedCallTargetInstrumentationFactory factory : ServiceLoader.loadInstalled(OptimizedCallTargetInstrumentationFactory.class)) { + if (factory.getArchitecture().equals(arch)) { + factory.setInstrumentedMethod(method); + return factory; + } + } + // No specialization of OptimizedCallTarget on this platform. + return CompilationResultBuilderFactory.Default; + } + + private static CompilationResult compileMethod(ResolvedJavaMethod javaMethod) { + Providers providers = getGraalProviders(); + MetaAccessProvider metaAccess = providers.getMetaAccess(); + SuitesProvider suitesProvider = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getSuites(); + Suites suites = suitesProvider.createSuites(); + suites.getHighTier().findPhase(InliningPhase.class).remove(); + StructuredGraph graph = new StructuredGraph(javaMethod); + new GraphBuilderPhase.Instance(metaAccess, GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph); + PhaseSuite graphBuilderSuite = suitesProvider.getDefaultGraphBuilderSuite(); + CallingConvention cc = getCallingConvention(providers.getCodeCache(), Type.JavaCallee, graph.method(), false); + Backend backend = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend(); + CompilationResultBuilderFactory factory = getOptimizedCallTargetInstrumentationFactory(backend.getTarget().arch.getName(), javaMethod); + return compileGraph(graph, null, cc, javaMethod, providers, backend, providers.getCodeCache().getTarget(), null, graphBuilderSuite, OptimisticOptimizations.ALL, getProfilingInfo(graph), null, + suites, new CompilationResult(), factory); + } + + private static Providers getGraalProviders() { + RuntimeProvider runtimeProvider = Graal.getRequiredCapability(RuntimeProvider.class); + return runtimeProvider.getHostBackend().getProviders(); + } +} diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/substitutions/HotSpotOptimizedCallTargetSubstitutions.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/substitutions/HotSpotOptimizedCallTargetSubstitutions.java Mon Apr 07 16:09:17 2014 -0700 @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.truffle.hotspot.substitutions; + +import com.oracle.graal.api.replacements.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.truffle.*; +import com.oracle.graal.truffle.hotspot.*; +import com.oracle.graal.truffle.nodes.asserts.*; + +@ClassSubstitution(HotSpotOptimizedCallTarget.class) +public class HotSpotOptimizedCallTargetSubstitutions { + + @MacroSubstitution(macro = NeverInlineMacroNode.class, isStatic = false) + public static native Object callHelper(OptimizedCallTarget target, Object[] args); + + @MacroSubstitution(macro = NeverInlineMacroNode.class, isStatic = false) + public static native Object interpreterCall(OptimizedCallTarget target, Object[] args); + + @MacroSubstitution(macro = NeverInlineMacroNode.class, isStatic = false) + public static native Object compiledCodeInvalidated(OptimizedCallTarget target, Object[] args); +} diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java --- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java Mon Apr 07 16:09:17 2014 -0700 @@ -51,7 +51,7 @@ public PartialEvaluationTest() { // Make sure Truffle runtime is initialized. - Assert.assertTrue(Truffle.getRuntime() instanceof GraalTruffleRuntime); + Assert.assertTrue(Truffle.getRuntime() != null); this.truffleCompiler = new TruffleCompilerImpl(); DebugEnvironment.initialize(System.out); @@ -85,7 +85,7 @@ } protected StructuredGraph partialEval(RootNode root, Object[] arguments, final Assumptions assumptions, final boolean canonicalizeReads) { - final OptimizedCallTargetImpl compilable = (OptimizedCallTargetImpl) Truffle.getRuntime().createCallTarget(root); + final OptimizedCallTarget compilable = (OptimizedCallTarget) Truffle.getRuntime().createCallTarget(root); // Executed AST so that all classes are loaded and initialized. compilable.call(arguments); diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/TruffleRuntimeTest.java --- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/TruffleRuntimeTest.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/TruffleRuntimeTest.java Mon Apr 07 16:09:17 2014 -0700 @@ -28,8 +28,8 @@ import com.oracle.graal.api.runtime.*; import com.oracle.graal.runtime.*; -import com.oracle.graal.truffle.*; import com.oracle.truffle.api.*; +import com.oracle.truffle.api.impl.*; public class TruffleRuntimeTest { @@ -46,6 +46,6 @@ @Test public void testRuntimeIsGraalRuntime() { TruffleRuntime runtime = Truffle.getRuntime(); - assertEquals(GraalTruffleRuntime.class, runtime.getClass()); + assertTrue(runtime.getClass() != DefaultTruffleRuntime.class); } } diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CompilationProfile.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CompilationProfile.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CompilationProfile.java Mon Apr 07 16:09:17 2014 -0700 @@ -126,7 +126,7 @@ this.previousTimestamp = timestamp; } - void reportInvalidated() { + public void reportInvalidated() { invalidationCount++; int reprofile = TruffleInvalidationReprofileCount.getValue(); ensureProfiling(reprofile, reprofile); diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java Mon Apr 07 16:09:17 2014 -0700 @@ -22,193 +22,10 @@ */ package com.oracle.graal.truffle; -import static com.oracle.graal.api.code.CodeUtil.*; -import static com.oracle.graal.compiler.GraalCompiler.*; -import static com.oracle.graal.truffle.TruffleCompilerOptions.*; - -import java.lang.reflect.*; -import java.util.*; - -import com.oracle.graal.api.code.*; -import com.oracle.graal.api.code.CallingConvention.Type; -import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.runtime.*; -import com.oracle.graal.compiler.target.*; -import com.oracle.graal.debug.*; -import com.oracle.graal.debug.Debug.Scope; -import com.oracle.graal.graph.*; -import com.oracle.graal.java.*; -import com.oracle.graal.lir.asm.*; -import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.phases.*; -import com.oracle.graal.phases.common.*; -import com.oracle.graal.phases.tiers.*; -import com.oracle.graal.phases.util.*; -import com.oracle.graal.runtime.*; import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.impl.*; -import com.oracle.truffle.api.nodes.*; - -/** - * Implementation of the Truffle runtime when running on top of Graal. - */ -public final class GraalTruffleRuntime implements TruffleRuntime { - - public static GraalTruffleRuntime makeInstance() { - return new GraalTruffleRuntime(); - } - - private TruffleCompiler truffleCompiler; - private Replacements truffleReplacements; - private ArrayList includes; - private ArrayList excludes; - - private GraalTruffleRuntime() { - installOptimizedCallTargetCallMethod(); - } - - public String getName() { - return "Graal Truffle Runtime"; - } - - public RootCallTarget createCallTarget(RootNode rootNode) { - if (truffleCompiler == null) { - truffleCompiler = new TruffleCompilerImpl(); - } - return new OptimizedCallTargetImpl(rootNode, truffleCompiler, TruffleMinInvokeThreshold.getValue(), TruffleCompilationThreshold.getValue(), acceptForCompilation(rootNode)); - } - - public CallNode createCallNode(CallTarget target) { - if (target instanceof OptimizedCallTarget) { - return OptimizedCallNode.create((OptimizedCallTarget) target); - } else { - return new DefaultCallNode(target); - } - } - - @Override - public VirtualFrame createVirtualFrame(Object[] arguments, FrameDescriptor frameDescriptor) { - return OptimizedCallTargetImpl.createFrame(frameDescriptor, arguments); - } - - @Override - public MaterializedFrame createMaterializedFrame(Object[] arguments) { - return createMaterializedFrame(arguments, new FrameDescriptor()); - } - - @Override - public MaterializedFrame createMaterializedFrame(Object[] arguments, FrameDescriptor frameDescriptor) { - return new FrameWithoutBoxing(frameDescriptor, arguments); - } - - @Override - public Assumption createAssumption() { - return createAssumption(null); - } - - @Override - public Assumption createAssumption(String name) { - return new OptimizedAssumption(name); - } - public Replacements getReplacements() { - if (truffleReplacements == null) { - truffleReplacements = TruffleReplacements.makeInstance(); - } - return truffleReplacements; - } - - private boolean acceptForCompilation(RootNode rootNode) { - if (TruffleCompileOnly.getValue() != null) { - if (includes == null) { - parseCompileOnly(); - } - - String name = rootNode.toString(); - boolean included = includes.isEmpty(); - for (int i = 0; !included && i < includes.size(); i++) { - if (name.contains(includes.get(i))) { - included = true; - } - } - if (!included) { - return false; - } - for (String exclude : excludes) { - if (name.contains(exclude)) { - return false; - } - } - } - return true; - } - - private void parseCompileOnly() { - includes = new ArrayList<>(); - excludes = new ArrayList<>(); - - String[] items = TruffleCompileOnly.getValue().split(","); - for (String item : items) { - if (item.startsWith("~")) { - excludes.add(item.substring(1)); - } else { - includes.add(item); - } - } - } +public interface GraalTruffleRuntime extends TruffleRuntime { - public static void installOptimizedCallTargetCallMethod() { - Providers providers = getGraalProviders(); - MetaAccessProvider metaAccess = providers.getMetaAccess(); - CodeCacheProvider codeCache = providers.getCodeCache(); - ResolvedJavaMethod resolvedCallMethod = metaAccess.lookupJavaMethod(getCallMethod()); - CompilationResult compResult = compileMethod(resolvedCallMethod); - try (Scope s = Debug.scope("CodeInstall", codeCache, resolvedCallMethod)) { - codeCache.setDefaultMethod(resolvedCallMethod, compResult); - } - } - - private static Method getCallMethod() { - Method method; - try { - method = OptimizedCallTargetImpl.class.getDeclaredMethod("call", new Class[]{Object[].class}); - } catch (NoSuchMethodException | SecurityException e) { - throw GraalInternalError.shouldNotReachHere(); - } - return method; - } - - private static CompilationResultBuilderFactory getOptimizedCallTargetInstrumentationFactory(String arch, ResolvedJavaMethod method) { - for (OptimizedCallTargetInstrumentationFactory factory : ServiceLoader.loadInstalled(OptimizedCallTargetInstrumentationFactory.class)) { - if (factory.getArchitecture().equals(arch)) { - factory.setInstrumentedMethod(method); - return factory; - } - } - // No specialization of OptimizedCallTarget on this platform. - return CompilationResultBuilderFactory.Default; - } - - private static CompilationResult compileMethod(ResolvedJavaMethod javaMethod) { - Providers providers = getGraalProviders(); - MetaAccessProvider metaAccess = providers.getMetaAccess(); - SuitesProvider suitesProvider = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getSuites(); - Suites suites = suitesProvider.createSuites(); - suites.getHighTier().findPhase(InliningPhase.class).remove(); - StructuredGraph graph = new StructuredGraph(javaMethod); - new GraphBuilderPhase.Instance(metaAccess, GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph); - PhaseSuite graphBuilderSuite = suitesProvider.getDefaultGraphBuilderSuite(); - CallingConvention cc = getCallingConvention(providers.getCodeCache(), Type.JavaCallee, graph.method(), false); - Backend backend = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend(); - CompilationResultBuilderFactory factory = getOptimizedCallTargetInstrumentationFactory(backend.getTarget().arch.getName(), javaMethod); - return compileGraph(graph, null, cc, javaMethod, providers, backend, providers.getCodeCache().getTarget(), null, graphBuilderSuite, OptimisticOptimizations.ALL, getProfilingInfo(graph), null, - suites, new CompilationResult(), factory); - } - - private static Providers getGraalProviders() { - RuntimeProvider runtimeProvider = Graal.getRequiredCapability(RuntimeProvider.class); - return runtimeProvider.getHostBackend().getProviders(); - } + Replacements getReplacements(); } diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java Mon Apr 07 16:09:17 2014 -0700 @@ -49,7 +49,6 @@ protected TruffleInliningResult inliningResult; protected final CompilationProfile compilationProfile; protected final CompilationPolicy compilationPolicy; - private final SpeculationLog speculationLog = new SpeculationLog(); private OptimizedCallTarget splitSource; private final AtomicInteger callSitesKnown = new AtomicInteger(0); @@ -181,9 +180,7 @@ invalidate(oldNode, newNode, reason); } - public SpeculationLog getSpeculationLog() { - return speculationLog; - } + public abstract SpeculationLog getSpeculationLog(); public Map getDebugProperties() { Map properties = new LinkedHashMap<>(); diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTargetImpl.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTargetImpl.java Mon Apr 07 23:35:41 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,181 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.truffle; - -import static com.oracle.graal.truffle.TruffleCompilerOptions.*; - -import java.util.concurrent.*; - -import com.oracle.graal.api.code.*; -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.nodes.*; - -/** - * Call target for running truffle on a standard VM (and not in SubstrateVM). - */ -public final class OptimizedCallTargetImpl extends OptimizedCallTarget { - - protected final TruffleCompiler compiler; - private Future installedCodeTask; - - OptimizedCallTargetImpl(RootNode rootNode, TruffleCompiler compiler, int invokeCounter, int compilationThreshold, boolean compilationEnabled) { - super(rootNode, invokeCounter, compilationThreshold, compilationEnabled, TruffleUseTimeForCompilationDecision.getValue() ? new TimedCompilationPolicy() : new DefaultCompilationPolicy()); - this.compiler = compiler; - } - - public boolean isOptimized() { - return installedCode != null || installedCodeTask != null; - } - - @CompilerDirectives.SlowPath - @Override - public Object call(Object[] args) { - return CompilerDirectives.inInterpreter() ? callHelper(args) : executeHelper(args); - } - - private Object callHelper(Object[] args) { - if (installedCode != null && installedCode.isValid()) { - reinstallCallMethodShortcut(); - } - if (TruffleCallTargetProfiling.getValue()) { - callCount++; - } - if (CompilerDirectives.injectBranchProbability(CompilerDirectives.FASTPATH_PROBABILITY, installedCode != null)) { - try { - return installedCode.executeVarargs(new Object[]{this, args}); - } catch (InvalidInstalledCodeException ex) { - return compiledCodeInvalidated(args); - } - } else { - return interpreterCall(args); - } - } - - private static void reinstallCallMethodShortcut() { - if (TraceTruffleCompilation.getValue()) { - OUT.println("[truffle] reinstall OptimizedCallTarget.call code with frame prolog shortcut."); - } - GraalTruffleRuntime.installOptimizedCallTargetCallMethod(); - } - - private Object compiledCodeInvalidated(Object[] args) { - invalidate(null, null, "Compiled code invalidated"); - return call(args); - } - - @Override - protected void invalidate(Node oldNode, Node newNode, CharSequence reason) { - InstalledCode m = this.installedCode; - if (m != null) { - CompilerAsserts.neverPartOfCompilation(); - installedCode = null; - inliningResult = null; - compilationProfile.reportInvalidated(); - logOptimizedInvalidated(this, oldNode, newNode, reason); - } - cancelInstalledTask(oldNode, newNode, reason); - } - - @Override - protected void cancelInstalledTask(Node oldNode, Node newNode, CharSequence reason) { - Future task = this.installedCodeTask; - if (task != null) { - task.cancel(true); - this.installedCodeTask = null; - logOptimizingUnqueued(this, oldNode, newNode, reason); - compilationProfile.reportInvalidated(); - } - } - - private Object interpreterCall(Object[] args) { - CompilerAsserts.neverPartOfCompilation(); - compilationProfile.reportInterpreterCall(); - - if (compilationEnabled && compilationPolicy.shouldCompile(compilationProfile)) { - InstalledCode code = compile(); - if (code != null && code.isValid()) { - this.installedCode = code; - try { - return code.executeVarargs(new Object[]{this, args}); - } catch (InvalidInstalledCodeException ex) { - return compiledCodeInvalidated(args); - } - } - } - return executeHelper(args); - } - - private boolean isCompiling() { - Future codeTask = this.installedCodeTask; - if (codeTask != null) { - if (codeTask.isCancelled()) { - installedCodeTask = null; - return false; - } - return true; - } - return false; - } - - @Override - public InstalledCode compile() { - if (isCompiling()) { - if (installedCodeTask.isDone()) { - return receiveInstalledCode(); - } - return null; - } else { - performInlining(); - cancelInlinedCallOptimization(); - logOptimizingQueued(this); - this.installedCodeTask = compiler.compile(this); - if (!TruffleBackgroundCompilation.getValue()) { - return receiveInstalledCode(); - } - return null; - } - } - - private InstalledCode receiveInstalledCode() { - try { - return installedCodeTask.get(); - } catch (InterruptedException | ExecutionException e) { - compilationEnabled = false; - logOptimizingFailed(this, e.getMessage()); - if (e.getCause() instanceof BailoutException) { - // Bailout => move on. - } else { - if (TraceTruffleCompilationExceptions.getValue()) { - e.printStackTrace(OUT); - } - if (TruffleCompilationExceptionsAreFatal.getValue()) { - System.exit(-1); - } - } - return null; - } finally { - onCompilationDone(); - } - } - -} diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Mon Apr 07 16:09:17 2014 -0700 @@ -30,6 +30,8 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.replacements.*; +import com.oracle.graal.api.runtime.*; import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.debug.internal.*; @@ -95,7 +97,14 @@ // Replace thisNode with constant. ParameterNode thisNode = graph.getParameter(0); - thisNode.replaceAndDelete(ConstantNode.forObject(callTarget, providers.getMetaAccess(), graph)); + + /* + * Converting the call target to a Constant using the SnippetReflectionProvider is a + * workaround, we should think about a better solution. Since object constants are + * VM-specific, only the hosting VM knows how to do the conversion. + */ + SnippetReflectionProvider snippetReflection = Graal.getRequiredCapability(SnippetReflectionProvider.class); + thisNode.replaceAndDelete(ConstantNode.forConstant(snippetReflection.forObject(callTarget), providers.getMetaAccess(), graph)); // Canonicalize / constant propagate. PhaseContext baseContext = new PhaseContext(providers, assumptions); @@ -123,7 +132,7 @@ if (TraceTruffleCompilationHistogram.getValue() && constantReceivers != null) { DebugHistogram histogram = Debug.createHistogram("Expanded Truffle Nodes"); for (Constant c : constantReceivers) { - histogram.add(c.asObject().getClass().getSimpleName()); + histogram.add(providers.getMetaAccess().lookupJavaType(c).getName()); } new DebugHistogramAsciiPrinter(TTY.out().out()).print(histogram); } @@ -170,7 +179,7 @@ PhaseContext phaseContext = new PhaseContext(providers, assumptions); TruffleExpansionLogger expansionLogger = null; if (TraceTruffleExpansion.getValue()) { - expansionLogger = new TruffleExpansionLogger(graph); + expansionLogger = new TruffleExpansionLogger(providers, graph); } boolean inliningEnabled = target.getInliningResult() != null && target.getInliningResult().size() > 0; Map methodTargetToStack = new HashMap<>(); @@ -278,7 +287,13 @@ return null; } - Object receiverValue = receiverNode.asConstant().asObject(); + /* + * Accessing the constant using the SnippetReflectionProvider is a workaround, we should + * think about a better solution. Since object constants are VM-specific, only the hosting + * VM knows how to do the conversion. + */ + SnippetReflectionProvider snippetReflection = Graal.getRequiredCapability(SnippetReflectionProvider.class); + Object receiverValue = snippetReflection.asObject(receiverNode.asConstant()); if (receiverValue instanceof OptimizedCallNode) { OptimizedCallNode callNode = (OptimizedCallNode) receiverValue; TruffleCallPath callPath = methodCallToCallPath.get(methodCallTargetNode); diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluatorCanonicalizer.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluatorCanonicalizer.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluatorCanonicalizer.java Mon Apr 07 16:09:17 2014 -0700 @@ -24,8 +24,6 @@ import java.lang.reflect.*; -import sun.misc.*; - import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.Node; import com.oracle.graal.nodes.*; @@ -44,8 +42,6 @@ this.constantReflection = constantReflection; } - private static final Unsafe unsafe = Unsafe.getUnsafe(); - @Override public Node canonicalize(Node node) { if (node instanceof LoadFieldNode) { @@ -60,14 +56,11 @@ } } else if (node instanceof LoadIndexedNode) { LoadIndexedNode loadIndexedNode = (LoadIndexedNode) node; - if (loadIndexedNode.array().isConstant() && !loadIndexedNode.array().isNullConstant() && loadIndexedNode.index().isConstant()) { - Object array = loadIndexedNode.array().asConstant().asObject(); - long index = loadIndexedNode.index().asConstant().asLong(); - if (index >= 0 && index < Array.getLength(array)) { - int arrayBaseOffset = unsafe.arrayBaseOffset(array.getClass()); - int arrayIndexScale = unsafe.arrayIndexScale(array.getClass()); - Constant constant = constantReflection.readUnsafeConstant(loadIndexedNode.elementKind(), array, arrayBaseOffset + index * arrayIndexScale, - loadIndexedNode.elementKind() == Kind.Object); + if (loadIndexedNode.array().isConstant() && loadIndexedNode.index().isConstant()) { + int index = loadIndexedNode.index().asConstant().asInt(); + + Constant constant = constantReflection.readArrayElement(loadIndexedNode.array().asConstant(), index); + if (constant != null) { return ConstantNode.forConstant(constant, metaAccess, loadIndexedNode.graph()); } } @@ -75,9 +68,10 @@ return node; } - private static boolean verifyFieldValue(ResolvedJavaField field, Constant constant) { - assert field.getAnnotation(Child.class) == null || constant.isNull() || constant.asObject() instanceof com.oracle.truffle.api.nodes.Node : "@Child field value must be a Node: " + field + - ", but was: " + constant.asObject(); + private boolean verifyFieldValue(ResolvedJavaField field, Constant constant) { + assert field.getAnnotation(Child.class) == null || constant.isNull() || + metaAccess.lookupJavaType(com.oracle.truffle.api.nodes.Node.class).isAssignableFrom(metaAccess.lookupJavaType(constant)) : "@Child field value must be a Node: " + field + + ", but was: " + constant; return true; } } diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java Mon Apr 07 16:09:17 2014 -0700 @@ -120,7 +120,7 @@ @Override public InstalledCode call() throws Exception { try (Scope s = Debug.scope("Truffle", new TruffleDebugJavaMethod(compilable))) { - return compileMethodImpl((OptimizedCallTargetImpl) compilable); + return compileMethodImpl(compilable); } catch (Throwable e) { throw Debug.handle(e); } @@ -132,11 +132,11 @@ public static final DebugTimer CompilationTime = Debug.timer("CompilationTime"); public static final DebugTimer CodeInstallationTime = Debug.timer("CodeInstallation"); - private InstalledCode compileMethodImpl(final OptimizedCallTargetImpl compilable) { + private InstalledCode compileMethodImpl(final OptimizedCallTarget compilable) { final StructuredGraph graph; if (TraceTruffleCompilation.getValue()) { - OptimizedCallTargetImpl.logOptimizingStart(compilable); + OptimizedCallTarget.logOptimizingStart(compilable); } long timeCompilationStarted = System.nanoTime(); @@ -179,7 +179,7 @@ properties.put("CodeSize", code != null ? code.length : 0); properties.put("Source", formatSourceSection(compilable.getRootNode().getSourceSection())); - OptimizedCallTargetImpl.logOptimizingDone(compilable, properties); + OptimizedCallTarget.logOptimizingDone(compilable, properties); } return compiledMethod; } diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleExpansionLogger.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleExpansionLogger.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleExpansionLogger.java Mon Apr 07 16:09:17 2014 -0700 @@ -31,13 +31,16 @@ import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.java.*; +import com.oracle.graal.phases.util.*; public class TruffleExpansionLogger { + private final Providers providers; private final ExpansionTree root; private final Map callToParentTree = new HashMap<>(); - public TruffleExpansionLogger(StructuredGraph graph) { + public TruffleExpansionLogger(Providers providers, StructuredGraph graph) { + this.providers = providers; root = new ExpansionTree(null, null, graph.method(), -1); registerParentInCalls(root, graph); } @@ -47,16 +50,16 @@ int sourceMethodBci = callTarget.invoke().bci(); ResolvedJavaMethod targetMethod = callTarget.targetMethod(); - Object targetReceiver = null; + ResolvedJavaType targetReceiverType = null; if (!Modifier.isStatic(sourceMethod.getModifiers()) && callTarget.receiver().isConstant()) { - targetReceiver = callTarget.receiver().asConstant().asObject(); + targetReceiverType = providers.getMetaAccess().lookupJavaType(callTarget.arguments().first().asConstant()); } - if (targetReceiver != null) { + if (targetReceiverType != null) { ExpansionTree parent = callToParentTree.get(callTarget); assert parent != null; callToParentTree.remove(callTarget); - ExpansionTree tree = new ExpansionTree(parent, targetReceiver, targetMethod, sourceMethodBci); + ExpansionTree tree = new ExpansionTree(parent, targetReceiverType, targetMethod, sourceMethodBci); registerParentInCalls(tree, inliningGraph); } } @@ -94,14 +97,14 @@ private static final class ExpansionTree implements Comparable { private final ExpansionTree parent; - private final Object targetReceiver; + private final ResolvedJavaType targetReceiverType; private final ResolvedJavaMethod targetMethod; private final int parentBci; private final List children = new ArrayList<>(); - public ExpansionTree(ExpansionTree parent, Object receiver, ResolvedJavaMethod targetMethod, int parentBci) { + public ExpansionTree(ExpansionTree parent, ResolvedJavaType targetReceiverType, ResolvedJavaMethod targetMethod, int parentBci) { this.parent = parent; - this.targetReceiver = receiver; + this.targetReceiverType = targetReceiverType; this.targetMethod = targetMethod; this.parentBci = parentBci; if (parent != null) { @@ -141,9 +144,9 @@ } String constantType = ""; - if (targetReceiver != null) { - if (!targetReceiver.getClass().getSimpleName().equals(className)) { - constantType = "<" + targetReceiver.getClass().getSimpleName() + ">"; + if (targetReceiverType != null) { + if (!targetReceiverType.getName().equals(className)) { + constantType = "<" + targetReceiverType.getName() + ">"; } } diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleReplacements.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleReplacements.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleReplacements.java Mon Apr 07 16:09:17 2014 -0700 @@ -26,39 +26,33 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.api.replacements.*; -import com.oracle.graal.api.runtime.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.phases.util.*; import com.oracle.graal.replacements.*; -import com.oracle.graal.runtime.*; import com.oracle.graal.truffle.substitutions.*; /** * Custom {@link Replacements} for Truffle compilation. */ -public final class TruffleReplacements extends ReplacementsImpl { +public abstract class TruffleReplacements extends ReplacementsImpl { private final Replacements graalReplacements; - private TruffleReplacements(Providers providers) { - super(providers, providers.getReplacements().getAssumptions(), providers.getCodeCache().getTarget()); + protected TruffleReplacements(Providers providers, SnippetReflectionProvider snippetReflection) { + super(providers, snippetReflection, providers.getReplacements().getAssumptions(), providers.getCodeCache().getTarget()); this.graalReplacements = providers.getReplacements(); + + registerTruffleSubstitutions(); } - public static Replacements makeInstance() { - Providers graalProviders = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getProviders(); - Replacements truffleReplacements = new TruffleReplacements(graalProviders); - - truffleReplacements.registerSubstitutions(CompilerAssertsSubstitutions.class); - truffleReplacements.registerSubstitutions(CompilerDirectivesSubstitutions.class); - truffleReplacements.registerSubstitutions(ExactMathSubstitutions.class); - truffleReplacements.registerSubstitutions(OptimizedAssumptionSubstitutions.class); - truffleReplacements.registerSubstitutions(OptimizedCallTargetSubstitutions.class); - truffleReplacements.registerSubstitutions(OptimizedCallTargetImplSubstitutions.class); - - return truffleReplacements; + protected void registerTruffleSubstitutions() { + registerSubstitutions(CompilerAssertsSubstitutions.class); + registerSubstitutions(CompilerDirectivesSubstitutions.class); + registerSubstitutions(ExactMathSubstitutions.class); + registerSubstitutions(OptimizedAssumptionSubstitutions.class); + registerSubstitutions(OptimizedCallTargetSubstitutions.class); } @Override diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/AssumptionNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/AssumptionNode.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/AssumptionNode.java Mon Apr 07 16:09:17 2014 -0700 @@ -23,6 +23,8 @@ package com.oracle.graal.truffle.nodes; import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.replacements.*; +import com.oracle.graal.api.runtime.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.replacements.nodes.*; @@ -39,13 +41,21 @@ return arguments.first(); } + private static SnippetReflectionProvider getSnippetReflection() { + /* + * This class requires access to the objects encapsulated in Constants, and therefore breaks + * the compiler-VM separation of object constants. + */ + return Graal.getRequiredCapability(SnippetReflectionProvider.class); + } + @Override public void simplify(SimplifierTool tool) { ValueNode assumption = getAssumption(); if (tool.assumptions() != null && assumption.isConstant()) { Constant c = assumption.asConstant(); assert c.getKind() == Kind.Object; - Object object = c.asObject(); + Object object = getSnippetReflection().asObject(c); OptimizedAssumption assumptionObject = (OptimizedAssumption) object; StructuredGraph graph = graph(); if (assumptionObject.isValid()) { diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/BailoutNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/BailoutNode.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/BailoutNode.java Mon Apr 07 16:09:17 2014 -0700 @@ -40,7 +40,7 @@ ValueNode arg = arguments.get(0); String message = ""; if (arg.isConstant()) { - message = (String) arg.asConstant().asObject(); + message = arg.asConstant().toValueString(); } throw new BailoutException(message); } diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/LoadIndexedFinalNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/LoadIndexedFinalNode.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/LoadIndexedFinalNode.java Mon Apr 07 16:09:17 2014 -0700 @@ -22,10 +22,6 @@ */ package com.oracle.graal.truffle.nodes; -import java.lang.reflect.*; - -import sun.misc.*; - import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; @@ -52,13 +48,9 @@ @Override public Node canonical(CanonicalizerTool tool) { - if (array().isConstant() && !array().isNullConstant() && index().isConstant()) { - Object array = array().asConstant().asObject(); - long index = index().asConstant().asLong(); - if (index >= 0 && index < Array.getLength(array)) { - int arrayBaseOffset = Unsafe.getUnsafe().arrayBaseOffset(array.getClass()); - int arrayIndexScale = Unsafe.getUnsafe().arrayIndexScale(array.getClass()); - Constant constant = tool.getConstantReflection().readUnsafeConstant(elementKind(), array().asConstant(), arrayBaseOffset + index * arrayIndexScale, elementKind() == Kind.Object); + if (array().isConstant() && index().isConstant()) { + Constant constant = tool.getConstantReflection().readArrayElement(array().asConstant(), index().asConstant().asInt()); + if (constant != null) { return ConstantNode.forConstant(constant, tool.getMetaAccess(), graph()); } } diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/ObjectLocationIdentity.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/ObjectLocationIdentity.java Mon Apr 07 16:09:17 2014 -0700 @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2013, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.truffle.nodes; + +import java.util.*; + +import com.oracle.graal.api.meta.*; + +/** + * A {@link LocationIdentity} wrapping an object. + */ +public final class ObjectLocationIdentity implements LocationIdentity { + + private static HashMap map = new HashMap<>(); + + private Constant object; + + public static LocationIdentity create(Constant object) { + assert object.getKind() == Kind.Object && object.isNonNull(); + synchronized (map) { + if (map.containsKey(object)) { + return map.get(object); + } else { + ObjectLocationIdentity locationIdentity = new ObjectLocationIdentity(object); + map.put(object, locationIdentity); + return locationIdentity; + } + } + } + + private ObjectLocationIdentity(Constant object) { + this.object = object; + } + + @Override + public String toString() { + return "Identity(" + object + ")"; + } +} diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java Mon Apr 07 16:09:17 2014 -0700 @@ -25,6 +25,8 @@ import java.util.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.replacements.*; +import com.oracle.graal.api.runtime.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; @@ -64,9 +66,17 @@ return arguments; } + private static SnippetReflectionProvider getSnippetReflection() { + /* + * This class requires access to the objects encapsulated in Constants, and therefore breaks + * the compiler-VM separation of object constants. + */ + return Graal.getRequiredCapability(SnippetReflectionProvider.class); + } + private FrameDescriptor getConstantFrameDescriptor() { assert descriptor.isConstant() && !descriptor.isNullConstant(); - return (FrameDescriptor) descriptor.asConstant().asObject(); + return (FrameDescriptor) getSnippetReflection().asObject(descriptor.asConstant()); } private int getFrameSize() { @@ -151,7 +161,7 @@ if (frameSize > 0) { FrameDescriptor frameDescriptor = getConstantFrameDescriptor(); - ConstantNode objectDefault = ConstantNode.forObject(frameDescriptor.getTypeConversion().getDefaultValue(), tool.getMetaAccessProvider(), graph()); + ConstantNode objectDefault = ConstantNode.forConstant(getSnippetReflection().forObject(frameDescriptor.getTypeConversion().getDefaultValue()), tool.getMetaAccessProvider(), graph()); ConstantNode tagDefault = ConstantNode.forByte((byte) 0, graph()); for (int i = 0; i < frameSize; i++) { objectArrayEntryState[i] = objectDefault; diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadFinalNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadFinalNode.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadFinalNode.java Mon Apr 07 16:09:17 2014 -0700 @@ -30,6 +30,7 @@ import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; +import com.oracle.graal.truffle.nodes.*; import com.oracle.truffle.api.*; /** @@ -56,7 +57,7 @@ @Override public Node canonical(CanonicalizerTool tool) { if (object.isConstant() && !object.isNullConstant() && offset.isConstant()) { - Constant constant = tool.getConstantReflection().readUnsafeConstant(accessKind, object.asConstant().asObject(), offset.asConstant().asLong(), accessKind == Kind.Object); + Constant constant = tool.getConstantReflection().readUnsafeConstant(accessKind, object.asConstant(), offset.asConstant().asLong(), accessKind == Kind.Object); return ConstantNode.forConstant(constant, tool.getMetaAccess(), graph()); } return this; @@ -86,12 +87,11 @@ @Override public void lower(LoweringTool tool) { CompareNode compare = CompareNode.createCompareNode(graph(), Condition.EQ, condition, ConstantNode.forBoolean(true, graph())); - Object locationIdentityObject = location.asConstant().asObject(); LocationIdentity locationIdentity; - if (locationIdentityObject == null) { + if (location.asConstant().isNull()) { locationIdentity = LocationIdentity.ANY_LOCATION; } else { - locationIdentity = ObjectLocationIdentity.create(locationIdentityObject); + locationIdentity = ObjectLocationIdentity.create(location.asConstant()); } UnsafeLoadNode result = graph().add(new UnsafeLoadNode(object, offset, accessKind, locationIdentity, compare)); graph().replaceFixedWithFixed(this, result); diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadMacroNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadMacroNode.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadMacroNode.java Mon Apr 07 16:09:17 2014 -0700 @@ -28,6 +28,7 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.truffle.nodes.*; import com.oracle.graal.truffle.nodes.asserts.*; import com.oracle.truffle.api.*; @@ -54,12 +55,11 @@ ValueNode objectArgument = arguments.get(OBJECT_ARGUMENT_INDEX); ValueNode offsetArgument = arguments.get(OFFSET_ARGUMENT_INDEX); ValueNode conditionArgument = arguments.get(CONDITION_ARGUMENT_INDEX); - Object locationIdentityObject = locationArgument.asConstant().asObject(); LocationIdentity locationIdentity; - if (locationIdentityObject == null) { + if (locationArgument.asConstant().isNull()) { locationIdentity = LocationIdentity.ANY_LOCATION; } else { - locationIdentity = ObjectLocationIdentity.create(locationIdentityObject); + locationIdentity = ObjectLocationIdentity.create(locationArgument.asConstant()); } CompareNode compare = CompareNode.createCompareNode(graph(), Condition.EQ, conditionArgument, ConstantNode.forBoolean(true, graph())); Kind returnKind = this.getTargetMethod().getSignature().getReturnKind(); diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeStoreMacroNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeStoreMacroNode.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeStoreMacroNode.java Mon Apr 07 16:09:17 2014 -0700 @@ -27,6 +27,7 @@ import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.truffle.nodes.*; import com.oracle.graal.truffle.nodes.asserts.*; import com.oracle.truffle.api.*; @@ -53,12 +54,11 @@ ValueNode objectArgument = arguments.get(OBJECT_ARGUMENT_INDEX); ValueNode offsetArgument = arguments.get(OFFSET_ARGUMENT_INDEX); ValueNode valueArgument = arguments.get(VALUE_ARGUMENT_INDEX); - Object locationIdentityObject = locationArgument.asConstant().asObject(); LocationIdentity locationIdentity; - if (locationIdentityObject == null) { + if (locationArgument.asConstant().isNull()) { locationIdentity = LocationIdentity.ANY_LOCATION; } else { - locationIdentity = ObjectLocationIdentity.create(locationIdentityObject); + locationIdentity = ObjectLocationIdentity.create(locationArgument.asConstant()); } UnsafeStoreNode unsafeStoreNode = graph().add( diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/UnsafeTypeCastMacroNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/UnsafeTypeCastMacroNode.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/UnsafeTypeCastMacroNode.java Mon Apr 07 16:09:17 2014 -0700 @@ -55,11 +55,10 @@ if (classArgument.isConstant() && nonNullArgument.isConstant()) { ValueNode objectArgument = arguments.get(OBJECT_ARGUMENT_INDEX); ValueNode conditionArgument = arguments.get(CONDITION_ARGUMENT_INDEX); - Class c = (Class) classArgument.asConstant().asObject(); - if (c == null) { + ResolvedJavaType lookupJavaType = tool.getConstantReflection().asJavaType(classArgument.asConstant()); + if (lookupJavaType == null) { return objectArgument; } - ResolvedJavaType lookupJavaType = tool.getMetaAccess().lookupJavaType(c); Stamp stamp = StampFactory.declared(lookupJavaType, nonNullArgument.asConstant().asInt() != 0); ConditionAnchorNode valueAnchorNode = graph().add(new ConditionAnchorNode(CompareNode.createCompareNode(graph(), Condition.EQ, conditionArgument, ConstantNode.forBoolean(true, graph())))); UnsafeCastNode piCast = graph().unique(new UnsafeCastNode(objectArgument, stamp, valueAnchorNode)); diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/OptimizedCallTargetImplSubstitutions.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/OptimizedCallTargetImplSubstitutions.java Mon Apr 07 23:35:41 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.truffle.substitutions; - -import com.oracle.graal.api.replacements.*; -import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.truffle.*; -import com.oracle.graal.truffle.nodes.asserts.*; - -@ClassSubstitution(OptimizedCallTargetImpl.class) -public class OptimizedCallTargetImplSubstitutions { - - @MacroSubstitution(macro = NeverInlineMacroNode.class, isStatic = false) - public static native Object callHelper(OptimizedCallTarget target, Object[] args); - - @MacroSubstitution(macro = NeverInlineMacroNode.class, isStatic = false) - public static native Object interpreterCall(OptimizedCallTarget target, Object[] args); - - @MacroSubstitution(macro = NeverInlineMacroNode.class, isStatic = false) - public static native Object compiledCodeInvalidated(OptimizedCallTarget target, Object[] args); -} diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationClosure.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationClosure.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationClosure.java Mon Apr 07 16:09:17 2014 -0700 @@ -39,8 +39,8 @@ public class PEReadEliminationClosure extends PartialEscapeClosure { - public PEReadEliminationClosure(SchedulePhase schedule, MetaAccessProvider metaAccess, Assumptions assumptions) { - super(schedule, metaAccess, assumptions); + public PEReadEliminationClosure(SchedulePhase schedule, MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, Assumptions assumptions) { + super(schedule, metaAccess, constantReflection, assumptions); } @Override diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java Mon Apr 07 16:09:17 2014 -0700 @@ -63,8 +63,8 @@ */ public static final class Final extends PartialEscapeClosure { - public Final(SchedulePhase schedule, MetaAccessProvider metaAccess, Assumptions assumptions) { - super(schedule, metaAccess, assumptions); + public Final(SchedulePhase schedule, MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, Assumptions assumptions) { + super(schedule, metaAccess, constantReflection, assumptions); } @Override @@ -78,10 +78,10 @@ } } - public PartialEscapeClosure(SchedulePhase schedule, MetaAccessProvider metaAccess, Assumptions assumptions) { + public PartialEscapeClosure(SchedulePhase schedule, MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, Assumptions assumptions) { super(schedule); this.usages = schedule.getCFG().graph.createNodeBitMap(); - this.tool = new VirtualizerToolImpl(metaAccess, assumptions, this); + this.tool = new VirtualizerToolImpl(metaAccess, constantReflection, assumptions, this); } public Map getHints() { diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapePhase.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapePhase.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapePhase.java Mon Apr 07 16:09:17 2014 -0700 @@ -72,9 +72,9 @@ @Override protected Closure createEffectsClosure(PhaseContext context, SchedulePhase schedule) { if (readElimination) { - return new PEReadEliminationClosure(schedule, context.getMetaAccess(), context.getAssumptions()); + return new PEReadEliminationClosure(schedule, context.getMetaAccess(), context.getConstantReflection(), context.getAssumptions()); } else { - return new PartialEscapeClosure.Final(schedule, context.getMetaAccess(), context.getAssumptions()); + return new PartialEscapeClosure.Final(schedule, context.getMetaAccess(), context.getConstantReflection(), context.getAssumptions()); } } diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualizerToolImpl.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualizerToolImpl.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualizerToolImpl.java Mon Apr 07 16:09:17 2014 -0700 @@ -40,11 +40,13 @@ class VirtualizerToolImpl implements VirtualizerTool { private final MetaAccessProvider metaAccess; + private final ConstantReflectionProvider constantReflection; private final Assumptions assumptions; private final PartialEscapeClosure closure; - VirtualizerToolImpl(MetaAccessProvider metaAccess, Assumptions assumptions, PartialEscapeClosure closure) { + VirtualizerToolImpl(MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, Assumptions assumptions, PartialEscapeClosure closure) { this.metaAccess = metaAccess; + this.constantReflection = constantReflection; this.assumptions = assumptions; this.closure = closure; } @@ -60,6 +62,10 @@ return metaAccess; } + public ConstantReflectionProvider getConstantReflectionProvider() { + return constantReflection; + } + @Override public Assumptions getAssumptions() { return assumptions; diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/SnippetLocationNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/SnippetLocationNode.java Mon Apr 07 16:09:17 2014 -0700 @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2013, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.word.nodes; + +import static com.oracle.graal.api.meta.LocationIdentity.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.replacements.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; + +/** + * Location node that can be used inside a snippet without having the elements (including the + * location identity and kind) as a snippet constant. Can represent locations in the form of [base + + * index * scale + disp]. When the location is created, all elements (base, index, scale, disp) are + * nodes. Both scale and disp must eventually canonicalize to {@link ConstantNode constants} so that + * this node can be canonicalized to a {@link IndexedLocationNode} or {@link ConstantLocationNode}. + */ +public final class SnippetLocationNode extends LocationNode implements Canonicalizable { + + private final SnippetReflectionProvider snippetReflection; + + @Input private ValueNode valueKind; + @Input(InputType.Association) private ValueNode locationIdentity; + @Input private ValueNode displacement; + @Input private ValueNode index; + @Input private ValueNode indexScaling; + + public static SnippetLocationNode create(SnippetReflectionProvider snippetReflection, ValueNode identity, ValueNode kind, ValueNode displacement, ValueNode index, ValueNode indexScaling, + Graph graph) { + return graph.unique(new SnippetLocationNode(snippetReflection, identity, kind, displacement, index, indexScaling)); + } + + private SnippetLocationNode(@InjectedNodeParameter SnippetReflectionProvider snippetReflection, ValueNode locationIdentity, ValueNode kind, ValueNode displacement) { + this(snippetReflection, locationIdentity, kind, displacement, null, null); + } + + private SnippetLocationNode(@InjectedNodeParameter SnippetReflectionProvider snippetReflection, ValueNode locationIdentity, ValueNode kind, ValueNode displacement, ValueNode index, + ValueNode indexScaling) { + super(StampFactory.object()); + this.snippetReflection = snippetReflection; + this.valueKind = kind; + this.locationIdentity = locationIdentity; + this.displacement = displacement; + this.index = index; + this.indexScaling = indexScaling; + } + + @Override + public Kind getValueKind() { + if (valueKind.isConstant()) { + return (Kind) snippetReflection.asObject(valueKind.asConstant()); + } + throw new GraalInternalError("Cannot access kind yet because it is not constant: " + valueKind); + } + + @Override + public LocationIdentity getLocationIdentity() { + if (locationIdentity.isConstant()) { + return (LocationIdentity) snippetReflection.asObject(locationIdentity.asConstant()); + } + // We do not know our actual location identity yet, so be conservative. + return ANY_LOCATION; + } + + @Override + public Node canonical(CanonicalizerTool tool) { + if (valueKind.isConstant() && locationIdentity.isConstant() && displacement.isConstant() && (indexScaling == null || indexScaling.isConstant())) { + Kind constKind = (Kind) snippetReflection.asObject(valueKind.asConstant()); + LocationIdentity constLocation = (LocationIdentity) snippetReflection.asObject(locationIdentity.asConstant()); + long constDisplacement = displacement.asConstant().asLong(); + int constIndexScaling = indexScaling == null ? 0 : indexScaling.asConstant().asInt(); + + if (index == null || constIndexScaling == 0) { + return ConstantLocationNode.create(constLocation, constKind, constDisplacement, graph()); + } else if (index.isConstant()) { + return ConstantLocationNode.create(constLocation, constKind, index.asConstant().asLong() * constIndexScaling + constDisplacement, graph()); + } else { + return IndexedLocationNode.create(constLocation, constKind, constDisplacement, index, graph(), constIndexScaling); + } + } + return this; + } + + @Override + public Value generateAddress(NodeLIRBuilderTool gen, Value base) { + throw new GraalInternalError("locationIdentity must be a constant so that this node can be canonicalized: " + locationIdentity); + } + + @NodeIntrinsic + public static native Location constantLocation(LocationIdentity identity, Kind kind, long displacement); + + @NodeIntrinsic + public static native Location indexedLocation(LocationIdentity identity, Kind kind, long displacement, int index, int indexScaling); +} diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java --- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java Mon Apr 07 16:09:17 2014 -0700 @@ -27,6 +27,7 @@ import java.lang.reflect.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.replacements.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.HeapAccess.BarrierType; @@ -49,13 +50,15 @@ public class WordTypeRewriterPhase extends Phase { protected final MetaAccessProvider metaAccess; + protected final SnippetReflectionProvider snippetReflection; protected final ResolvedJavaType wordBaseType; protected final ResolvedJavaType wordImplType; protected final ResolvedJavaType objectAccessType; protected final Kind wordKind; - public WordTypeRewriterPhase(MetaAccessProvider metaAccess, Kind wordKind) { + public WordTypeRewriterPhase(MetaAccessProvider metaAccess, SnippetReflectionProvider snippetReflection, Kind wordKind) { this.metaAccess = metaAccess; + this.snippetReflection = snippetReflection; this.wordKind = wordKind; this.wordBaseType = metaAccess.lookupJavaType(WordBase.class); this.wordImplType = metaAccess.lookupJavaType(Word.class); @@ -86,7 +89,7 @@ if (node.isConstant()) { ConstantNode oldConstant = (ConstantNode) node; assert oldConstant.getValue().getKind() == Kind.Object; - WordBase value = (WordBase) oldConstant.getValue().asObject(); + WordBase value = (WordBase) snippetReflection.asObject(oldConstant.getValue()); ConstantNode newConstant = ConstantNode.forIntegerKind(wordKind, value.rawValue(), node.graph()); graph.replaceFloating(oldConstant, newConstant); @@ -221,7 +224,7 @@ assert arguments.size() == 3; Kind readKind = asKind(callTargetNode.returnType()); LocationNode location = makeLocation(graph, arguments.get(1), readKind, ANY_LOCATION); - BarrierType barrierType = (BarrierType) arguments.get(2).asConstant().asObject(); + BarrierType barrierType = (BarrierType) snippetReflection.asObject(arguments.get(2).asConstant()); replace(invoke, readOp(graph, arguments.get(0), invoke, location, barrierType, true)); break; } @@ -359,10 +362,10 @@ private LocationNode makeLocation(StructuredGraph graph, ValueNode offset, Kind readKind, ValueNode locationIdentity) { if (locationIdentity.isConstant()) { - return makeLocation(graph, offset, readKind, (LocationIdentity) locationIdentity.asConstant().asObject()); + return makeLocation(graph, offset, readKind, (LocationIdentity) snippetReflection.asObject(locationIdentity.asConstant())); } - return SnippetLocationNode.create(locationIdentity, ConstantNode.forObject(readKind, metaAccess, graph), ConstantNode.forLong(0, graph), fromSigned(graph, offset), - ConstantNode.forInt(1, graph), graph); + return SnippetLocationNode.create(snippetReflection, locationIdentity, ConstantNode.forConstant(snippetReflection.forObject(readKind), metaAccess, graph), ConstantNode.forLong(0, graph), + fromSigned(graph, offset), ConstantNode.forInt(1, graph), graph); } protected LocationNode makeLocation(StructuredGraph graph, ValueNode offset, Kind readKind, LocationIdentity locationIdentity) { diff -r ff5660822992 -r db4254246f9a graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeVerificationPhase.java --- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeVerificationPhase.java Mon Apr 07 23:35:41 2014 +0200 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeVerificationPhase.java Mon Apr 07 16:09:17 2014 -0700 @@ -25,6 +25,7 @@ import java.lang.reflect.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.replacements.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.Node.NodeIntrinsic; import com.oracle.graal.nodes.*; @@ -44,8 +45,8 @@ private final WordTypeRewriterPhase wordAccess; - public WordTypeVerificationPhase(MetaAccessProvider metaAccess, Kind wordKind) { - this.wordAccess = new WordTypeRewriterPhase(metaAccess, wordKind); + public WordTypeVerificationPhase(MetaAccessProvider metaAccess, SnippetReflectionProvider snippetReflection, Kind wordKind) { + this.wordAccess = new WordTypeRewriterPhase(metaAccess, snippetReflection, wordKind); } @Override diff -r ff5660822992 -r db4254246f9a src/share/vm/classfile/systemDictionary.hpp --- a/src/share/vm/classfile/systemDictionary.hpp Mon Apr 07 23:35:41 2014 +0200 +++ b/src/share/vm/classfile/systemDictionary.hpp Mon Apr 07 16:09:17 2014 -0700 @@ -204,6 +204,8 @@ do_klass(HotSpotResolvedJavaMethod_klass, com_oracle_graal_hotspot_meta_HotSpotResolvedJavaMethod, Opt) \ do_klass(HotSpotResolvedObjectType_klass, com_oracle_graal_hotspot_meta_HotSpotResolvedObjectType, Opt) \ do_klass(HotSpotMonitorValue_klass, com_oracle_graal_hotspot_meta_HotSpotMonitorValue, Opt) \ + do_klass(HotSpotObjectConstant_klass, com_oracle_graal_hotspot_meta_HotSpotObjectConstant, Opt) \ + do_klass(HotSpotMetaspaceConstant_klass, com_oracle_graal_hotspot_meta_HotSpotMetaspaceConstant, Opt) \ /* graal.api.code */ \ do_klass(Assumptions_klass, com_oracle_graal_api_code_Assumptions, Opt) \ do_klass(Assumptions_ConcreteMethod_klass, com_oracle_graal_api_code_Assumptions_ConcreteMethod, Opt) \ @@ -231,6 +233,8 @@ do_klass(SpeculationLog_klass, com_oracle_graal_api_code_SpeculationLog, Opt) \ /* graal.api.meta */ \ do_klass(Constant_klass, com_oracle_graal_api_meta_Constant, Opt) \ + do_klass(PrimitiveConstant_klass, com_oracle_graal_api_meta_PrimitiveConstant, Opt) \ + do_klass(NullConstant_klass, com_oracle_graal_api_meta_NullConstant, Opt) \ do_klass(ExceptionHandler_klass, com_oracle_graal_api_meta_ExceptionHandler, Opt) \ do_klass(Kind_klass, com_oracle_graal_api_meta_Kind, Opt) \ do_klass(JavaMethod_klass, com_oracle_graal_api_meta_JavaMethod, Opt) \ diff -r ff5660822992 -r db4254246f9a src/share/vm/classfile/vmSymbols.hpp --- a/src/share/vm/classfile/vmSymbols.hpp Mon Apr 07 23:35:41 2014 +0200 +++ b/src/share/vm/classfile/vmSymbols.hpp Mon Apr 07 16:09:17 2014 -0700 @@ -315,8 +315,12 @@ template(com_oracle_graal_hotspot_meta_HotSpotResolvedJavaMethod, "com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod") \ template(com_oracle_graal_hotspot_meta_HotSpotResolvedObjectType, "com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType") \ template(com_oracle_graal_hotspot_meta_HotSpotMonitorValue, "com/oracle/graal/hotspot/meta/HotSpotMonitorValue") \ + template(com_oracle_graal_hotspot_meta_HotSpotObjectConstant, "com/oracle/graal/hotspot/meta/HotSpotObjectConstant") \ + template(com_oracle_graal_hotspot_meta_HotSpotMetaspaceConstant, "com/oracle/graal/hotspot/meta/HotSpotMetaspaceConstant") \ /* graal.api.meta */ \ template(com_oracle_graal_api_meta_Constant, "com/oracle/graal/api/meta/Constant") \ + template(com_oracle_graal_api_meta_PrimitiveConstant, "com/oracle/graal/api/meta/PrimitiveConstant") \ + template(com_oracle_graal_api_meta_NullConstant, "com/oracle/graal/api/meta/NullConstant") \ template(com_oracle_graal_api_meta_ConstantPool, "com/oracle/graal/api/meta/ConstantPool") \ template(com_oracle_graal_api_meta_ExceptionHandler, "com/oracle/graal/api/meta/ExceptionHandler") \ template(com_oracle_graal_api_meta_JavaMethod, "com/oracle/graal/api/meta/JavaMethod") \ @@ -352,7 +356,7 @@ /* graal.gpu */ \ template(com_oracle_graal_gpu_ExternalCompilationResult, "com/oracle/graal/gpu/ExternalCompilationResult") \ /* graal.truffle */ \ - template(com_oracle_graal_truffle_GraalTruffleRuntime, "com/oracle/graal/truffle/GraalTruffleRuntime") \ + template(com_oracle_graal_truffle_hotspot_HotSpotTruffleRuntime, "com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime") \ template(startCompiler_name, "startCompiler") \ template(bootstrap_name, "bootstrap") \ template(compileTheWorld_name, "compileTheWorld") \ @@ -367,7 +371,7 @@ template(runtime_name, "runtime") \ template(runtime_signature, "()Lcom/oracle/graal/hotspot/HotSpotGraalRuntime;") \ template(makeInstance_name, "makeInstance") \ - template(makeInstance_signature, "()Lcom/oracle/graal/truffle/GraalTruffleRuntime;") \ + template(makeInstance_signature, "()Lcom/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime;") \ template(initialize_name, "initialize") \ template(forObject_name, "forObject") \ template(callbackInternal_name, "callbackInternal") \ diff -r ff5660822992 -r db4254246f9a src/share/vm/graal/graalCodeInstaller.cpp --- a/src/share/vm/graal/graalCodeInstaller.cpp Mon Apr 07 23:35:41 2014 +0200 +++ b/src/share/vm/graal/graalCodeInstaller.cpp Mon Apr 07 16:09:17 2014 -0700 @@ -180,14 +180,14 @@ // Records any Metadata values embedded in a Constant (e.g., the value returned by HotSpotResolvedObjectType.klass()). static void record_metadata_in_constant(oop constant, OopRecorder* oop_recorder) { - char kind = Kind::typeChar(Constant::kind(constant)); - char wordKind = 'j'; - if (kind == wordKind) { - oop obj = Constant::object(constant); - jlong prim = Constant::primitive(constant); - if (obj != NULL) { - record_metadata_reference(obj, prim, false, oop_recorder); - } + if (constant->is_a(HotSpotMetaspaceConstant::klass())) { + oop obj = HotSpotMetaspaceConstant::metaspaceObject(constant); + jlong prim = HotSpotMetaspaceConstant::primitive(constant); + assert(Kind::typeChar(Constant::kind(constant)) == 'j', "must have word kind"); + assert(obj != NULL, "must have an object"); + assert(prim != 0, "must have a primitive value"); + + record_metadata_reference(obj, prim, false, oop_recorder); } } @@ -263,17 +263,19 @@ return value; } else if (value->is_a(Constant::klass())){ record_metadata_in_constant(value, oop_recorder); - jlong prim = Constant::primitive(value); if (type == T_INT || type == T_FLOAT || type == T_SHORT || type == T_CHAR || type == T_BOOLEAN || type == T_BYTE) { + jlong prim = PrimitiveConstant::primitive(value); return new ConstantIntValue(*(jint*)&prim); } else if (type == T_LONG || type == T_DOUBLE) { + jlong prim = PrimitiveConstant::primitive(value); second = new ConstantIntValue(0); return new ConstantLongValue(prim); } else if (type == T_OBJECT) { - oop obj = Constant::object(value); - if (obj == NULL) { + if (value->is_a(NullConstant::klass())) { return new ConstantOopWriteValue(NULL); } else { + oop obj = HotSpotObjectConstant::object(value); + assert(obj != NULL, "null value must be in NullConstant"); return new ConstantOopWriteValue(JNIHandles::make_local(obj)); } } else if (type == T_ADDRESS) { diff -r ff5660822992 -r db4254246f9a src/share/vm/graal/graalJavaAccess.hpp --- a/src/share/vm/graal/graalJavaAccess.hpp Mon Apr 07 23:35:41 2014 +0200 +++ b/src/share/vm/graal/graalJavaAccess.hpp Mon Apr 07 16:09:17 2014 -0700 @@ -201,8 +201,18 @@ end_class \ start_class(Constant) \ oop_field(Constant, kind, "Lcom/oracle/graal/api/meta/Kind;") \ - oop_field(Constant, object, "Ljava/lang/Object;") \ - long_field(Constant, primitive) \ + end_class \ + start_class(PrimitiveConstant) \ + long_field(PrimitiveConstant, primitive) \ + end_class \ + start_class(NullConstant) \ + end_class \ + start_class(HotSpotObjectConstant) \ + oop_field(HotSpotObjectConstant, object, "Ljava/lang/Object;") \ + end_class \ + start_class(HotSpotMetaspaceConstant) \ + long_field(HotSpotMetaspaceConstant, primitive) \ + oop_field(HotSpotMetaspaceConstant, metaspaceObject, "Ljava/lang/Object;") \ end_class \ start_class(Kind) \ char_field(Kind, typeChar) \ diff -r ff5660822992 -r db4254246f9a src/share/vm/graal/graalVMToCompiler.cpp --- a/src/share/vm/graal/graalVMToCompiler.cpp Mon Apr 07 23:35:41 2014 +0200 +++ b/src/share/vm/graal/graalVMToCompiler.cpp Mon Apr 07 16:09:17 2014 -0700 @@ -49,12 +49,12 @@ } Handle VMToCompiler::truffleRuntime() { - Symbol* name = vmSymbols::com_oracle_graal_truffle_GraalTruffleRuntime(); + Symbol* name = vmSymbols::com_oracle_graal_truffle_hotspot_HotSpotTruffleRuntime(); KlassHandle klass = loadClass(name); JavaValue result(T_OBJECT); JavaCalls::call_static(&result, klass, vmSymbols::makeInstance_name(), vmSymbols::makeInstance_signature(), Thread::current()); - check_pending_exception("Couldn't initialize GraalTruffleRuntime"); + check_pending_exception("Couldn't initialize HotSpotTruffleRuntime"); return Handle((oop) result.get_jobject()); }