# HG changeset patch # User Thomas Wuerthinger # Date 1423828474 -3600 # Node ID 343e0e71031b84240e7cd4f7462827b461590b1c # Parent 8d09a572da84f37e3f8139ff682b702fdb3dafa0# Parent dd7d436a7e19ff2333f7107be80350032d88f934 Merge. diff -r 8d09a572da84 -r 343e0e71031b graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java Fri Feb 13 12:48:27 2015 +0100 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java Fri Feb 13 12:54:34 2015 +0100 @@ -532,7 +532,9 @@ private Assumption[] assumptions; /** - * The list of the methods whose bytecodes were used as input to the compilation. + * The list of the methods whose bytecodes were used as input to the compilation. If + * {@code null}, then the compilation did not record method dependencies. Otherwise, the first + * element of this array is the root method of the compilation. */ private ResolvedJavaMethod[] methods; @@ -552,6 +554,9 @@ @Override public String toString() { + if (methods != null) { + return getClass().getName() + "[" + methods[0].format("%H.%n(%p)%r") + "]"; + } return identityHashCodeString(this); } @@ -629,17 +634,45 @@ /** * Sets the methods whose bytecodes were used as input to the compilation. + * + * @param rootMethod the root method of the compilation + * @param inlinedMethods the methods inlined during compilation */ - public void setMethods(ResolvedJavaMethod[] methods) { - this.methods = methods; + public void setMethods(ResolvedJavaMethod rootMethod, Collection inlinedMethods) { + assert rootMethod != null; + assert inlinedMethods != null; + if (inlinedMethods.contains(rootMethod)) { + methods = inlinedMethods.toArray(new ResolvedJavaMethod[inlinedMethods.size()]); + for (int i = 0; i < methods.length; i++) { + if (methods[i].equals(rootMethod)) { + if (i != 0) { + ResolvedJavaMethod tmp = methods[0]; + methods[0] = methods[i]; + methods[i] = tmp; + } + break; + } + } + } else { + methods = new ResolvedJavaMethod[1 + inlinedMethods.size()]; + methods[0] = rootMethod; + int i = 1; + for (ResolvedJavaMethod m : inlinedMethods) { + methods[i++] = m; + } + } } /** * Gets a fixed-size {@linkplain Arrays#asList(Object...) view} of the methods whose bytecodes * were used as input to the compilation. + * + * @return {@code null} if the compilation did not record method dependencies otherwise the + * methods whose bytecodes were used as input to the compilation with the first element + * being the root method of the compilation */ public Collection getMethods() { - return methods == null ? Collections.emptyList() : Arrays.asList(methods); + return methods == null ? null : Arrays.asList(methods); } public DataSection getDataSection() { diff -r 8d09a572da84 -r 343e0e71031b graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Fri Feb 13 12:48:27 2015 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Fri Feb 13 12:54:34 2015 +0100 @@ -280,7 +280,7 @@ LIRGenerationResult lirGen = null; lirGen = emitLIR(backend, target, schedule, graph, stub, cc, registerConfig, lirSuites); try (Scope s = Debug.scope("CodeGen", lirGen, lirGen.getLIR())) { - emitCode(backend, graph.getAssumptions(), graph.getMethods(), lirGen, compilationResult, installedCodeOwner, factory); + emitCode(backend, graph.getAssumptions(), graph.method(), graph.getInlinedMethods(), lirGen, compilationResult, installedCodeOwner, factory); } catch (Throwable e) { throw Debug.handle(e); } @@ -364,8 +364,8 @@ return lirGenRes; } - public static void emitCode(Backend backend, Assumptions assumptions, Set methods, LIRGenerationResult lirGenRes, CompilationResult compilationResult, - ResolvedJavaMethod installedCodeOwner, CompilationResultBuilderFactory factory) { + public static void emitCode(Backend backend, Assumptions assumptions, ResolvedJavaMethod rootMethod, Set inlinedMethods, LIRGenerationResult lirGenRes, + CompilationResult compilationResult, ResolvedJavaMethod installedCodeOwner, CompilationResultBuilderFactory factory) { FrameMap frameMap = lirGenRes.getFrameMap(); CompilationResultBuilder crb = backend.newCompilationResultBuilder(lirGenRes, frameMap, compilationResult, factory); backend.emitCode(crb, lirGenRes.getLIR(), installedCodeOwner); @@ -373,8 +373,8 @@ if (assumptions != null && !assumptions.isEmpty()) { compilationResult.setAssumptions(assumptions.toArray()); } - if (methods != null) { - compilationResult.setMethods(methods.toArray(new ResolvedJavaMethod[methods.size()])); + if (inlinedMethods != null) { + compilationResult.setMethods(rootMethod, inlinedMethods); } if (Debug.isMeterEnabled()) { diff -r 8d09a572da84 -r 343e0e71031b graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotMethodSubstitutionTest.java --- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotMethodSubstitutionTest.java Fri Feb 13 12:48:27 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotMethodSubstitutionTest.java Fri Feb 13 12:54:34 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2015, 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 @@ -33,25 +33,20 @@ */ public class HotSpotMethodSubstitutionTest extends MethodSubstitutionTest { - /* - * We have to ignore this test for now because currently there is no way to read uncompressed - * pointers in a compressed world via JNI. - */ - @Ignore @Test public void testObjectSubstitutions() { + TestClassA obj = new TestClassA(); + test("getClass0"); test("objectHashCode"); - Object obj = new Object(); - - assertDeepEquals("a string".getClass(), ObjectSubstitutions.getClass("a string")); - assertDeepEquals(obj.hashCode(), ObjectSubstitutions.hashCode(obj)); + test("getClass0", "a string"); + test("objectHashCode", obj); } @SuppressWarnings("all") - public static boolean getClass0(Object obj, Class clazz) { - return obj.getClass() == clazz; + public static Class getClass0(Object obj) { + return obj.getClass(); } @SuppressWarnings("all") @@ -59,15 +54,9 @@ return obj.hashCode(); } - /* - * We have to ignore this test for now because currently there is no way to read uncompressed - * pointers in a compressed world via JNI. - */ - @Ignore @Test public void testClassSubstitutions() { test("getModifiers"); - test("isInstance"); test("isInterface"); test("isArray"); test("isPrimitive"); @@ -75,15 +64,12 @@ test("getComponentType"); for (Class c : new Class[]{getClass(), Cloneable.class, int[].class, String[][].class}) { - assertDeepEquals(c.getModifiers(), ClassSubstitutions.getModifiers(c)); - assertDeepEquals(c.isInterface(), ClassSubstitutions.isInterface(c)); - assertDeepEquals(c.isArray(), ClassSubstitutions.isArray(c)); - assertDeepEquals(c.isPrimitive(), ClassSubstitutions.isPrimitive(c)); - assertDeepEquals(c.getSuperclass(), ClassSubstitutions.getSuperclass(c)); - assertDeepEquals(c.getComponentType(), ClassSubstitutions.getComponentType(c)); - for (Object o : new Object[]{this, new int[5], new String[2][], new Object()}) { - assertDeepEquals(c.isInstance(o), ClassSubstitutions.isInstance(c, o)); - } + test("getModifiers", c); + test("isInterface", c); + test("isArray", c); + test("isPrimitive", c); + test("getSuperClass", c); + test("getComponentType", c); } } @@ -93,11 +79,6 @@ } @SuppressWarnings("all") - public static boolean isInstance(Class clazz) { - return clazz.isInstance(Number.class); - } - - @SuppressWarnings("all") public static boolean isInterface(Class clazz) { return clazz.isInterface(); } @@ -122,11 +103,6 @@ return clazz.getComponentType(); } - /* - * We have to ignore this test for now because currently there is no way to read uncompressed - * pointers in a compressed world via JNI. - */ - @Ignore @Test public void testThreadSubstitutions() { test("currentThread"); @@ -134,13 +110,13 @@ test("threadInterrupted"); Thread currentThread = Thread.currentThread(); - assertDeepEquals(currentThread, ThreadSubstitutions.currentThread()); - assertDeepEquals(currentThread.isInterrupted(), ThreadSubstitutions.isInterrupted(currentThread, false)); + test("currentThread", currentThread); + test("threadIsInterrupted", currentThread); } @SuppressWarnings("all") - public static Thread currentThread() { - return Thread.currentThread(); + public static boolean currentThread(Thread other) { + return Thread.currentThread() == other; } @SuppressWarnings("all") @@ -161,7 +137,7 @@ SystemSubstitutions.currentTimeMillis(); SystemSubstitutions.nanoTime(); for (Object o : new Object[]{this, new int[5], new String[2][], new Object()}) { - assertDeepEquals(System.identityHashCode(o), SystemSubstitutions.identityHashCode(o)); + test("systemIdentityHashCode", o); } } diff -r 8d09a572da84 -r 343e0e71031b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Fri Feb 13 12:48:27 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Fri Feb 13 12:54:34 2015 +0100 @@ -208,7 +208,7 @@ if (graph == null || entryBCI != INVOCATION_ENTRY_BCI) { graph = new StructuredGraph(method, entryBCI, AllowAssumptions.from(OptAssumptions.getValue())); if (!recordEvolMethodDeps) { - graph.disableMethodRecording(); + graph.disableInlinedMethodRecording(); } } else { // Compiling method substitution - must clone the graph diff -r 8d09a572da84 -r 343e0e71031b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledRuntimeStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledRuntimeStub.java Fri Feb 13 12:48:27 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledRuntimeStub.java Fri Feb 13 12:54:34 2015 +0100 @@ -56,7 +56,7 @@ // Stubs cannot be recompiled so they cannot be compiled with // assumptions and there is no point in recording evol_method dependencies assert compResult.getAssumptions().isEmpty() : "stubs should not use assumptions: " + this; - assert compResult.getMethods().isEmpty() : "stubs should not record evol_method dependencies: " + this; + assert compResult.getMethods() == null : "stubs should not record evol_method dependencies: " + this; for (DataPatch data : compResult.getDataPatches()) { if (data.reference instanceof ConstantReference) { diff -r 8d09a572da84 -r 343e0e71031b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java Fri Feb 13 12:48:27 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java Fri Feb 13 12:54:34 2015 +0100 @@ -119,6 +119,10 @@ if (graph.getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) { instanceofSnippets.lower((InstanceOfDynamicNode) n, tool); } + } else if (n instanceof ClassIsAssignableFromNode) { + if (graph.getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) { + instanceofSnippets.lower((ClassIsAssignableFromNode) n, tool); + } } else if (n instanceof NewInstanceNode) { if (graph.getGuardsStage().areFrameStatesAtDeopts()) { newObjectSnippets.lower((NewInstanceNode) n, registers, tool); diff -r 8d09a572da84 -r 343e0e71031b 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 Fri Feb 13 12:48:27 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassCastNode.java Fri Feb 13 12:54:34 2015 +0100 @@ -33,7 +33,7 @@ /** * {@link MacroNode Macro node} for {@link Class#cast(Object)}. * - * @see ClassSubstitutions#cast(Class, Object) + * @see HotSpotClassSubstitutions#cast(Class, Object) */ @NodeInfo public final class ClassCastNode extends MacroStateSplitNode implements Canonicalizable.Binary { diff -r 8d09a572da84 -r 343e0e71031b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetClassLoader0Node.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetClassLoader0Node.java Fri Feb 13 12:48:27 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetClassLoader0Node.java Fri Feb 13 12:54:34 2015 +0100 @@ -34,7 +34,7 @@ /** * {@link MacroNode Macro node} for {@link Class#getClassLoader0()}. * - * @see ClassSubstitutions#getClassLoader0(Class) + * @see HotSpotClassSubstitutions#getClassLoader0(Class) */ @SuppressWarnings("javadoc") @NodeInfo diff -r 8d09a572da84 -r 343e0e71031b 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 Fri Feb 13 12:48:27 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetComponentTypeNode.java Fri Feb 13 12:54:34 2015 +0100 @@ -34,7 +34,7 @@ /** * {@link MacroNode Macro node} for {@link Class#getComponentType()}. * - * @see ClassSubstitutions#getComponentType(Class) + * @see HotSpotClassSubstitutions#getComponentType(Class) */ @NodeInfo public final class ClassGetComponentTypeNode extends MacroNode implements Canonicalizable { diff -r 8d09a572da84 -r 343e0e71031b 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 Fri Feb 13 12:48:27 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetModifiersNode.java Fri Feb 13 12:54:34 2015 +0100 @@ -33,7 +33,7 @@ /** * {@link MacroNode Macro node} for {@link Class#getModifiers()}. * - * @see ClassSubstitutions#getModifiers(Class) + * @see HotSpotClassSubstitutions#getModifiers(Class) */ @NodeInfo public final class ClassGetModifiersNode extends MacroNode implements Canonicalizable { diff -r 8d09a572da84 -r 343e0e71031b 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 Fri Feb 13 12:48:27 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetSuperclassNode.java Fri Feb 13 12:54:34 2015 +0100 @@ -34,7 +34,7 @@ /** * {@link MacroNode Macro node} for {@link Class#getSuperclass()}. * - * @see ClassSubstitutions#getSuperclass(Class) + * @see HotSpotClassSubstitutions#getSuperclass(Class) */ @NodeInfo public final class ClassGetSuperclassNode extends MacroNode implements Canonicalizable { diff -r 8d09a572da84 -r 343e0e71031b 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 Fri Feb 13 12:48:27 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsArrayNode.java Fri Feb 13 12:54:34 2015 +0100 @@ -33,7 +33,7 @@ /** * {@link MacroNode Macro node} for {@link Class#isArray()}. * - * @see ClassSubstitutions#isArray(Class) + * @see HotSpotClassSubstitutions#isArray(Class) */ @NodeInfo public final class ClassIsArrayNode extends MacroNode implements Canonicalizable { diff -r 8d09a572da84 -r 343e0e71031b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsAssignableFromNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsAssignableFromNode.java Fri Feb 13 12:48:27 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,66 +0,0 @@ -/* - * 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.nodes; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; -import com.oracle.graal.graph.spi.*; -import com.oracle.graal.hotspot.replacements.*; -import com.oracle.graal.nodeinfo.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.replacements.nodes.*; - -/** - * {@link MacroNode Macro node} for {@link Class#isAssignableFrom(Class)}. - * - * @see ClassSubstitutions#isAssignableFrom(Class, Class) - */ -@NodeInfo -public final class ClassIsAssignableFromNode extends MacroStateSplitNode implements Canonicalizable { - public ClassIsAssignableFromNode(Invoke invoke) { - super(invoke); - } - - private ValueNode getJavaClass() { - return arguments.get(0); - } - - private ValueNode getOtherClass() { - return arguments.get(1); - } - - @Override - public Node canonical(CanonicalizerTool tool) { - ValueNode javaClass = getJavaClass(); - ValueNode otherClass = getOtherClass(); - if (javaClass.isConstant() && otherClass.isConstant()) { - ConstantReflectionProvider constantReflection = tool.getConstantReflection(); - ResolvedJavaType thisType = constantReflection.asJavaType(javaClass.asJavaConstant()); - ResolvedJavaType otherType = constantReflection.asJavaType(otherClass.asJavaConstant()); - if (thisType != null && otherType != null) { - return ConstantNode.forBoolean(thisType.isAssignableFrom(otherType)); - } - } - return this; - } -} diff -r 8d09a572da84 -r 343e0e71031b 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 Fri Feb 13 12:48:27 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.hotspot.nodes; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; -import com.oracle.graal.graph.spi.*; -import com.oracle.graal.hotspot.replacements.*; -import com.oracle.graal.nodeinfo.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.java.*; -import com.oracle.graal.replacements.nodes.*; - -/** - * {@link MacroNode Macro node} for {@link Class#isInstance(Object)}. - * - * @see ClassSubstitutions#isInstance(Class, Object) - */ -@NodeInfo -public final class ClassIsInstanceNode extends MacroNode implements Canonicalizable { - - public ClassIsInstanceNode(Invoke invoke) { - super(invoke); - } - - private ValueNode getJavaClass() { - return arguments.get(0); - } - - private ValueNode getObject() { - return arguments.get(1); - } - - @Override - public Node canonical(CanonicalizerTool tool) { - ValueNode javaClass = getJavaClass(); - if (javaClass.isConstant()) { - ValueNode object = getObject(); - ConstantReflectionProvider constantReflection = tool.getConstantReflection(); - ResolvedJavaType type = constantReflection.asJavaType(javaClass.asConstant()); - if (type != null) { - if (type.isPrimitive()) { - return ConstantNode.forBoolean(false); - } - if (object.isConstant()) { - JavaConstant c = object.asJavaConstant(); - return ConstantNode.forBoolean(c.isNonNull() && type.isInstance(c)); - } - InstanceOfNode instanceOf = new InstanceOfNode(type, object, null); - return new ConditionalNode(instanceOf, ConstantNode.forBoolean(true), ConstantNode.forBoolean(false)); - } - } - return this; - } -} diff -r 8d09a572da84 -r 343e0e71031b 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 Fri Feb 13 12:48:27 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsInterfaceNode.java Fri Feb 13 12:54:34 2015 +0100 @@ -33,7 +33,7 @@ /** * {@link MacroNode Macro node} for {@link Class#isInterface()}. * - * @see ClassSubstitutions#isInterface(Class) + * @see HotSpotClassSubstitutions#isInterface(Class) */ @NodeInfo public final class ClassIsInterfaceNode extends MacroNode implements Canonicalizable { diff -r 8d09a572da84 -r 343e0e71031b 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 Fri Feb 13 12:48:27 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsPrimitiveNode.java Fri Feb 13 12:54:34 2015 +0100 @@ -33,7 +33,7 @@ /** * {@link MacroNode Macro node} for {@link Class#isPrimitive()}. * - * @see ClassSubstitutions#isPrimitive(Class) + * @see HotSpotClassSubstitutions#isPrimitive(Class) */ @NodeInfo public final class ClassIsPrimitiveNode extends MacroNode implements Canonicalizable { diff -r 8d09a572da84 -r 343e0e71031b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ClassSubstitutions.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ClassSubstitutions.java Fri Feb 13 12:48:27 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,160 +0,0 @@ -/* - * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.hotspot.replacements; - -import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; -import static com.oracle.graal.nodes.PiNode.*; - -import java.lang.reflect.*; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.replacements.*; -import com.oracle.graal.hotspot.nodes.*; -import com.oracle.graal.hotspot.word.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.word.*; - -/** - * Substitutions for {@link java.lang.Class} methods. - */ -@ClassSubstitution(java.lang.Class.class) -public class ClassSubstitutions { - - @MacroSubstitution(macro = ClassGetModifiersNode.class, isStatic = false) - @MethodSubstitution(isStatic = false, forced = true) - public static int getModifiers(final Class thisObj) { - KlassPointer klass = ClassGetHubNode.readClass(thisObj); - if (klass.isNull()) { - // Class for primitive type - return Modifier.ABSTRACT | Modifier.FINAL | Modifier.PUBLIC; - } else { - return klass.readInt(klassModifierFlagsOffset(), KLASS_MODIFIER_FLAGS_LOCATION); - } - } - - // This MacroSubstitution should be removed once non-null klass pointers can be optimized - @MacroSubstitution(macro = ClassIsInterfaceNode.class, isStatic = false) - @MethodSubstitution(isStatic = false, forced = true) - public static boolean isInterface(final Class thisObj) { - KlassPointer klass = ClassGetHubNode.readClass(thisObj); - if (klass.isNull()) { - return false; - } else { - int accessFlags = klass.readInt(klassAccessFlagsOffset(), KLASS_ACCESS_FLAGS_LOCATION); - return (accessFlags & Modifier.INTERFACE) != 0; - } - } - - // This MacroSubstitution should be removed once non-null klass pointers can be optimized - @MacroSubstitution(macro = ClassIsArrayNode.class, isStatic = false) - @MethodSubstitution(isStatic = false, forced = true) - public static boolean isArray(final Class thisObj) { - KlassPointer klass = ClassGetHubNode.readClass(thisObj); - if (klass.isNull()) { - return false; - } else { - return klassIsArray(klass); - } - } - - // This MacroSubstitution should be removed once non-null klass pointers can be optimized - @MacroSubstitution(macro = ClassIsPrimitiveNode.class, isStatic = false) - @MethodSubstitution(isStatic = false, forced = true) - public static boolean isPrimitive(final Class thisObj) { - KlassPointer klass = ClassGetHubNode.readClass(thisObj); - return klass.isNull(); - } - - @MacroSubstitution(macro = ClassGetClassLoader0Node.class, isStatic = false) - public static native ClassLoader getClassLoader0(Class thisObj); - - @MacroSubstitution(macro = ClassGetSuperclassNode.class, isStatic = false) - @MethodSubstitution(isStatic = false) - public static Class getSuperclass(final Class thisObj) { - KlassPointer klass = ClassGetHubNode.readClass(thisObj); - if (!klass.isNull()) { - int accessFlags = klass.readInt(klassAccessFlagsOffset(), KLASS_ACCESS_FLAGS_LOCATION); - if ((accessFlags & Modifier.INTERFACE) == 0) { - if (klassIsArray(klass)) { - return Object.class; - } else { - Word superKlass = klass.readWord(klassSuperKlassOffset(), KLASS_SUPER_KLASS_LOCATION); - if (superKlass.equal(0)) { - return null; - } else { - return readJavaMirror(superKlass); - } - } - } - } - return null; - } - - public static Class readJavaMirror(Word klass) { - return piCastExactNonNull(klass.readObject(classMirrorOffset(), CLASS_MIRROR_LOCATION), Class.class); - } - - @MacroSubstitution(macro = ClassGetComponentTypeNode.class, isStatic = false) - @MethodSubstitution(isStatic = false) - public static Class getComponentType(final Class thisObj) { - KlassPointer klass = ClassGetHubNode.readClass(thisObj); - if (!klass.isNull()) { - if (klassIsArray(klass)) { - return piCastExactNonNull(klass.readObject(arrayKlassComponentMirrorOffset(), ARRAY_KLASS_COMPONENT_MIRROR), Class.class); - } - } - return null; - } - - @MacroSubstitution(macro = ClassIsInstanceNode.class, isStatic = false) - @MethodSubstitution(isStatic = false) - public static boolean isInstance(Class thisObj, Object obj) { - return ConditionalNode.materializeIsInstance(thisObj, obj); - } - - @MacroSubstitution(macro = ClassIsAssignableFromNode.class, isStatic = false) - @MethodSubstitution(isStatic = false) - public static boolean isAssignableFrom(Class thisClass, Class otherClass) { - if (BranchProbabilityNode.probability(BranchProbabilityNode.NOT_LIKELY_PROBABILITY, otherClass == null)) { - DeoptimizeNode.deopt(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.NullCheckException); - return false; - } - GuardingNode anchorNode = SnippetAnchorNode.anchor(); - KlassPointer thisHub = ClassGetHubNode.readClass(thisClass, anchorNode); - KlassPointer otherHub = ClassGetHubNode.readClass(otherClass, anchorNode); - if (thisHub.isNull() || otherHub.isNull()) { - // primitive types, only true if equal. - return thisClass == otherClass; - } - if (!TypeCheckSnippetUtils.checkUnknownSubType(thisHub, otherHub)) { - return false; - } - return true; - } - - @MacroSubstitution(macro = ClassCastNode.class, isStatic = false) - public static native Object cast(final Class thisObj, Object obj); -} diff -r 8d09a572da84 -r 343e0e71031b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CompilerToVMImplSubstitutions.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CompilerToVMImplSubstitutions.java Fri Feb 13 12:48:27 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CompilerToVMImplSubstitutions.java Fri Feb 13 12:54:34 2015 +0100 @@ -34,6 +34,6 @@ @MethodSubstitution(isStatic = false) public static Class getJavaMirror(@SuppressWarnings("unused") CompilerToVMImpl impl, long metaspaceklass) { - return ClassSubstitutions.readJavaMirror(Word.unsigned(metaspaceklass)); + return HotSpotClassSubstitutions.readJavaMirror(Word.unsigned(metaspaceklass)); } } diff -r 8d09a572da84 -r 343e0e71031b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotClassSubstitutions.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotClassSubstitutions.java Fri Feb 13 12:54:34 2015 +0100 @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.hotspot.replacements; + +import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; +import static com.oracle.graal.nodes.PiNode.*; + +import java.lang.reflect.*; + +import com.oracle.graal.api.replacements.*; +import com.oracle.graal.hotspot.nodes.*; +import com.oracle.graal.hotspot.word.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.word.*; + +/** + * Substitutions for {@link java.lang.Class} methods. + */ +@ClassSubstitution(java.lang.Class.class) +public class HotSpotClassSubstitutions { + + @MacroSubstitution(macro = ClassGetModifiersNode.class, isStatic = false) + @MethodSubstitution(isStatic = false, forced = true) + public static int getModifiers(final Class thisObj) { + KlassPointer klass = ClassGetHubNode.readClass(thisObj); + if (klass.isNull()) { + // Class for primitive type + return Modifier.ABSTRACT | Modifier.FINAL | Modifier.PUBLIC; + } else { + return klass.readInt(klassModifierFlagsOffset(), KLASS_MODIFIER_FLAGS_LOCATION); + } + } + + // This MacroSubstitution should be removed once non-null klass pointers can be optimized + @MacroSubstitution(macro = ClassIsInterfaceNode.class, isStatic = false) + @MethodSubstitution(isStatic = false, forced = true) + public static boolean isInterface(final Class thisObj) { + KlassPointer klass = ClassGetHubNode.readClass(thisObj); + if (klass.isNull()) { + return false; + } else { + int accessFlags = klass.readInt(klassAccessFlagsOffset(), KLASS_ACCESS_FLAGS_LOCATION); + return (accessFlags & Modifier.INTERFACE) != 0; + } + } + + // This MacroSubstitution should be removed once non-null klass pointers can be optimized + @MacroSubstitution(macro = ClassIsArrayNode.class, isStatic = false) + @MethodSubstitution(isStatic = false, forced = true) + public static boolean isArray(final Class thisObj) { + KlassPointer klass = ClassGetHubNode.readClass(thisObj); + if (klass.isNull()) { + return false; + } else { + return klassIsArray(klass); + } + } + + // This MacroSubstitution should be removed once non-null klass pointers can be optimized + @MacroSubstitution(macro = ClassIsPrimitiveNode.class, isStatic = false) + @MethodSubstitution(isStatic = false, forced = true) + public static boolean isPrimitive(final Class thisObj) { + KlassPointer klass = ClassGetHubNode.readClass(thisObj); + return klass.isNull(); + } + + @MacroSubstitution(macro = ClassGetClassLoader0Node.class, isStatic = false) + public static native ClassLoader getClassLoader0(Class thisObj); + + @MacroSubstitution(macro = ClassGetSuperclassNode.class, isStatic = false) + @MethodSubstitution(isStatic = false) + public static Class getSuperclass(final Class thisObj) { + KlassPointer klass = ClassGetHubNode.readClass(thisObj); + if (!klass.isNull()) { + int accessFlags = klass.readInt(klassAccessFlagsOffset(), KLASS_ACCESS_FLAGS_LOCATION); + if ((accessFlags & Modifier.INTERFACE) == 0) { + if (klassIsArray(klass)) { + return Object.class; + } else { + Word superKlass = klass.readWord(klassSuperKlassOffset(), KLASS_SUPER_KLASS_LOCATION); + if (superKlass.equal(0)) { + return null; + } else { + return readJavaMirror(superKlass); + } + } + } + } + return null; + } + + public static Class readJavaMirror(Word klass) { + return piCastExactNonNull(klass.readObject(classMirrorOffset(), CLASS_MIRROR_LOCATION), Class.class); + } + + @MacroSubstitution(macro = ClassGetComponentTypeNode.class, isStatic = false) + @MethodSubstitution(isStatic = false) + public static Class getComponentType(final Class thisObj) { + KlassPointer klass = ClassGetHubNode.readClass(thisObj); + if (!klass.isNull()) { + if (klassIsArray(klass)) { + return piCastExactNonNull(klass.readObject(arrayKlassComponentMirrorOffset(), ARRAY_KLASS_COMPONENT_MIRROR), Class.class); + } + } + return null; + } + + @MacroSubstitution(macro = ClassCastNode.class, isStatic = false) + public static native Object cast(final Class thisObj, Object obj); +} diff -r 8d09a572da84 -r 343e0e71031b 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 Fri Feb 13 12:48:27 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotSubstitutions.java Fri Feb 13 12:54:34 2015 +0100 @@ -60,7 +60,7 @@ replacements.registerSubstitutions(System.class, SystemSubstitutions.class); replacements.registerSubstitutions(Thread.class, ThreadSubstitutions.class); replacements.registerSubstitutions(Unsafe.class, UnsafeSubstitutions.class); - replacements.registerSubstitutions(Class.class, ClassSubstitutions.class); + replacements.registerSubstitutions(Class.class, HotSpotClassSubstitutions.class); replacements.registerSubstitutions(CRC32.class, CRC32Substitutions.class); replacements.registerSubstitutions(Reflection.class, ReflectionSubstitutions.class); replacements.registerSubstitutions(NodeClass.class, HotSpotNodeClassSubstitutions.class); diff -r 8d09a572da84 -r 343e0e71031b 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 Fri Feb 13 12:48:27 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java Fri Feb 13 12:54:34 2015 +0100 @@ -32,6 +32,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.api.meta.ProfilingInfo.TriState; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.nodes.*; @@ -194,6 +195,25 @@ return trueValue; } + @Snippet + public static Object isAssignableFrom(Class thisClass, Class otherClass, Object trueValue, Object falseValue) { + if (BranchProbabilityNode.probability(BranchProbabilityNode.NOT_FREQUENT_PROBABILITY, otherClass == null)) { + DeoptimizeNode.deopt(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.NullCheckException); + return false; + } + GuardingNode anchorNode = SnippetAnchorNode.anchor(); + KlassPointer thisHub = ClassGetHubNode.readClass(thisClass, anchorNode); + KlassPointer otherHub = ClassGetHubNode.readClass(otherClass, anchorNode); + if (thisHub.isNull() || otherHub.isNull()) { + // primitive types, only true if equal. + return thisClass == otherClass ? trueValue : falseValue; + } + if (!TypeCheckSnippetUtils.checkUnknownSubType(thisHub, otherHub)) { + return falseValue; + } + return trueValue; + } + static class Options { // @formatter:off @@ -214,6 +234,7 @@ private final SnippetInfo instanceofPrimary = snippet(InstanceOfSnippets.class, "instanceofPrimary"); private final SnippetInfo instanceofSecondary = snippet(InstanceOfSnippets.class, "instanceofSecondary"); private final SnippetInfo instanceofDynamic = snippet(InstanceOfSnippets.class, "instanceofDynamic"); + private final SnippetInfo isAssignableFrom = snippet(InstanceOfSnippets.class, "isAssignableFrom"); private final long compilationThreshold; public Templates(HotSpotProviders providers, TargetDescription target, long compilationThreshold) { @@ -264,8 +285,7 @@ } return args; - } else { - assert replacer.instanceOf instanceof InstanceOfDynamicNode; + } else if (replacer.instanceOf instanceof InstanceOfDynamicNode) { InstanceOfDynamicNode instanceOf = (InstanceOfDynamicNode) replacer.instanceOf; ValueNode object = instanceOf.object(); @@ -275,6 +295,16 @@ args.add("trueValue", replacer.trueValue); args.add("falseValue", replacer.falseValue); return args; + } else if (replacer.instanceOf instanceof ClassIsAssignableFromNode) { + ClassIsAssignableFromNode isAssignable = (ClassIsAssignableFromNode) replacer.instanceOf; + Arguments args = new Arguments(isAssignableFrom, isAssignable.graph().getGuardsStage(), tool.getLoweringStage()); + args.add("thisClass", isAssignable.getThisClass()); + args.add("otherClass", isAssignable.getOtherClass()); + args.add("trueValue", replacer.trueValue); + args.add("falseValue", replacer.falseValue); + return args; + } else { + throw GraalInternalError.shouldNotReachHere(); } } } diff -r 8d09a572da84 -r 343e0e71031b 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 Fri Feb 13 12:48:27 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java Fri Feb 13 12:54:34 2015 +0100 @@ -192,7 +192,7 @@ boolean isObjectResult = linkage.getOutgoingCallingConvention().getReturn().getKind() == Kind.Object; StructuredGraph graph = new StructuredGraph(toString(), null, AllowAssumptions.NO); - graph.disableMethodRecording(); + graph.disableInlinedMethodRecording(); GraphKit kit = new HotSpotGraphKit(graph, providers); ParameterNode[] params = createParameters(kit, args); diff -r 8d09a572da84 -r 343e0e71031b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java Fri Feb 13 12:48:27 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java Fri Feb 13 12:54:34 2015 +0100 @@ -161,7 +161,7 @@ // Stubs cannot be recompiled so they cannot be compiled with // assumptions and there is no point in recording evol_method dependencies assert graph.getAssumptions() == null; - assert !graph.isMethodRecordingEnabled() : graph; + assert !graph.isInlinedMethodRecordingEnabled() : graph; if (!(graph.start() instanceof StubStartNode)) { StubStartNode newStart = graph.add(new StubStartNode(Stub.this)); diff -r 8d09a572da84 -r 343e0e71031b 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 Fri Feb 13 12:48:27 2015 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Fri Feb 13 12:54:34 2015 +0100 @@ -971,9 +971,9 @@ calleeBeforeUnwindNode.setNext(handleException(calleeUnwindValue, bci())); } - // Record method dependency in the graph - if (currentGraph.isMethodRecordingEnabled()) { - currentGraph.getMethods().add(targetMethod); + // Record inlined method dependency in the graph + if (currentGraph.isInlinedMethodRecordingEnabled()) { + currentGraph.getInlinedMethods().add(targetMethod); } } diff -r 8d09a572da84 -r 343e0e71031b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java Fri Feb 13 12:48:27 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java Fri Feb 13 12:54:34 2015 +0100 @@ -112,9 +112,9 @@ private final Assumptions assumptions; /** - * The methods whose bytecodes are used while constructing this graph. + * The methods that were inlined while constructing this graph. */ - private Set methods = new HashSet<>(); + private Set inlinedMethods = new HashSet<>(); /** * Creates a new Graph containing a single {@link AbstractBeginNode} as the {@link #start() @@ -220,16 +220,16 @@ } public StructuredGraph copy(String newName, ResolvedJavaMethod newMethod) { - return copy(newName, newMethod, AllowAssumptions.from(assumptions != null), isMethodRecordingEnabled()); + return copy(newName, newMethod, AllowAssumptions.from(assumptions != null), isInlinedMethodRecordingEnabled()); } - public StructuredGraph copy(String newName, ResolvedJavaMethod newMethod, AllowAssumptions allowAssumptions, boolean enableMethodRecording) { + public StructuredGraph copy(String newName, ResolvedJavaMethod newMethod, AllowAssumptions allowAssumptions, boolean enableInlinedMethodRecording) { StructuredGraph copy = new StructuredGraph(newName, newMethod, graphId, entryBCI, allowAssumptions); if (allowAssumptions == AllowAssumptions.YES && assumptions != null) { copy.assumptions.record(assumptions); } - if (!enableMethodRecording) { - copy.disableMethodRecording(); + if (!enableInlinedMethodRecording) { + copy.disableInlinedMethodRecording(); } copy.setGuardsStage(getGuardsStage()); copy.isAfterFloatingReadPhase = isAfterFloatingReadPhase; @@ -512,26 +512,26 @@ } /** - * Disables recording of method used while constructing this graph. This can be done at most - * once and must be done before any methods are recorded. + * Disables recording of methods inlined while constructing this graph. This can be done at most + * once and must be done before any inlined methods are recorded. */ - public void disableMethodRecording() { - assert methods != null : "cannot disable method recording more than once"; - assert methods.isEmpty() : "cannot disable method recording once methods have been recorded"; - methods = null; + public void disableInlinedMethodRecording() { + assert inlinedMethods != null : "cannot disable inlined method recording more than once"; + assert inlinedMethods.isEmpty() : "cannot disable inlined method recording once methods have been recorded"; + inlinedMethods = null; } - public boolean isMethodRecordingEnabled() { - return methods != null; + public boolean isInlinedMethodRecordingEnabled() { + return inlinedMethods != null; } /** - * Gets the methods whose bytecodes are used while constructing this graph. + * Gets the methods that were inlined while constructing this graph. * - * @return {@code null} if method recording has been {@linkplain #disableMethodRecording() - * disabled} + * @return {@code null} if inlined method recording has been + * {@linkplain #disableInlinedMethodRecording() disabled} */ - public Set getMethods() { - return methods; + public Set getInlinedMethods() { + return inlinedMethods; } } diff -r 8d09a572da84 -r 343e0e71031b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConditionalNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConditionalNode.java Fri Feb 13 12:48:27 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConditionalNode.java Fri Feb 13 12:54:34 2015 +0100 @@ -157,4 +157,24 @@ public static boolean materializeIsInstance(Class mirror, Object object) { return mirror.isInstance(object); } + + /** + * @param thisClass + * @param otherClass + * @param dummy a marker to make this constructor unique for the + * {@link #materializeIsAssignableFrom(Class, Class, int)} NodeIntrinsic + */ + public ConditionalNode(ValueNode thisClass, ValueNode otherClass, int dummy) { + this(thisClass.graph().unique(new ClassIsAssignableFromNode(thisClass, otherClass))); + } + + @SuppressWarnings("unused") + @NodeIntrinsic + private static boolean materializeIsAssignableFrom(Class thisClass, Class otherClass, @ConstantNodeParameter int dummy) { + return thisClass.isAssignableFrom(otherClass); + } + + public static boolean materializeIsAssignableFrom(Class thisClass, Class otherClass) { + return materializeIsAssignableFrom(thisClass, otherClass, 0); + } } diff -r 8d09a572da84 -r 343e0e71031b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ComputeAddressNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ComputeAddressNode.java Fri Feb 13 12:48:27 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ComputeAddressNode.java Fri Feb 13 12:54:34 2015 +0100 @@ -52,6 +52,6 @@ @Override public void generate(NodeLIRBuilderTool gen) { Value addr = getLocation().generateAddress(gen, gen.getLIRGeneratorTool(), gen.operand(getObject())); - gen.setResult(this, addr); + gen.setResult(this, gen.getLIRGeneratorTool().asAllocatable(addr)); } } diff -r 8d09a572da84 -r 343e0e71031b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ClassIsAssignableFromNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ClassIsAssignableFromNode.java Fri Feb 13 12:54:34 2015 +0100 @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2014, 2015, 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.java; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; +import com.oracle.graal.nodeinfo.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.spi.*; + +/** + * The {@code ClassIsAssignableFromNode} represents a type check against {@link Class} instead of + * against instances. This is used, for instance, to intrinsify + * {@link Class#isAssignableFrom(Class)} . + */ +@NodeInfo +public final class ClassIsAssignableFromNode extends LogicNode implements Canonicalizable.Binary, Lowerable { + @Input ValueNode thisClass; + @Input ValueNode otherClass; + + public ClassIsAssignableFromNode(ValueNode thisClass, ValueNode otherClass) { + this.thisClass = thisClass; + this.otherClass = otherClass; + } + + public Object getThisClass() { + return thisClass; + } + + public Object getOtherClass() { + return otherClass; + } + + @Override + public ValueNode getX() { + return thisClass; + } + + @Override + public ValueNode getY() { + return otherClass; + } + + @Override + public Node canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { + if (forX.isConstant() && forY.isConstant()) { + ConstantReflectionProvider constantReflection = tool.getConstantReflection(); + ResolvedJavaType thisType = constantReflection.asJavaType(forX.asJavaConstant()); + ResolvedJavaType otherType = constantReflection.asJavaType(forY.asJavaConstant()); + if (thisType != null && otherType != null) { + return LogicConstantNode.forBoolean(thisType.isAssignableFrom(otherType)); + } + } + return this; + } + + @Override + public void lower(LoweringTool tool) { + tool.getLowerer().lower(this, tool); + } + +} diff -r 8d09a572da84 -r 343e0e71031b graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java Fri Feb 13 12:48:27 2015 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java Fri Feb 13 12:54:34 2015 +0100 @@ -373,9 +373,9 @@ assert inlineGraph.getAssumptions() == null : "cannot inline graph which makes assumptions into a graph that doesn't: " + inlineGraph + " -> " + graph; } - // Copy method dependencies from inlinee to caller - if (inlineGraph.isMethodRecordingEnabled() && graph.isMethodRecordingEnabled()) { - graph.getMethods().addAll(inlineGraph.getMethods()); + // Copy inlined methods from inlinee to caller + if (inlineGraph.isInlinedMethodRecordingEnabled() && graph.isInlinedMethodRecordingEnabled()) { + graph.getInlinedMethods().addAll(inlineGraph.getInlinedMethods()); } return duplicates; diff -r 8d09a572da84 -r 343e0e71031b graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/AbstractInlineInfo.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/AbstractInlineInfo.java Fri Feb 13 12:48:27 2015 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/AbstractInlineInfo.java Fri Feb 13 12:54:34 2015 +0100 @@ -66,8 +66,8 @@ InliningUtil.InlinedBytecodes.add(concrete.getCodeSize()); StructuredGraph graph = invoke.asNode().graph(); - if (graph.isMethodRecordingEnabled()) { - graph.getMethods().add(concrete); + if (graph.isInlinedMethodRecordingEnabled()) { + graph.getInlinedMethods().add(concrete); } return canonicalizeNodes; } diff -r 8d09a572da84 -r 343e0e71031b graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/elem/InlineableGraph.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/elem/InlineableGraph.java Fri Feb 13 12:48:27 2015 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/elem/InlineableGraph.java Fri Feb 13 12:54:34 2015 +0100 @@ -201,12 +201,12 @@ private static StructuredGraph parseBytecodes(ResolvedJavaMethod method, HighTierContext context, CanonicalizerPhase canonicalizer, StructuredGraph caller) { StructuredGraph newGraph = new StructuredGraph(method, AllowAssumptions.from(caller.getAssumptions() != null)); try (Debug.Scope s = Debug.scope("InlineGraph", newGraph)) { - if (!caller.isMethodRecordingEnabled()) { - // Don't record method dependencies in the inlinee if + if (!caller.isInlinedMethodRecordingEnabled()) { + // Don't record inlined methods in the callee if // the caller doesn't want them. This decision is // preserved in the graph cache (if used) which is // ok since the graph cache is compilation local. - newGraph.disableMethodRecording(); + newGraph.disableInlinedMethodRecording(); } if (context.getGraphBuilderSuite() != null) { context.getGraphBuilderSuite().apply(newGraph, context); diff -r 8d09a572da84 -r 343e0e71031b graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/StandardMethodSubstitutionsTest.java --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/StandardMethodSubstitutionsTest.java Fri Feb 13 12:48:27 2015 +0100 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/StandardMethodSubstitutionsTest.java Fri Feb 13 12:54:34 2015 +0100 @@ -177,4 +177,25 @@ public static double longBitsToDouble(long value) { return Double.longBitsToDouble(value); } + + @SuppressWarnings("all") + public static boolean isInstance(Class clazz) { + return clazz.isInstance(Number.class); + } + + @SuppressWarnings("all") + public static boolean isAssignableFrom(Class clazz) { + return clazz.isInstance(Number.class); + } + + @Test + public void testClassSubstitutions() { + test("isInstance"); + for (Class c : new Class[]{getClass(), Cloneable.class, int[].class, String[][].class}) { + for (Object o : new Object[]{this, new int[5], new String[2][], new Object()}) { + assertDeepEquals(c.isInstance(o), ClassSubstitutions.isInstance(c, o)); + assertDeepEquals(c.isAssignableFrom(o.getClass()), ClassSubstitutions.isAssignableFrom(c, o.getClass())); + } + } + } } diff -r 8d09a572da84 -r 343e0e71031b graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ClassSubstitutions.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ClassSubstitutions.java Fri Feb 13 12:54:34 2015 +0100 @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2015, 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 com.oracle.graal.api.replacements.*; +import com.oracle.graal.nodes.calc.*; + +/** + * Substitutions for {@link java.lang.Class} methods. + */ +@ClassSubstitution(java.lang.Class.class) +public class ClassSubstitutions { + + @MethodSubstitution(isStatic = false) + public static boolean isInstance(Class thisObj, Object obj) { + return ConditionalNode.materializeIsInstance(thisObj, obj); + } + + @MethodSubstitution(isStatic = false) + public static boolean isAssignableFrom(Class thisClass, Class otherClass) { + return ConditionalNode.materializeIsAssignableFrom(thisClass, otherClass); + } +} diff -r 8d09a572da84 -r 343e0e71031b 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 Fri Feb 13 12:48:27 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraalMethodSubstitutions.java Fri Feb 13 12:54:34 2015 +0100 @@ -62,6 +62,7 @@ replacements.registerSubstitutions(Short.class, ShortSubstitutions.class); replacements.registerSubstitutions(UnsignedMath.class, UnsignedMathSubstitutions.class); replacements.registerSubstitutions(Edges.class, EdgesSubstitutions.class); + replacements.registerSubstitutions(Class.class, ClassSubstitutions.class); } if (Options.UseBlackholeSubstitution.getValue()) { replacements.registerSubstitutions(new Type() { diff -r 8d09a572da84 -r 343e0e71031b 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 Fri Feb 13 12:48:27 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java Fri Feb 13 12:54:34 2015 +0100 @@ -65,7 +65,7 @@ protected abstract Arguments makeArguments(InstanceOfUsageReplacer replacer, LoweringTool tool); public void lower(FloatingNode instanceOf, LoweringTool tool) { - assert instanceOf instanceof InstanceOfNode || instanceOf instanceof InstanceOfDynamicNode; + assert instanceOf instanceof InstanceOfNode || instanceOf instanceof InstanceOfDynamicNode || instanceOf instanceof ClassIsAssignableFromNode; List usages = instanceOf.usages().snapshot(); Instantiation instantiation = new Instantiation(); @@ -176,7 +176,7 @@ public final ValueNode falseValue; public InstanceOfUsageReplacer(Instantiation instantiation, FloatingNode instanceOf, ValueNode trueValue, ValueNode falseValue) { - assert instanceOf instanceof InstanceOfNode || instanceOf instanceof InstanceOfDynamicNode; + assert instanceOf instanceof InstanceOfNode || instanceOf instanceof InstanceOfDynamicNode || instanceOf instanceof ClassIsAssignableFromNode; this.instantiation = instantiation; this.instanceOf = instanceOf; this.trueValue = trueValue; diff -r 8d09a572da84 -r 343e0e71031b 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 Fri Feb 13 12:48:27 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Fri Feb 13 12:54:34 2015 +0100 @@ -612,7 +612,7 @@ final StructuredGraph graph = new StructuredGraph(methodToParse, AllowAssumptions.NO); // They will also never be never be evolved or have breakpoints set in them - graph.disableMethodRecording(); + graph.disableInlinedMethodRecording(); try (Scope s = Debug.scope("buildInitialGraph", graph)) { MetaAccessProvider metaAccess = replacements.providers.getMetaAccess(); diff -r 8d09a572da84 -r 343e0e71031b 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 Fri Feb 13 12:48:27 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Fri Feb 13 12:54:34 2015 +0100 @@ -566,8 +566,8 @@ // Copy snippet graph, replacing constant parameters with given arguments final StructuredGraph snippetCopy = new StructuredGraph(snippetGraph.name, snippetGraph.method(), AllowAssumptions.NO); - if (!snippetGraph.isMethodRecordingEnabled()) { - snippetCopy.disableMethodRecording(); + if (!snippetGraph.isInlinedMethodRecordingEnabled()) { + snippetCopy.disableInlinedMethodRecording(); } Map nodeReplacements = Node.newIdentityMap(); diff -r 8d09a572da84 -r 343e0e71031b graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/InstrumentationPartialEvaluationTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/InstrumentationPartialEvaluationTest.java Fri Feb 13 12:54:34 2015 +0100 @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2015, 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.test; + +import org.junit.*; + +import com.oracle.graal.truffle.test.nodes.*; +import com.oracle.truffle.api.frame.*; +import com.oracle.truffle.api.instrument.*; +import com.oracle.truffle.api.instrument.impl.*; + +/** + * Tests for a single simple PE test with various combinations of instrumentation attached. None of + * the instrumentation ultimate does anything, so should compile away. + */ +public class InstrumentationPartialEvaluationTest extends PartialEvaluationTest { + + public static Object constant42() { + return 42; + } + + @Test + public void constantValueUninstrumented() { + FrameDescriptor fd = new FrameDescriptor(); + AbstractTestNode result = new ConstantTestNode(42); + RootTestNode root = new RootTestNode(fd, "constantValue", result); + root.adoptChildren(); + assertPartialEvalEquals("constant42", root); + } + + @Ignore + @Test + public void constantValueProbedNoInstruments() { + FrameDescriptor fd = new FrameDescriptor(); + AbstractTestNode result = new ConstantTestNode(42); + RootTestNode root = new RootTestNode(fd, "constantValue", result); + root.adoptChildren(); + result.probe(); + assertPartialEvalEquals("constant42", root); + } + + @Ignore + @Test + public void constantValueProbedNullInstrument() { + FrameDescriptor fd = new FrameDescriptor(); + AbstractTestNode result = new ConstantTestNode(42); + RootTestNode root = new RootTestNode(fd, "constantValue", result); + root.adoptChildren(); + Probe probe = result.probe(); + Instrument instrument = Instrument.create(new DefaultEventListener(), "Null test Instrument"); + probe.attach(instrument); + assertPartialEvalEquals("constant42", root); + } + + @Ignore + @Test + public void constantValueProbedNullInstrumentDisposed() { + FrameDescriptor fd = new FrameDescriptor(); + AbstractTestNode result = new ConstantTestNode(42); + RootTestNode root = new RootTestNode(fd, "constantValue", result); + root.adoptChildren(); + Probe probe = result.probe(); + Instrument instrument = Instrument.create(new DefaultEventListener(), "Null test Instrument"); + probe.attach(instrument); + instrument.dispose(); + assertPartialEvalEquals("constant42", root); + } + + @Ignore + @Test + public void constantValueProbedTwoNullInstruments() { + FrameDescriptor fd = new FrameDescriptor(); + AbstractTestNode result = new ConstantTestNode(42); + RootTestNode root = new RootTestNode(fd, "constantValue", result); + root.adoptChildren(); + Probe probe = result.probe(); + Instrument instrument1 = Instrument.create(new DefaultEventListener(), "Null test Instrument 1"); + probe.attach(instrument1); + Instrument instrument2 = Instrument.create(new DefaultEventListener(), "Null test Instrument 2"); + probe.attach(instrument2); + assertPartialEvalEquals("constant42", root); + } + + @Ignore + @Test + public void constantValueProbedThreeNullInstruments() { + FrameDescriptor fd = new FrameDescriptor(); + AbstractTestNode result = new ConstantTestNode(42); + RootTestNode root = new RootTestNode(fd, "constantValue", result); + root.adoptChildren(); + Probe probe = result.probe(); + Instrument instrument1 = Instrument.create(new DefaultEventListener(), "Null test Instrument 1"); + probe.attach(instrument1); + Instrument instrument2 = Instrument.create(new DefaultEventListener(), "Null test Instrument 2"); + probe.attach(instrument2); + Instrument instrument3 = Instrument.create(new DefaultEventListener(), "Null test Instrument 3"); + probe.attach(instrument3); + assertPartialEvalEquals("constant42", root); + } + + @Ignore + @Test + public void constantValueProbedThreeNullInstrumentsOneDisposed() { + FrameDescriptor fd = new FrameDescriptor(); + AbstractTestNode result = new ConstantTestNode(42); + RootTestNode root = new RootTestNode(fd, "constantValue", result); + root.adoptChildren(); + Probe probe = result.probe(); + Instrument instrument1 = Instrument.create(new DefaultEventListener(), "Null test Instrument 1"); + probe.attach(instrument1); + Instrument instrument2 = Instrument.create(new DefaultEventListener(), "Null test Instrument 2"); + probe.attach(instrument2); + Instrument instrument3 = Instrument.create(new DefaultEventListener(), "Null test Instrument 3"); + probe.attach(instrument3); + instrument2.dispose(); + assertPartialEvalEquals("constant42", root); + } +} diff -r 8d09a572da84 -r 343e0e71031b graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/nodes/AbstractTestNode.java --- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/nodes/AbstractTestNode.java Fri Feb 13 12:48:27 2015 +0100 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/nodes/AbstractTestNode.java Fri Feb 13 12:54:34 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2015, 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 @@ -23,6 +23,7 @@ package com.oracle.graal.truffle.test.nodes; import com.oracle.truffle.api.frame.*; +import com.oracle.truffle.api.instrument.ProbeNode.WrapperNode; import com.oracle.truffle.api.nodes.*; public abstract class AbstractTestNode extends Node { @@ -31,5 +32,15 @@ super(null); } + @Override + public boolean isInstrumentable() { + return true; + } + + @Override + public WrapperNode createWrapperNode() { + return new WrapperTestNode(this); + } + public abstract int execute(VirtualFrame frame); } diff -r 8d09a572da84 -r 343e0e71031b graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/nodes/WrapperTestNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/nodes/WrapperTestNode.java Fri Feb 13 12:54:34 2015 +0100 @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2015, 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.test.nodes; + +import com.oracle.truffle.api.frame.*; +import com.oracle.truffle.api.instrument.*; +import com.oracle.truffle.api.instrument.ProbeNode.WrapperNode; +import com.oracle.truffle.api.nodes.*; + +/** + * Support for PE testing instrumentation. + */ +public final class WrapperTestNode extends AbstractTestNode implements WrapperNode { + + @Child private AbstractTestNode child; + @Child private ProbeNode probeNode; + + public WrapperTestNode(AbstractTestNode child) { + this.child = child; + } + + public String instrumentationInfo() { + return "Wrapper for PE test nodes"; + } + + @Override + public boolean isInstrumentable() { + return false; + } + + public void insertProbe(ProbeNode newProbeNode) { + this.probeNode = newProbeNode; + } + + public Probe getProbe() { + return probeNode.getProbe(); + } + + @Override + public Node getChild() { + return child; + } + + @Override + public int execute(VirtualFrame frame) { + probeNode.enter(child, frame); + try { + final int result = child.execute(frame); + probeNode.returnValue(child, frame, result); + return result; + } catch (KillException e) { + throw (e); + } catch (Exception e) { + probeNode.returnExceptional(child, frame, e); + throw (e); + } + + } + +} diff -r 8d09a572da84 -r 343e0e71031b 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 Fri Feb 13 12:48:27 2015 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java Fri Feb 13 12:54:34 2015 +0100 @@ -166,9 +166,8 @@ compilationNotify.notifyCompilationGraalTierFinished((OptimizedCallTarget) predefinedInstalledCode, graph); - if (graph.isMethodRecordingEnabled()) { - Set methods = graph.getMethods(); - result.setMethods(methods.toArray(new ResolvedJavaMethod[methods.size()])); + if (graph.isInlinedMethodRecordingEnabled()) { + result.setMethods(graph.method(), graph.getInlinedMethods()); } else { assert result.getMethods() == null; } diff -r 8d09a572da84 -r 343e0e71031b graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/WordCastNode.java --- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/WordCastNode.java Fri Feb 13 12:48:27 2015 +0100 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/WordCastNode.java Fri Feb 13 12:54:34 2015 +0100 @@ -65,6 +65,17 @@ /* If the cast is unused, it can be eliminated. */ return input; } + + assert !stamp().isCompatible(input.stamp()); + if (input.isConstant()) { + /* Null pointers are uncritical for GC, so they can be constant folded. */ + if (input.asJavaConstant().isNull()) { + return ConstantNode.forIntegerStamp(stamp(), 0); + } else if (input.asJavaConstant().getKind().isNumericInteger() && input.asJavaConstant().asLong() == 0) { + return ConstantNode.forConstant(stamp(), JavaConstant.NULL_POINTER, tool.getMetaAccess()); + } + } + return this; } diff -r 8d09a572da84 -r 343e0e71031b 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 Fri Feb 13 12:48:27 2015 +0100 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java Fri Feb 13 12:54:34 2015 +0100 @@ -113,6 +113,8 @@ protected void rewriteNode(StructuredGraph graph, Node node) { if (node instanceof CheckCastNode) { rewriteCheckCast(graph, (CheckCastNode) node); + } else if (node instanceof PiNode) { + rewritePi(graph, (PiNode) node); } else if (node instanceof LoadFieldNode) { rewriteLoadField(graph, (LoadFieldNode) node); } else if (node instanceof AccessIndexedNode) { @@ -133,6 +135,16 @@ } /** + * Remove casts between word types (which by now no longer have kind Object). + */ + protected void rewritePi(StructuredGraph graph, PiNode node) { + if (node.getKind() == wordKind) { + node.replaceAtUsages(node.object()); + graph.removeFloating(node); + } + } + + /** * Fold constant field reads, e.g. enum constants. */ protected void rewriteLoadField(StructuredGraph graph, LoadFieldNode node) { diff -r 8d09a572da84 -r 343e0e71031b graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/expression/DSLExpression.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/expression/DSLExpression.java Fri Feb 13 12:48:27 2015 +0100 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/expression/DSLExpression.java Fri Feb 13 12:54:34 2015 +0100 @@ -23,6 +23,7 @@ package com.oracle.truffle.dsl.processor.expression; import java.util.*; +import java.util.concurrent.atomic.*; import javax.lang.model.element.*; import javax.lang.model.type.*; @@ -68,6 +69,19 @@ return variables; } + public boolean containsComparisons() { + final AtomicBoolean found = new AtomicBoolean(); + this.accept(new AbstractDSLExpressionVisitor() { + @Override + public void visitBinary(Binary binary) { + if (binary.isComparison()) { + found.set(true); + } + } + }); + return found.get(); + } + public void setResolvedTargetType(TypeMirror resolvedTargetType) { this.resolvedTargetType = resolvedTargetType; } @@ -131,6 +145,10 @@ this.right = right; } + public boolean isComparison() { + return DSLExpressionResolver.COMPARABLE_OPERATORS.contains(operator) || DSLExpressionResolver.IDENTITY_OPERATORS.contains(operator); + } + @Override public boolean equals(Object obj) { if (obj instanceof Binary) { diff -r 8d09a572da84 -r 343e0e71031b graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/expression/DSLExpressionResolver.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/expression/DSLExpressionResolver.java Fri Feb 13 12:48:27 2015 +0100 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/expression/DSLExpressionResolver.java Fri Feb 13 12:54:34 2015 +0100 @@ -41,8 +41,8 @@ public class DSLExpressionResolver implements DSLExpressionVisitor { private static final List LOGIC_OPERATORS = Arrays.asList("||"); - private static final List COMPARABLE_OPERATORS = Arrays.asList("<", "<=", ">", ">="); - private static final List IDENTITY_OPERATORS = Arrays.asList("==", "!="); + public static final List COMPARABLE_OPERATORS = Arrays.asList("<", "<=", ">", ">="); + public static final List IDENTITY_OPERATORS = Arrays.asList("==", "!="); private static final String CONSTRUCTOR_KEYWORD = "new"; private final List variables = new ArrayList<>(); diff -r 8d09a572da84 -r 343e0e71031b graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/NodeGenFactory.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/NodeGenFactory.java Fri Feb 13 12:48:27 2015 +0100 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/NodeGenFactory.java Fri Feb 13 12:54:34 2015 +0100 @@ -213,6 +213,8 @@ } clazz.add(createGetCostMethod()); + avoidFindbugsProblems(clazz); + if (singleSpecializable) { if (node.needsRewrites(context)) { clazz.add(createUnsupportedMethod()); @@ -236,6 +238,28 @@ return clazz; } + private void avoidFindbugsProblems(CodeTypeElement clazz) { + TypeElement type = context.getEnvironment().getElementUtils().getTypeElement("edu.umd.cs.findbugs.annotations.SuppressFBWarnings"); + if (type == null) { + return; + } + boolean foundComparison = false; + outer: for (SpecializationData specialization : node.getSpecializations()) { + for (GuardExpression guard : specialization.getGuards()) { + if (guard.getExpression().containsComparisons()) { + foundComparison = true; + break outer; + } + } + } + + if (foundComparison) { + CodeAnnotationMirror annotation = new CodeAnnotationMirror((DeclaredType) type.asType()); + annotation.setElementValue(annotation.findExecutableElement("value"), new CodeAnnotationValue("SA_LOCAL_SELF_COMPARISON")); + clazz.addAnnotationMirror(annotation); + } + } + private Element createUnsupportedMethod() { LocalContext locals = LocalContext.load(this); CodeExecutableElement method = locals.createMethod(modifiers(PROTECTED), getType(UnsupportedSpecializationException.class), "unsupported"); diff -r 8d09a572da84 -r 343e0e71031b graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/NodeParser.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/NodeParser.java Fri Feb 13 12:48:27 2015 +0100 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/NodeParser.java Fri Feb 13 12:54:34 2015 +0100 @@ -1126,10 +1126,6 @@ } private void initializeGeneric(final NodeData node) { - if (!node.needsRewrites(context)) { - return; - } - List generics = new ArrayList<>(); for (SpecializationData spec : node.getSpecializations()) { if (spec.isFallback()) {