# HG changeset patch # User Doug Simon # Date 1417018489 -3600 # Node ID 25a21e1794ec9f8a592ba26ed1b814d1b5cec969 # Parent 8a2e6bc4384cda3f83e818017293f7ec3310c3cf modified SnippetReflectionProvider to support both VM-side and compiler-side constants in a compilation replay context diff -r 8a2e6bc4384c -r 25a21e1794ec graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestConstantReflectionProvider.java --- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestConstantReflectionProvider.java Wed Nov 26 14:03:13 2014 +0100 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestConstantReflectionProvider.java Wed Nov 26 17:14:49 2014 +0100 @@ -54,12 +54,12 @@ public void readArrayLengthTest() { for (JavaConstant c : constants) { Integer actual = constantReflection.readArrayLength(c); - if (c.getKind() != Kind.Object || c.isNull() || !snippetReflection.asObject(c).getClass().isArray()) { + if (c.getKind() != Kind.Object || c.isNull() || !snippetReflection.asObject(Object.class, c).getClass().isArray()) { assertNull(actual); } else { assertNotNull(actual); int actualInt = actual; - assertEquals(Array.getLength(snippetReflection.asObject(c)), actualInt); + assertEquals(Array.getLength(snippetReflection.asObject(Object.class, c)), actualInt); } } } @@ -74,10 +74,10 @@ } } - assertEquals(Long.valueOf(42), snippetReflection.asObject(constantReflection.boxPrimitive(JavaConstant.forLong(42)))); - assertEquals(Integer.valueOf(666), snippetReflection.asObject(constantReflection.boxPrimitive(JavaConstant.forInt(666)))); - assertEquals(Byte.valueOf((byte) 123), snippetReflection.asObject(constantReflection.boxPrimitive(JavaConstant.forByte((byte) 123)))); - assertSame(Boolean.TRUE, snippetReflection.asObject(constantReflection.boxPrimitive(JavaConstant.forBoolean(true)))); + assertEquals(Long.valueOf(42), snippetReflection.asObject(Long.class, constantReflection.boxPrimitive(JavaConstant.forLong(42)))); + assertEquals(Integer.valueOf(666), snippetReflection.asObject(Integer.class, constantReflection.boxPrimitive(JavaConstant.forInt(666)))); + assertEquals(Byte.valueOf((byte) 123), snippetReflection.asObject(Byte.class, constantReflection.boxPrimitive(JavaConstant.forByte((byte) 123)))); + assertSame(Boolean.TRUE, snippetReflection.asObject(Boolean.class, constantReflection.boxPrimitive(JavaConstant.forBoolean(true)))); assertNull(constantReflection.boxPrimitive(JavaConstant.NULL_POINTER)); assertNull(constantReflection.boxPrimitive(snippetReflection.forObject("abc"))); @@ -100,19 +100,4 @@ assertNull(constantReflection.unboxPrimitive(JavaConstant.NULL_POINTER)); assertNull(constantReflection.unboxPrimitive(snippetReflection.forObject("abc"))); } - - @Test - public void testAsJavaType() { - for (JavaConstant 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 8a2e6bc4384c -r 25a21e1794ec 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 Wed Nov 26 14:03:13 2014 +0100 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestMetaAccessProvider.java Wed Nov 26 17:14:49 2014 +0100 @@ -81,7 +81,7 @@ public void lookupJavaTypeConstantTest() { for (JavaConstant c : constants) { if (c.getKind() == Kind.Object && !c.isNull()) { - Object o = snippetReflection.asObject(c); + Object o = snippetReflection.asObject(Object.class, c); ResolvedJavaType type = metaAccess.lookupJavaType(c); assertNotNull(type); assertTrue(type.equals(metaAccess.lookupJavaType(o.getClass()))); diff -r 8a2e6bc4384c -r 25a21e1794ec 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 Wed Nov 26 14:03:13 2014 +0100 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaField.java Wed Nov 26 17:14:49 2014 +0100 @@ -22,7 +22,6 @@ */ package com.oracle.graal.api.meta.test; -import static java.lang.reflect.Modifier.*; import static org.junit.Assert.*; import java.lang.annotation.*; @@ -73,26 +72,6 @@ @Test public void readConstantValueTest() throws NoSuchFieldException { - for (Map.Entry e : fields.entrySet()) { - Field field = e.getKey(); - if (isStatic(field.getModifiers())) { - try { - Object expected = field.get(null); - Object actual = snippetReflection.asBoxedValue(constantReflection.readConstantFieldValue(e.getValue(), null)); - assertEquals(expected, actual); - } catch (IllegalArgumentException | IllegalAccessException e1) { - } - } else { - try { - Object receiver = field.getDeclaringClass().newInstance(); - Object expected = field.get(receiver); - Object actual = snippetReflection.asBoxedValue(constantReflection.readConstantFieldValue(e.getValue(), snippetReflection.forObject(receiver))); - assertEquals(expected, actual); - } catch (InstantiationException | IllegalArgumentException | IllegalAccessException e1) { - } - } - } - ResolvedJavaField field = metaAccess.lookupJavaField(getClass().getDeclaredField("stringField")); for (Object receiver : new Object[]{this, null, new String()}) { JavaConstant value = constantReflection.readConstantFieldValue(field, snippetReflection.forObject(receiver)); @@ -104,38 +83,11 @@ JavaConstant value = constantReflection.readConstantFieldValue(constField, snippetReflection.forObject(receiver)); if (value != null) { Object expected = "constantField"; - assertTrue(snippetReflection.asObject(value) == expected); + assertTrue(snippetReflection.asObject(Object.class, value) == expected); } } } - @Test - public void readValueTest() throws IllegalArgumentException, IllegalAccessException { - for (Map.Entry e : fields.entrySet()) { - Field field = e.getKey(); - field.setAccessible(true); - if (isStatic(field.getModifiers())) { - try { - Object expected = field.get(null); - Object actual = snippetReflection.asBoxedValue(constantReflection.readFieldValue(e.getValue(), null)); - assertEquals(expected, actual); - } catch (IllegalArgumentException | IllegalAccessException e1) { - } - } - } - - String testString = "a test string"; - testString.hashCode(); // create hash - for (Field f : String.class.getDeclaredFields()) { - f.setAccessible(true); - ResolvedJavaField rf = metaAccess.lookupJavaField(f); - Object receiver = isStatic(f.getModifiers()) ? null : testString; - Object expected = f.get(receiver); - Object actual = snippetReflection.asBoxedValue(constantReflection.readFieldValue(rf, receiver == null ? null : snippetReflection.forObject(receiver))); - assertEquals(expected, actual); - } - } - String stringField = "field"; final String constantStringField = "constantField"; diff -r 8a2e6bc4384c -r 25a21e1794ec 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 Wed Nov 26 14:03:13 2014 +0100 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaType.java Wed Nov 26 17:14:49 2014 +0100 @@ -124,7 +124,7 @@ public void isInstanceTest() { for (JavaConstant c : constants) { if (c.getKind() == Kind.Object && !c.isNull()) { - Object o = snippetReflection.asObject(c); + Object o = snippetReflection.asObject(Object.class, c); Class cls = o.getClass(); while (cls != null) { ResolvedJavaType type = metaAccess.lookupJavaType(cls); diff -r 8a2e6bc4384c -r 25a21e1794ec graal/com.oracle.graal.api.replacements/src/com/oracle/graal/api/replacements/SnippetReflectionProvider.java --- a/graal/com.oracle.graal.api.replacements/src/com/oracle/graal/api/replacements/SnippetReflectionProvider.java Wed Nov 26 14:03:13 2014 +0100 +++ b/graal/com.oracle.graal.api.replacements/src/com/oracle/graal/api/replacements/SnippetReflectionProvider.java Wed Nov 26 17:14:49 2014 +0100 @@ -22,6 +22,9 @@ */ package com.oracle.graal.api.replacements; +import java.lang.reflect.*; +import java.util.*; + import com.oracle.graal.api.meta.*; /** @@ -42,13 +45,31 @@ JavaConstant forObject(Object object); /** - * Returns the object reference the given constant represents. The constant must have kind - * {@link Kind#Object}. + * Gets the object reference a given constant represents if it is of a given type. The constant + * must have kind {@link Kind#Object}. * - * @param constant the to access - * @return the object value of the constant + * @param type the expected type of the object represented by {@code constant}. If the object is + * required to be of this type, then wrap the call to this method in + * {@link Objects#requireNonNull(Object)}. + * @param constant an object constant + * @return the object value represented by {@code constant} cast to {@code type} if it is an + * {@link Class#isInstance(Object) instance of} {@code type} otherwise {@code null} */ - Object asObject(JavaConstant constant); + T asObject(Class type, JavaConstant constant); + + /** + * Gets the object reference a given constant represents if it is of a given type. The constant + * must have kind {@link Kind#Object}. + * + * @param type the expected type of the object represented by {@code constant}. If the object is + * required to be of this type, then wrap the call to this method in + * {@link Objects#requireNonNull(Object)}. + * @param constant an object constant + * @return the object value represented by {@code constant} if it is an + * {@link ResolvedJavaType#isInstance(JavaConstant) instance of} {@code type} otherwise + * {@code null} + */ + Object asObject(ResolvedJavaType type, JavaConstant constant); /** * Creates a boxed constant for the given kind from an Object. The object needs to be of the @@ -61,12 +82,74 @@ JavaConstant forBoxed(Kind kind, Object value); /** - * Returns the value of this constant as a boxed Java value. + * Resolves a parameter or return type involved in snippet code to a {@link Class}. + */ + static Class resolveClassForSnippet(JavaType type) throws ClassNotFoundException { + try { + return Class.forName(type.toClassName()); + } catch (ClassNotFoundException e) { + // Support for -XX:-UseGraalClassLoader + return Class.forName(type.toClassName(), false, ClassLoader.getSystemClassLoader()); + } + } + + /** + * Invokes a given method via {@link Method#invoke(Object, Object...)}. + */ + default Object invoke(ResolvedJavaMethod method, Object receiver, Object... args) { + try { + JavaType[] parameterTypes = method.toParameterTypes(); + Class[] parameterClasses = new Class[parameterTypes.length]; + for (int i = 0; i < parameterClasses.length; ++i) { + JavaType type = parameterTypes[i]; + if (type.getKind() != Kind.Object) { + parameterClasses[i] = type.getKind().toJavaClass(); + } else { + parameterClasses[i] = resolveClassForSnippet(parameterTypes[i]); + } + } + + Class c = resolveClassForSnippet(method.getDeclaringClass()); + Method javaMethod = c.getDeclaredMethod(method.getName(), parameterClasses); + javaMethod.setAccessible(true); + return javaMethod.invoke(receiver, args); + } catch (IllegalAccessException | InvocationTargetException | ClassNotFoundException | NoSuchMethodException ex) { + throw new IllegalArgumentException(ex); + } + } + + /** + * Gets the constant value of this field. Note that a {@code static final} field may not be + * considered constant if its declaring class is not yet initialized or if it is a well known + * field that can be updated via other means (e.g., {@link System#setOut(java.io.PrintStream)}). * - * @param constant the constant to box - * @return the value of the constant + * @param receiver object from which this field's value is to be read. This value is ignored if + * this field is static. + * @return the constant value of this field or {@code null} if this field is not considered + * constant by the runtime */ - Object asBoxedValue(JavaConstant constant); + default Object readConstantFieldValue(JavaField field, Object receiver) { + try { + Class c = resolveClassForSnippet(field.getDeclaringClass()); + Field javaField = c.getDeclaredField(field.getName()); + javaField.setAccessible(true); + return javaField.get(receiver); + } catch (IllegalAccessException | ClassNotFoundException | NoSuchFieldException ex) { + throw new IllegalArgumentException(ex); + } + } + + /** + * Creates a new array with a given type as the component type and the specified length. This + * method is similar to {@link Array#newInstance(Class, int)}. + */ + default Object newArray(ResolvedJavaType componentType, int length) { + try { + return Array.newInstance(resolveClassForSnippet(componentType), length); + } catch (ClassNotFoundException e) { + throw new IllegalArgumentException(e); + } + } /** * Gets the value to bind to a parameter in a {@link SubstitutionGuard} constructor. diff -r 8a2e6bc4384c -r 25a21e1794ec 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 Wed Nov 26 14:03:13 2014 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/deopt/CompiledMethodTest.java Wed Nov 26 17:14:49 2014 +0100 @@ -56,7 +56,7 @@ new DeadCodeEliminationPhase().apply(graph); for (ConstantNode node : ConstantNode.getConstantNodes(graph)) { - if (node.getKind() == Kind.Object && " ".equals(getSnippetReflection().asObject(node.asJavaConstant()))) { + if (node.getKind() == Kind.Object && " ".equals(getSnippetReflection().asObject(String.class, node.asJavaConstant()))) { node.replace(graph, ConstantNode.forConstant(getSnippetReflection().forObject("-"), getMetaAccess(), graph)); } } diff -r 8a2e6bc4384c -r 25a21e1794ec graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotObjectConstant.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotObjectConstant.java Wed Nov 26 14:03:13 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotObjectConstant.java Wed Nov 26 17:14:49 2014 +0100 @@ -23,6 +23,7 @@ package com.oracle.graal.hotspot.meta; import java.lang.invoke.*; +import java.util.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; @@ -101,4 +102,28 @@ * Determines if this constant represents an {@linkplain String#intern() interned} string. */ boolean isInternedString(); + + /** + * Gets the object represented by this constant represents if it is of a given type. + * + * @param type the expected type of the object represented by this constant. If the object is + * required to be of this type, then wrap the call to this method in + * {@link Objects#requireNonNull(Object)}. + * @return the object value represented by this constant if it is an + * {@link ResolvedJavaType#isInstance(JavaConstant) instance of} {@code type} otherwise + * {@code null} + */ + T asObject(Class type); + + /** + * Gets the object represented by this constant represents if it is of a given type. + * + * @param type the expected type of the object represented by this constant. If the object is + * required to be of this type, then wrap the call to this method in + * {@link Objects#requireNonNull(Object)}. + * @return the object value represented by this constant if it is an + * {@link ResolvedJavaType#isInstance(JavaConstant) instance of} {@code type} otherwise + * {@code null} + */ + Object asObject(ResolvedJavaType type); } diff -r 8a2e6bc4384c -r 25a21e1794ec graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotObjectConstantImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotObjectConstantImpl.java Wed Nov 26 14:03:13 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotObjectConstantImpl.java Wed Nov 26 17:14:49 2014 +0100 @@ -205,6 +205,20 @@ return false; } + public T asObject(Class type) { + if (type.isInstance(object)) { + return type.cast(object); + } + return null; + } + + public Object asObject(ResolvedJavaType type) { + if (type.isInstance(this)) { + return object; + } + return null; + } + @Override public boolean isNull() { return false; diff -r 8a2e6bc4384c -r 25a21e1794ec graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSnippetReflectionProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSnippetReflectionProvider.java Wed Nov 26 14:03:13 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSnippetReflectionProvider.java Wed Nov 26 17:14:49 2014 +0100 @@ -40,8 +40,15 @@ } @Override - public Object asObject(JavaConstant constant) { - return ((HotSpotObjectConstantImpl) constant).object(); + public Object asObject(ResolvedJavaType type, JavaConstant constant) { + HotSpotObjectConstant hsConstant = (HotSpotObjectConstant) constant; + return hsConstant.asObject(type); + } + + @Override + public T asObject(Class type, JavaConstant constant) { + HotSpotObjectConstant hsConstant = (HotSpotObjectConstant) constant; + return hsConstant.asObject(type); } @Override @@ -49,11 +56,6 @@ return HotSpotObjectConstantImpl.forBoxedValue(kind, value); } - @Override - public Object asBoxedValue(JavaConstant constant) { - return HotSpotObjectConstantImpl.asBoxedValue(constant); - } - public Object getSubstitutionGuardParameter(Class type) { if (type.isInstance(runtime)) { return runtime; diff -r 8a2e6bc4384c -r 25a21e1794ec 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 Wed Nov 26 14:03:13 2014 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java Wed Nov 26 17:14:49 2014 +0100 @@ -86,7 +86,7 @@ ResolvedJavaType[] parameterTypes = resolveJavaTypes(target.toParameterTypes(), declaringClass); // Prepare the arguments for the reflective factory method call on the node class. - JavaConstant[] nodeFactoryArguments = prepareArguments(methodCallTargetNode, parameterTypes, target, false); + Object[] nodeFactoryArguments = prepareArguments(methodCallTargetNode, parameterTypes, target, false); if (nodeFactoryArguments == null) { return false; } @@ -105,7 +105,7 @@ ResolvedJavaType[] parameterTypes = resolveJavaTypes(target.toParameterTypes(), declaringClass); // Prepare the arguments for the reflective method call - JavaConstant[] arguments = prepareArguments(methodCallTargetNode, parameterTypes, target, true); + JavaConstant[] arguments = (JavaConstant[]) prepareArguments(methodCallTargetNode, parameterTypes, target, true); if (arguments == null) { return false; } @@ -156,9 +156,9 @@ * @return the arguments for the reflective invocation or null if an argument of {@code invoke} * that is expected to be constant isn't */ - private JavaConstant[] prepareArguments(MethodCallTargetNode methodCallTargetNode, ResolvedJavaType[] parameterTypes, ResolvedJavaMethod target, boolean folding) { + private Object[] prepareArguments(MethodCallTargetNode methodCallTargetNode, ResolvedJavaType[] parameterTypes, ResolvedJavaMethod target, boolean folding) { NodeInputList arguments = methodCallTargetNode.arguments(); - JavaConstant[] reflectionCallArguments = new JavaConstant[arguments.size()]; + Object[] reflectionCallArguments = folding ? new JavaConstant[arguments.size()] : new Object[arguments.size()]; for (int i = 0; i < reflectionCallArguments.length; ++i) { int parameterIndex = i; if (!methodCallTargetNode.isStatic()) { @@ -173,24 +173,34 @@ Constant constant = constantNode.asConstant(); ResolvedJavaType type = providers.getConstantReflection().asJavaType(constant); if (type != null) { - reflectionCallArguments[i] = snippetReflection.forObject(type); + reflectionCallArguments[i] = type; parameterTypes[i] = providers.getMetaAccess().lookupJavaType(ResolvedJavaType.class); } else { JavaConstant javaConstant = (JavaConstant) constant; if (parameterTypes[i].getKind() == Kind.Boolean) { - reflectionCallArguments[i] = snippetReflection.forObject(Boolean.valueOf(javaConstant.asInt() != 0)); + reflectionCallArguments[i] = Boolean.valueOf(javaConstant.asInt() != 0); } else if (parameterTypes[i].getKind() == Kind.Byte) { - reflectionCallArguments[i] = snippetReflection.forObject(Byte.valueOf((byte) javaConstant.asInt())); + reflectionCallArguments[i] = Byte.valueOf((byte) javaConstant.asInt()); } else if (parameterTypes[i].getKind() == Kind.Short) { - reflectionCallArguments[i] = snippetReflection.forObject(Short.valueOf((short) javaConstant.asInt())); + reflectionCallArguments[i] = Short.valueOf((short) javaConstant.asInt()); } else if (parameterTypes[i].getKind() == Kind.Char) { - reflectionCallArguments[i] = snippetReflection.forObject(Character.valueOf((char) javaConstant.asInt())); + reflectionCallArguments[i] = Character.valueOf((char) javaConstant.asInt()); + } else if (parameterTypes[i].getKind() == Kind.Object) { + if (!folding) { + reflectionCallArguments[i] = snippetReflection.asObject(parameterTypes[i], javaConstant); + } else { + reflectionCallArguments[i] = javaConstant; + } } else { - reflectionCallArguments[i] = javaConstant; + reflectionCallArguments[i] = javaConstant.asBoxedPrimitive(); } } + if (folding && reflectionCallArguments[i] != constant) { + assert !(reflectionCallArguments[i] instanceof JavaConstant); + reflectionCallArguments[i] = snippetReflection.forObject(reflectionCallArguments[i]); + } } else { - reflectionCallArguments[i] = snippetReflection.forObject(argument); + reflectionCallArguments[i] = argument; parameterTypes[i] = providers.getMetaAccess().lookupJavaType(ValueNode.class); } } @@ -210,13 +220,13 @@ } protected Node createNodeInstance(StructuredGraph graph, ResolvedJavaType nodeClass, ResolvedJavaType[] parameterTypes, Stamp invokeStamp, boolean setStampFromReturnType, - JavaConstant[] nodeFactoryArguments) { + Object[] nodeFactoryArguments) { ResolvedJavaMethod factory = null; - JavaConstant[] arguments = null; + Object[] arguments = null; for (ResolvedJavaMethod m : nodeClass.getDeclaredMethods()) { if (m.getName().equals("create") && !m.isSynthetic()) { - JavaConstant[] match = match(graph, invokeStamp, m, parameterTypes, nodeFactoryArguments); + Object[] match = match(graph, invokeStamp, m, parameterTypes, nodeFactoryArguments); if (match != null) { if (factory == null) { @@ -234,7 +244,7 @@ } try { - ValueNode intrinsicNode = (ValueNode) snippetReflection.asObject(invokeFactory(factory, arguments)); + ValueNode intrinsicNode = (ValueNode) snippetReflection.invoke(factory, null, arguments); if (setStampFromReturnType) { intrinsicNode.setStamp(invokeStamp); @@ -245,10 +255,6 @@ } } - protected JavaConstant invokeFactory(ResolvedJavaMethod factory, JavaConstant[] arguments) { - return factory.invoke(null, arguments); - } - private static String sigString(ResolvedJavaType[] types) { StringBuilder sb = new StringBuilder("("); for (int i = 0; i < types.length; i++) { @@ -260,39 +266,41 @@ return sb.append(")").toString(); } - private static boolean containsInjected(ResolvedJavaMethod c, int start, int end) { - for (int i = start; i < end; i++) { + private static boolean checkNoMoreInjected(ResolvedJavaMethod c, int start) { + int count = c.getSignature().getParameterCount(false); + for (int i = start; i < count; i++) { if (c.getParameterAnnotation(InjectedNodeParameter.class, i) != null) { - return true; + throw new GraalInternalError("Injected parameter %d of type %s must precede all non-injected parameters of %s", i, + c.getSignature().getParameterType(i, c.getDeclaringClass()).toJavaName(false), c.format("%H.%n(%p)")); } } - return false; + return true; } - private JavaConstant[] match(StructuredGraph graph, Stamp invokeStamp, ResolvedJavaMethod m, ResolvedJavaType[] parameterTypes, JavaConstant[] nodeFactoryArguments) { - JavaConstant[] arguments = null; - JavaConstant[] injected = null; + private Object[] match(StructuredGraph graph, Stamp invokeStamp, ResolvedJavaMethod m, ResolvedJavaType[] parameterTypes, Object[] nodeFactoryArguments) { + Object[] arguments = null; + Object[] injected = null; ResolvedJavaType[] signature = resolveJavaTypes(m.getSignature().toParameterTypes(null), m.getDeclaringClass()); MetaAccessProvider metaAccess = providers.getMetaAccess(); for (int i = 0; i < signature.length; i++) { if (m.getParameterAnnotation(InjectedNodeParameter.class, i) != null) { - injected = injected == null ? new JavaConstant[1] : Arrays.copyOf(injected, injected.length + 1); + injected = injected == null ? new Object[1] : Arrays.copyOf(injected, injected.length + 1); Object injectedParameter = snippetReflection.getInjectedNodeIntrinsicParameter(signature[i]); if (injectedParameter != null) { - injected[injected.length - 1] = snippetReflection.forObject(injectedParameter); + injected[injected.length - 1] = injectedParameter; } else if (signature[i].equals(metaAccess.lookupJavaType(MetaAccessProvider.class))) { - injected[injected.length - 1] = snippetReflection.forObject(metaAccess); + injected[injected.length - 1] = metaAccess; } else if (signature[i].equals(metaAccess.lookupJavaType(StructuredGraph.class))) { - injected[injected.length - 1] = snippetReflection.forObject(graph); + injected[injected.length - 1] = graph; } else if (signature[i].equals(metaAccess.lookupJavaType(ForeignCallsProvider.class))) { - injected[injected.length - 1] = snippetReflection.forObject(providers.getForeignCalls()); + injected[injected.length - 1] = providers.getForeignCalls(); } else if (signature[i].equals(metaAccess.lookupJavaType(SnippetReflectionProvider.class))) { - injected[injected.length - 1] = snippetReflection.forObject(snippetReflection); + injected[injected.length - 1] = snippetReflection; } else if (signature[i].isAssignableFrom(metaAccess.lookupJavaType(Stamp.class))) { - injected[injected.length - 1] = snippetReflection.forObject(invokeStamp); + injected[injected.length - 1] = invokeStamp; } else if (signature[i].isAssignableFrom(metaAccess.lookupJavaType(StampProvider.class))) { - injected[injected.length - 1] = snippetReflection.forObject(providers.getStampProvider()); + injected[injected.length - 1] = providers.getStampProvider(); } else { throw new GraalInternalError("Cannot handle injected argument of type %s in %s", signature[i].toJavaName(), m.format("%H.%n(%p)")); } @@ -301,7 +309,7 @@ // Chop injected arguments from signature signature = Arrays.copyOfRange(signature, i, signature.length); } - assert !containsInjected(m, i, signature.length); + assert checkNoMoreInjected(m, i); break; } } @@ -330,18 +338,22 @@ } } arguments = Arrays.copyOf(nodeFactoryArguments, fixedArgs + 1); - arguments[fixedArgs] = componentType.newArray(nodeFactoryArguments.length - fixedArgs); + arguments[fixedArgs] = snippetReflection.newArray(componentType, nodeFactoryArguments.length - fixedArgs); - Object varargs = snippetReflection.asObject(arguments[fixedArgs]); + Object varargs = arguments[fixedArgs]; for (int i = fixedArgs; i < nodeFactoryArguments.length; i++) { - Array.set(varargs, i - fixedArgs, snippetReflection.asBoxedValue(nodeFactoryArguments[i])); + if (componentType.isPrimitive()) { + Array.set(varargs, i - fixedArgs, nodeFactoryArguments[i]); + } else { + ((Object[]) varargs)[i - fixedArgs] = nodeFactoryArguments[i]; + } } } else { return null; } if (injected != null) { - JavaConstant[] copy = new JavaConstant[injected.length + arguments.length]; + Object[] copy = new Object[injected.length + arguments.length]; System.arraycopy(injected, 0, copy, 0, injected.length); System.arraycopy(arguments, 0, copy, injected.length, arguments.length); arguments = copy; diff -r 8a2e6bc4384c -r 25a21e1794ec 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 Wed Nov 26 14:03:13 2014 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Wed Nov 26 17:14:49 2014 +0100 @@ -433,7 +433,7 @@ } JavaConstant constantCallNode = node.asJavaConstant(); - Object value = snippetReflection.asObject(constantCallNode); + Object value = snippetReflection.asObject(Object.class, constantCallNode); if (!(value instanceof OptimizedDirectCallNode)) { // might be an indirect call. diff -r 8a2e6bc4384c -r 25a21e1794ec 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 Wed Nov 26 14:03:13 2014 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/AssumptionNode.java Wed Nov 26 17:14:49 2014 +0100 @@ -69,7 +69,7 @@ if (tool.assumptions() != null && assumption.isConstant()) { JavaConstant c = assumption.asJavaConstant(); assert c.getKind() == Kind.Object; - Object object = getSnippetReflection().asObject(c); + Object object = getSnippetReflection().asObject(Object.class, c); OptimizedAssumption assumptionObject = (OptimizedAssumption) object; StructuredGraph graph = graph(); if (assumptionObject.isValid()) { diff -r 8a2e6bc4384c -r 25a21e1794ec 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 Wed Nov 26 14:03:13 2014 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java Wed Nov 26 17:14:49 2014 +0100 @@ -87,7 +87,7 @@ private FrameDescriptor getConstantFrameDescriptor() { assert descriptor.isConstant() && !descriptor.isNullConstant(); - return (FrameDescriptor) getSnippetReflection().asObject(descriptor.asJavaConstant()); + return getSnippetReflection().asObject(FrameDescriptor.class, descriptor.asJavaConstant()); } private int getFrameSize() { diff -r 8a2e6bc4384c -r 25a21e1794ec graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/SnippetLocationNode.java --- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/SnippetLocationNode.java Wed Nov 26 14:03:13 2014 +0100 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/SnippetLocationNode.java Wed Nov 26 17:14:49 2014 +0100 @@ -85,7 +85,7 @@ @Override public Kind getValueKind() { if (valueKind.isConstant()) { - return (Kind) snippetReflection.asObject(valueKind.asJavaConstant()); + return snippetReflection.asObject(Kind.class, valueKind.asJavaConstant()); } throw new GraalInternalError("Cannot access kind yet because it is not constant: " + valueKind); } @@ -93,7 +93,8 @@ @Override public LocationIdentity getLocationIdentity() { if (locationIdentity.isConstant()) { - return (LocationIdentity) snippetReflection.asObject(locationIdentity.asJavaConstant()); + LocationIdentity identity = snippetReflection.asObject(LocationIdentity.class, locationIdentity.asJavaConstant()); + return identity; } // We do not know our actual location identity yet, so be conservative. return ANY_LOCATION; @@ -102,8 +103,8 @@ @Override public Node canonical(CanonicalizerTool tool) { if (valueKind.isConstant() && locationIdentity.isConstant() && displacement.isConstant() && (indexScaling == null || indexScaling.isConstant())) { - Kind constKind = (Kind) snippetReflection.asObject(valueKind.asJavaConstant()); - LocationIdentity constLocation = (LocationIdentity) snippetReflection.asObject(locationIdentity.asJavaConstant()); + Kind constKind = snippetReflection.asObject(Kind.class, valueKind.asJavaConstant()); + LocationIdentity constLocation = snippetReflection.asObject(LocationIdentity.class, locationIdentity.asJavaConstant()); long constDisplacement = displacement.asJavaConstant().asLong(); int constIndexScaling = indexScaling == null ? 0 : indexScaling.asJavaConstant().asInt(); diff -r 8a2e6bc4384c -r 25a21e1794ec 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 Wed Nov 26 14:03:13 2014 +0100 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java Wed Nov 26 17:14:49 2014 +0100 @@ -96,7 +96,7 @@ if (node.isConstant()) { ConstantNode oldConstant = (ConstantNode) node; assert oldConstant.asJavaConstant().getKind() == Kind.Object; - WordBase value = (WordBase) snippetReflection.asObject(oldConstant.asJavaConstant()); + WordBase value = snippetReflection.asObject(WordBase.class, oldConstant.asJavaConstant()); ConstantNode newConstant = ConstantNode.forIntegerKind(wordKind, value.rawValue(), node.graph()); graph.replaceFloating(oldConstant, newConstant); @@ -241,7 +241,7 @@ assert arguments.size() == 3; Kind readKind = asKind(callTargetNode.returnType()); LocationNode location = makeLocation(graph, arguments.get(1), readKind, ANY_LOCATION); - BarrierType barrierType = (BarrierType) snippetReflection.asObject(arguments.get(2).asJavaConstant()); + BarrierType barrierType = snippetReflection.asObject(BarrierType.class, arguments.get(2).asJavaConstant()); replace(invoke, readOp(graph, arguments.get(0), invoke, location, barrierType, true)); break; } @@ -381,7 +381,7 @@ protected LocationNode makeLocation(StructuredGraph graph, ValueNode offset, Kind readKind, ValueNode locationIdentity) { if (locationIdentity.isConstant()) { - return makeLocation(graph, offset, readKind, (LocationIdentity) snippetReflection.asObject(locationIdentity.asJavaConstant())); + return makeLocation(graph, offset, readKind, snippetReflection.asObject(LocationIdentity.class, locationIdentity.asJavaConstant())); } return SnippetLocationNode.create(snippetReflection, locationIdentity, ConstantNode.forConstant(snippetReflection.forObject(readKind), metaAccess, graph), ConstantNode.forLong(0, graph), fromSigned(graph, offset), ConstantNode.forInt(1, graph), graph);