changeset 21606:625b2b12b418

Cleanup and generalize graph builder plugins
author Christian Wimmer <christian.wimmer@oracle.com>
date Fri, 29 May 2015 13:19:05 -0700
parents 7a7cf422160b
children 71b338926f2e
files graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/GenericInvocationPlugin.java graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/GraphBuilderConfiguration.java graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/LoadFieldPlugin.java graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/LoadIndexedPlugin.java graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/NodePlugin.java graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/TypeCheckPlugin.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoadFieldPlugin.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoadIndexedPlugin.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotNodePlugin.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotParameterPlugin.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotWordOperationPlugin.java graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultGenericInvocationPlugin.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/MethodHandleInvocationPlugin.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/MethodHandlePlugin.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPlugin.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/WordOperationPlugin.java graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/ConditionAnchoringTest.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java
diffstat 21 files changed, 889 insertions(+), 850 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/GenericInvocationPlugin.java	Fri May 29 17:23:14 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/*
- * 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.graphbuilderconf;
-
-import com.oracle.jvmci.meta.ResolvedJavaMethod;
-import com.oracle.graal.nodes.*;
-
-/**
- * Plugin for handling an invocation based on some property of the method being invoked such as any
- * annotations it may have.
- */
-public interface GenericInvocationPlugin extends GraphBuilderPlugin {
-    /**
-     * Executes this plugin for an invocation of a given method with a given set of arguments.
-     *
-     * @return {@code true} if this plugin handled the invocation, {@code false} if not
-     */
-    boolean apply(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args);
-}
--- a/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/GraphBuilderConfiguration.java	Fri May 29 17:23:14 2015 +0200
+++ b/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/GraphBuilderConfiguration.java	Fri May 29 13:19:05 2015 -0700
@@ -32,12 +32,9 @@
 
     public static class Plugins {
         private final InvocationPlugins invocationPlugins;
-        private LoadFieldPlugin loadFieldPlugin;
-        private LoadIndexedPlugin loadIndexedPlugin;
-        private TypeCheckPlugin typeCheckPlugin;
+        private NodePlugin[] nodePlugins;
         private ParameterPlugin parameterPlugin;
         private InlineInvokePlugin inlineInvokePlugin;
-        private GenericInvocationPlugin genericInvocationPlugin;
         private LoopExplosionPlugin loopExplosionPlugin;
 
         /**
@@ -48,12 +45,9 @@
         public Plugins(Plugins copyFrom) {
             this.invocationPlugins = new InvocationPlugins(copyFrom.invocationPlugins);
             this.parameterPlugin = copyFrom.parameterPlugin;
-            this.loadFieldPlugin = copyFrom.loadFieldPlugin;
-            this.loadIndexedPlugin = copyFrom.loadIndexedPlugin;
-            this.typeCheckPlugin = copyFrom.typeCheckPlugin;
+            this.nodePlugins = copyFrom.nodePlugins;
             this.inlineInvokePlugin = copyFrom.inlineInvokePlugin;
             this.loopExplosionPlugin = copyFrom.loopExplosionPlugin;
-            this.genericInvocationPlugin = copyFrom.genericInvocationPlugin;
         }
 
         /**
@@ -64,42 +58,20 @@
          */
         public Plugins(InvocationPlugins invocationPlugins) {
             this.invocationPlugins = invocationPlugins;
+            this.nodePlugins = new NodePlugin[0];
         }
 
         public InvocationPlugins getInvocationPlugins() {
             return invocationPlugins;
         }
 
-        public GenericInvocationPlugin getGenericInvocationPlugin() {
-            return genericInvocationPlugin;
-        }
-
-        public void setGenericInvocationPlugin(GenericInvocationPlugin plugin) {
-            this.genericInvocationPlugin = plugin;
-        }
-
-        public LoadFieldPlugin getLoadFieldPlugin() {
-            return loadFieldPlugin;
+        public NodePlugin[] getNodePlugins() {
+            return nodePlugins;
         }
 
-        public void setLoadFieldPlugin(LoadFieldPlugin plugin) {
-            this.loadFieldPlugin = plugin;
-        }
-
-        public LoadIndexedPlugin getLoadIndexedPlugin() {
-            return loadIndexedPlugin;
-        }
-
-        public void setLoadIndexedPlugin(LoadIndexedPlugin plugin) {
-            this.loadIndexedPlugin = plugin;
-        }
-
-        public TypeCheckPlugin getTypeCheckPlugin() {
-            return typeCheckPlugin;
-        }
-
-        public void setTypeCheckPlugin(TypeCheckPlugin typeCheckPlugin) {
-            this.typeCheckPlugin = typeCheckPlugin;
+        public void appendNodePlugin(NodePlugin plugin) {
+            nodePlugins = Arrays.copyOf(nodePlugins, nodePlugins.length + 1);
+            nodePlugins[nodePlugins.length - 1] = plugin;
         }
 
         public ParameterPlugin getParameterPlugin() {
--- a/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/LoadFieldPlugin.java	Fri May 29 17:23:14 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-/*
- * 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.graphbuilderconf;
-
-import com.oracle.jvmci.meta.ConstantReflectionProvider;
-import com.oracle.jvmci.meta.JavaConstant;
-import com.oracle.jvmci.meta.MetaAccessProvider;
-import com.oracle.jvmci.meta.ResolvedJavaField;
-import com.oracle.graal.nodes.*;
-
-public interface LoadFieldPlugin extends GraphBuilderPlugin {
-    @SuppressWarnings("unused")
-    default boolean apply(GraphBuilderContext b, ValueNode receiver, ResolvedJavaField field) {
-        return false;
-    }
-
-    @SuppressWarnings("unused")
-    default boolean apply(GraphBuilderContext graphBuilderContext, ResolvedJavaField staticField) {
-        return false;
-    }
-
-    default boolean tryConstantFold(GraphBuilderContext b, MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, ResolvedJavaField field, JavaConstant receiver) {
-        JavaConstant result = constantReflection.readConstantFieldValue(field, receiver);
-        if (result != null) {
-            ConstantNode constantNode = ConstantNode.forConstant(result, metaAccess);
-            b.addPush(field.getKind(), constantNode);
-            return true;
-        }
-        return false;
-    }
-}
--- a/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/LoadIndexedPlugin.java	Fri May 29 17:23:14 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-/*
- * 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.graphbuilderconf;
-
-import com.oracle.jvmci.meta.Kind;
-import com.oracle.graal.nodes.*;
-
-public interface LoadIndexedPlugin extends GraphBuilderPlugin {
-    @SuppressWarnings("unused")
-    default boolean apply(GraphBuilderContext b, ValueNode array, ValueNode index, Kind elementKind) {
-        return false;
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/NodePlugin.java	Fri May 29 13:19:05 2015 -0700
@@ -0,0 +1,155 @@
+/*
+ * 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.graphbuilderconf;
+
+import com.oracle.jvmci.meta.*;
+import com.oracle.graal.nodes.*;
+
+public interface NodePlugin extends GraphBuilderPlugin {
+    /**
+     * Handle the parsing of a method invocation bytecode to a method that can be bound statically.
+     * If the method returns true, it must {@link GraphBuilderContext#push push} a value as the
+     * result of the method invocation using the {@link Signature#getReturnKind return kind} of the
+     * method.
+     *
+     * @param b the context
+     * @param method the statically bound, invoked method
+     * @param args the arguments of the method invocation
+     * @return true if the plugin handles the invocation, false otherwise
+     */
+    default boolean handleInvoke(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args) {
+        return false;
+    }
+
+    /**
+     * Handle the parsing of a GETFIELD bytecode. If the method returns true, it must
+     * {@link GraphBuilderContext#push push} a value using the {@link ResolvedJavaField#getKind()
+     * kind} of the field.
+     *
+     * @param b the context
+     * @param object the receiver object for the field access
+     * @param field the accessed field
+     * @return true if the plugin handles the field access, false otherwise
+     */
+    default boolean handleLoadField(GraphBuilderContext b, ValueNode object, ResolvedJavaField field) {
+        return false;
+    }
+
+    /**
+     * Handle the parsing of a GETSTATIC bytecode. If the method returns true, it must
+     * {@link GraphBuilderContext#push push} a value using the {@link ResolvedJavaField#getKind()
+     * kind} of the field.
+     *
+     * @param b the context
+     * @param field the accessed field
+     * @return true if the plugin handles the field access, false otherwise
+     */
+    default boolean handleLoadStaticField(GraphBuilderContext b, ResolvedJavaField field) {
+        return false;
+    }
+
+    /**
+     * Handle the parsing of a PUTFIELD bytecode.
+     *
+     * @param b the context
+     * @param object the receiver object for the field access
+     * @param field the accessed field
+     * @param value the value to be stored into the field
+     * @return true if the plugin handles the field access, false otherwise
+     */
+    default boolean handleStoreField(GraphBuilderContext b, ValueNode object, ResolvedJavaField field, ValueNode value) {
+        return false;
+    }
+
+    /**
+     * Handle the parsing of a PUTSTATIC bytecode.
+     *
+     * @param b the context
+     * @param field the accessed field
+     * @param value the value to be stored into the field
+     * @return true if the plugin handles the field access, false otherwise.
+     */
+    default boolean handleStoreStaticField(GraphBuilderContext b, ResolvedJavaField field, ValueNode value) {
+        return false;
+    }
+
+    /**
+     * Handle the parsing of an array load bytecode. If the method returns true, it must
+     * {@link GraphBuilderContext#push push} a value using the provided elementKind.
+     *
+     * @param b the context
+     * @param array the accessed array
+     * @param index the index for the array access
+     * @param elementKind the element kind of the accessed array
+     * @return true if the plugin handles the array access, false otherwise.
+     */
+    default boolean handleLoadIndexed(GraphBuilderContext b, ValueNode array, ValueNode index, Kind elementKind) {
+        return false;
+    }
+
+    /**
+     * Handle the parsing of an array store bytecode.
+     *
+     * @param b the context
+     * @param array the accessed array
+     * @param index the index for the array access
+     * @param elementKind the element kind of the accessed array
+     * @param value the value to be stored into the array
+     * @return true if the plugin handles the array access, false otherwise.
+     */
+    default boolean handleStoreIndexed(GraphBuilderContext b, ValueNode array, ValueNode index, Kind elementKind, ValueNode value) {
+        return false;
+    }
+
+    /**
+     * Handle the parsing of a CHECKCAST bytecode. If the method returns true, it must
+     * {@link GraphBuilderContext#push push} a value with the result of the cast using
+     * {@link Kind#Object}.
+     *
+     * @param b the context
+     * @param object the object to be type checked
+     * @param type the type that the object is checked against
+     * @param profile the profiling information for the type check, or null if no profiling
+     *            information is available
+     * @return true if the plugin handles the cast, false otherwise
+     */
+    default boolean handleCheckCast(GraphBuilderContext b, ValueNode object, ResolvedJavaType type, JavaTypeProfile profile) {
+        return false;
+    }
+
+    /**
+     * Handle the parsing of a INSTANCEOF bytecode. If the method returns true, it must
+     * {@link GraphBuilderContext#push push} a value with the result of the instanceof using
+     * {@link Kind#Int}.
+     *
+     * @param b the context
+     * @param object the object to be type checked
+     * @param type the type that the object is checked against
+     * @param profile the profiling information for the type check, or null if no profiling
+     *            information is available
+     * @return true if the plugin handles the instanceof, false otherwise
+     */
+    default boolean handleInstanceOf(GraphBuilderContext b, ValueNode object, ResolvedJavaType type, JavaTypeProfile profile) {
+        return false;
+    }
+}
--- a/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/TypeCheckPlugin.java	Fri May 29 17:23:14 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-/*
- * 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.graphbuilderconf;
-
-import com.oracle.jvmci.meta.ResolvedJavaType;
-import com.oracle.jvmci.meta.JavaTypeProfile;
-import com.oracle.graal.nodes.*;
-
-public interface TypeCheckPlugin extends GraphBuilderPlugin {
-    /**
-     * Intercept the parsing of a CHECKCAST bytecode. If the method returns true, it must push
-     * {@link GraphBuilderContext#push push} an object value as the result of the cast.
-     *
-     * @param b The context.
-     * @param object The object to be type checked.
-     * @param type The type that the object is checked against.
-     * @param profile The profiling information for the type check, or null if no profiling
-     *            information is available.
-     * @return True if the plugin handled the cast, false if the bytecode parser should handle the
-     *         cast.
-     */
-    default boolean checkCast(GraphBuilderContext b, ValueNode object, ResolvedJavaType type, JavaTypeProfile profile) {
-        return false;
-    }
-
-    /**
-     * Intercept the parsing of a INSTANCEOF bytecode. If the method returns true, it must push
-     * {@link GraphBuilderContext#push push} an integer value with the result of the instanceof.
-     *
-     * @param b The context.
-     * @param object The object to be type checked.
-     * @param type The type that the object is checked against.
-     * @param profile The profiling information for the type check, or null if no profiling
-     *            information is available.
-     * @return True if the plugin handled the instanceof, false if the bytecode parser should handle
-     *         the instanceof.
-     */
-    default boolean instanceOf(GraphBuilderContext b, ValueNode object, ResolvedJavaType type, JavaTypeProfile profile) {
-        return false;
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java	Fri May 29 17:23:14 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java	Fri May 29 13:19:05 2015 -0700
@@ -73,16 +73,15 @@
         InvocationPlugins invocationPlugins = new HotSpotInvocationPlugins(config, metaAccess);
 
         Plugins plugins = new Plugins(invocationPlugins);
-        NodeIntrinsificationPhase nodeIntrinsification = new NodeIntrinsificationPhase(metaAccess, constantReflection, snippetReflection, foreignCalls, stampProvider);
+        NodeIntrinsificationPhase nodeIntrinsificationPhase = new NodeIntrinsificationPhase(metaAccess, constantReflection, snippetReflection, foreignCalls, stampProvider);
+        NodeIntrinsificationPlugin nodeIntrinsificationPlugin = new NodeIntrinsificationPlugin(metaAccess, nodeIntrinsificationPhase, wordTypes, false);
         HotSpotWordOperationPlugin wordOperationPlugin = new HotSpotWordOperationPlugin(snippetReflection, wordTypes);
+        HotSpotNodePlugin nodePlugin = new HotSpotNodePlugin(metaAccess, constantReflection, wordOperationPlugin, nodeIntrinsificationPlugin);
 
-        plugins.setParameterPlugin(new HotSpotParameterPlugin(wordTypes));
-        plugins.setLoadFieldPlugin(new HotSpotLoadFieldPlugin(metaAccess, constantReflection));
-        plugins.setLoadIndexedPlugin(new HotSpotLoadIndexedPlugin(wordTypes));
-        plugins.setTypeCheckPlugin(wordOperationPlugin);
+        plugins.setParameterPlugin(nodePlugin);
+        plugins.appendNodePlugin(nodePlugin);
+        plugins.appendNodePlugin(new MethodHandlePlugin(constantReflection.getMethodHandleAccess()));
         plugins.setInlineInvokePlugin(new DefaultInlineInvokePlugin(replacements));
-        plugins.setGenericInvocationPlugin(new MethodHandleInvocationPlugin(constantReflection.getMethodHandleAccess(), new DefaultGenericInvocationPlugin(metaAccess, nodeIntrinsification,
-                        wordOperationPlugin)));
 
         registerObjectPlugins(invocationPlugins);
         registerClassPlugins(plugins);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoadFieldPlugin.java	Fri May 29 17:23:14 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +0,0 @@
-/*
- * 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.hotspot.meta;
-
-import com.oracle.jvmci.meta.ResolvedJavaField;
-import com.oracle.jvmci.meta.MetaAccessProvider;
-import com.oracle.jvmci.meta.JavaConstant;
-import com.oracle.jvmci.meta.ConstantReflectionProvider;
-import static com.oracle.graal.compiler.common.GraalOptions.*;
-import static com.oracle.graal.hotspot.meta.HotSpotGraalConstantReflectionProvider.*;
-
-import com.oracle.graal.graphbuilderconf.*;
-import com.oracle.graal.nodes.*;
-
-public final class HotSpotLoadFieldPlugin implements LoadFieldPlugin {
-    private final MetaAccessProvider metaAccess;
-    private final ConstantReflectionProvider constantReflection;
-
-    public HotSpotLoadFieldPlugin(MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection) {
-        this.metaAccess = metaAccess;
-        this.constantReflection = constantReflection;
-    }
-
-    public boolean apply(GraphBuilderContext b, ValueNode receiver, ResolvedJavaField field) {
-        if (!ImmutableCode.getValue() || b.parsingIntrinsic()) {
-            if (receiver.isConstant()) {
-                JavaConstant asJavaConstant = receiver.asJavaConstant();
-                return tryReadField(b, field, asJavaConstant);
-            }
-        }
-        return false;
-    }
-
-    private boolean tryReadField(GraphBuilderContext b, ResolvedJavaField field, JavaConstant receiver) {
-        // FieldReadEnabledInImmutableCode is non null only if assertions are enabled
-        if (FieldReadEnabledInImmutableCode != null && ImmutableCode.getValue()) {
-            FieldReadEnabledInImmutableCode.set(Boolean.TRUE);
-            try {
-                return tryConstantFold(b, metaAccess, constantReflection, field, receiver);
-            } finally {
-                FieldReadEnabledInImmutableCode.set(null);
-            }
-        } else {
-            return tryConstantFold(b, metaAccess, constantReflection, field, receiver);
-        }
-    }
-
-    public boolean apply(GraphBuilderContext b, ResolvedJavaField staticField) {
-        if (!ImmutableCode.getValue() || b.parsingIntrinsic()) {
-            return tryReadField(b, staticField, null);
-        }
-        return false;
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoadIndexedPlugin.java	Fri May 29 17:23:14 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/*
- * 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.hotspot.meta;
-
-import com.oracle.jvmci.meta.ResolvedJavaType;
-import com.oracle.jvmci.meta.Kind;
-import com.oracle.graal.compiler.common.type.*;
-import com.oracle.graal.graphbuilderconf.*;
-import com.oracle.graal.hotspot.nodes.*;
-import com.oracle.graal.hotspot.nodes.type.*;
-import com.oracle.graal.hotspot.word.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.java.*;
-import com.oracle.graal.nodes.type.*;
-
-public final class HotSpotLoadIndexedPlugin implements LoadIndexedPlugin {
-    private final HotSpotWordTypes wordTypes;
-
-    public HotSpotLoadIndexedPlugin(HotSpotWordTypes wordTypes) {
-        this.wordTypes = wordTypes;
-    }
-
-    public boolean apply(GraphBuilderContext b, ValueNode array, ValueNode index, Kind elementKind) {
-        if (b.parsingIntrinsic()) {
-            ResolvedJavaType arrayType = StampTool.typeOrNull(array);
-            /*
-             * There are cases where the array does not have a known type yet, i.e., the type is
-             * null. In that case we assume it is not a word type.
-             */
-            if (arrayType != null && wordTypes.isWord(arrayType.getComponentType()) && elementKind != wordTypes.getWordKind()) {
-                /*
-                 * The elementKind of the node is a final field, and other information such as the
-                 * stamp depends on elementKind. Therefore, just create a new node and replace the
-                 * old one.
-                 */
-                Stamp componentStamp = wordTypes.getWordStamp(arrayType.getComponentType());
-                if (componentStamp instanceof MetaspacePointerStamp) {
-                    b.addPush(elementKind, new LoadIndexedPointerNode(componentStamp, array, index));
-                } else {
-                    b.addPush(elementKind, new LoadIndexedNode(array, index, wordTypes.getWordKind()));
-                }
-                return true;
-            }
-        }
-        return false;
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotNodePlugin.java	Fri May 29 13:19:05 2015 -0700
@@ -0,0 +1,187 @@
+/*
+ * 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.hotspot.meta;
+
+import static com.oracle.graal.compiler.common.GraalOptions.*;
+import static com.oracle.graal.hotspot.meta.HotSpotGraalConstantReflectionProvider.*;
+
+import com.oracle.graal.api.replacements.*;
+import com.oracle.graal.compiler.common.type.*;
+import com.oracle.graal.graph.Node.*;
+import com.oracle.graal.graphbuilderconf.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.replacements.*;
+import com.oracle.graal.word.*;
+import com.oracle.jvmci.meta.*;
+
+/**
+ * This plugin handles the HotSpot-specific customizations of bytecode parsing:
+ * <p>
+ * {@link Word}-type rewriting for {@link GraphBuilderContext#parsingIntrinsic intrinsic} functions
+ * (snippets and method substitutions), by forwarding to the {@link WordOperationPlugin}. Note that
+ * we forward the {@link NodePlugin} and {@link ParameterPlugin} methods, but not the
+ * {@link InlineInvokePlugin} methods implemented by {@link WordOperationPlugin}. The latter is not
+ * necessary because HotSpot only uses the {@link Word} type in methods that are force-inlined,
+ * i.e., there are never non-inlined invokes that involve the {@link Word} type.
+ * <p>
+ * Handling of {@link Fold} and {@link NodeIntrinsic} annotated methods, by forwarding to the
+ * {@link NodeIntrinsificationPlugin} when parsing intrinsic functions.
+ * <p>
+ * Constant folding of field loads.
+ */
+public final class HotSpotNodePlugin implements NodePlugin, ParameterPlugin {
+    private final MetaAccessProvider metaAccess;
+    private final ConstantReflectionProvider constantReflection;
+
+    protected final WordOperationPlugin wordOperationPlugin;
+    protected final NodeIntrinsificationPlugin nodeIntrinsificationPlugin;
+
+    public HotSpotNodePlugin(MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, WordOperationPlugin wordOperationPlugin,
+                    NodeIntrinsificationPlugin nodeIntrinsificationPlugin) {
+        this.metaAccess = metaAccess;
+        this.constantReflection = constantReflection;
+        this.wordOperationPlugin = wordOperationPlugin;
+        this.nodeIntrinsificationPlugin = nodeIntrinsificationPlugin;
+    }
+
+    @Override
+    public FloatingNode interceptParameter(GraphBuilderContext b, int index, Stamp stamp) {
+        if (b.parsingIntrinsic()) {
+            return wordOperationPlugin.interceptParameter(b, index, stamp);
+        }
+        return null;
+    }
+
+    @Override
+    public boolean handleInvoke(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args) {
+        if (b.parsingIntrinsic() && wordOperationPlugin.handleInvoke(b, method, args)) {
+            return true;
+        }
+        if (b.parsingIntrinsic() && nodeIntrinsificationPlugin.handleInvoke(b, method, args)) {
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public boolean handleLoadField(GraphBuilderContext b, ValueNode object, ResolvedJavaField field) {
+        if (!ImmutableCode.getValue() || b.parsingIntrinsic()) {
+            if (object.isConstant()) {
+                JavaConstant asJavaConstant = object.asJavaConstant();
+                if (tryReadField(b, field, asJavaConstant)) {
+                    return true;
+                }
+            }
+        }
+        if (b.parsingIntrinsic() && wordOperationPlugin.handleLoadField(b, object, field)) {
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public boolean handleLoadStaticField(GraphBuilderContext b, ResolvedJavaField field) {
+        if (!ImmutableCode.getValue() || b.parsingIntrinsic()) {
+            if (tryReadField(b, field, null)) {
+                return true;
+            }
+        }
+        if (b.parsingIntrinsic() && wordOperationPlugin.handleLoadStaticField(b, field)) {
+            return true;
+        }
+        return false;
+    }
+
+    private boolean tryReadField(GraphBuilderContext b, ResolvedJavaField field, JavaConstant object) {
+        // FieldReadEnabledInImmutableCode is non null only if assertions are enabled
+        if (FieldReadEnabledInImmutableCode != null && ImmutableCode.getValue()) {
+            FieldReadEnabledInImmutableCode.set(Boolean.TRUE);
+            try {
+                return tryConstantFold(b, field, object);
+            } finally {
+                FieldReadEnabledInImmutableCode.set(null);
+            }
+        } else {
+            return tryConstantFold(b, field, object);
+        }
+    }
+
+    private boolean tryConstantFold(GraphBuilderContext b, ResolvedJavaField field, JavaConstant object) {
+        JavaConstant result = constantReflection.readConstantFieldValue(field, object);
+        if (result != null) {
+            ConstantNode constantNode = ConstantNode.forConstant(result, metaAccess, b.getGraph());
+            b.push(field.getKind(), constantNode);
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public boolean handleStoreField(GraphBuilderContext b, ValueNode object, ResolvedJavaField field, ValueNode value) {
+        if (b.parsingIntrinsic() && wordOperationPlugin.handleStoreField(b, object, field, value)) {
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public boolean handleStoreStaticField(GraphBuilderContext b, ResolvedJavaField field, ValueNode value) {
+        if (b.parsingIntrinsic() && wordOperationPlugin.handleStoreStaticField(b, field, value)) {
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public boolean handleLoadIndexed(GraphBuilderContext b, ValueNode array, ValueNode index, Kind elementKind) {
+        if (b.parsingIntrinsic() && wordOperationPlugin.handleLoadIndexed(b, array, index, elementKind)) {
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public boolean handleStoreIndexed(GraphBuilderContext b, ValueNode array, ValueNode index, Kind elementKind, ValueNode value) {
+        if (b.parsingIntrinsic() && wordOperationPlugin.handleStoreIndexed(b, array, index, elementKind, value)) {
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public boolean handleCheckCast(GraphBuilderContext b, ValueNode object, ResolvedJavaType type, JavaTypeProfile profile) {
+        if (b.parsingIntrinsic() && wordOperationPlugin.handleCheckCast(b, object, type, profile)) {
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public boolean handleInstanceOf(GraphBuilderContext b, ValueNode object, ResolvedJavaType type, JavaTypeProfile profile) {
+        if (b.parsingIntrinsic() && wordOperationPlugin.handleInstanceOf(b, object, type, profile)) {
+            return true;
+        }
+        return false;
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotParameterPlugin.java	Fri May 29 17:23:14 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/*
- * 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.hotspot.meta;
-
-import com.oracle.jvmci.meta.ResolvedJavaType;
-import com.oracle.graal.compiler.common.type.*;
-import com.oracle.graal.graphbuilderconf.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.calc.*;
-import com.oracle.graal.nodes.type.*;
-import com.oracle.graal.word.*;
-
-public final class HotSpotParameterPlugin implements ParameterPlugin {
-    private final WordTypes wordTypes;
-
-    public HotSpotParameterPlugin(WordTypes wordTypes) {
-        this.wordTypes = wordTypes;
-    }
-
-    public FloatingNode interceptParameter(GraphBuilderContext b, int index, Stamp stamp) {
-        if (b.parsingIntrinsic()) {
-            ResolvedJavaType type = StampTool.typeOrNull(stamp);
-            if (wordTypes.isWord(type)) {
-                return new ParameterNode(index, wordTypes.getWordStamp(type));
-            }
-        }
-        return null;
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotWordOperationPlugin.java	Fri May 29 17:23:14 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotWordOperationPlugin.java	Fri May 29 13:19:05 2015 -0700
@@ -22,26 +22,28 @@
  */
 package com.oracle.graal.hotspot.meta;
 
-import com.oracle.jvmci.meta.ResolvedJavaMethod;
-import com.oracle.jvmci.meta.Kind;
-import static com.oracle.jvmci.meta.LocationIdentity.*;
 import static com.oracle.graal.hotspot.word.HotSpotOperation.HotspotOpcode.*;
 import static com.oracle.graal.nodes.ConstantNode.*;
+import static com.oracle.jvmci.meta.LocationIdentity.*;
 
 import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.graphbuilderconf.*;
+import com.oracle.graal.hotspot.nodes.*;
 import com.oracle.graal.hotspot.nodes.type.*;
 import com.oracle.graal.hotspot.word.*;
 import com.oracle.graal.hotspot.word.HotSpotOperation.HotspotOpcode;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.memory.HeapAccess.BarrierType;
 import com.oracle.graal.nodes.memory.*;
+import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.word.*;
 import com.oracle.jvmci.common.*;
+import com.oracle.jvmci.meta.*;
 
 /**
  * Extends {@link WordOperationPlugin} to handle {@linkplain HotSpotOperation HotSpot word
@@ -53,7 +55,18 @@
     }
 
     @Override
-    public boolean apply(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args) {
+    protected LoadIndexedNode createLoadIndexedNode(ValueNode array, ValueNode index) {
+        ResolvedJavaType arrayType = StampTool.typeOrNull(array);
+        Stamp componentStamp = wordTypes.getWordStamp(arrayType.getComponentType());
+        if (componentStamp instanceof MetaspacePointerStamp) {
+            return new LoadIndexedPointerNode(componentStamp, array, index);
+        } else {
+            return super.createLoadIndexedNode(array, index);
+        }
+    }
+
+    @Override
+    public boolean handleInvoke(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args) {
         if (!wordTypes.isWordOperation(method)) {
             return false;
         }
@@ -67,7 +80,7 @@
         return true;
     }
 
-    public void processHotSpotWordOperation(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args, HotSpotOperation operation) {
+    protected void processHotSpotWordOperation(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args, HotSpotOperation operation) {
         Kind returnKind = method.getSignature().getReturnKind();
         switch (operation.opcode()) {
             case POINTER_EQ:
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Fri May 29 17:23:14 2015 +0200
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Fri May 29 13:19:05 2015 -0700
@@ -1488,8 +1488,12 @@
             }
 
             private boolean tryGenericInvocationPlugin(ValueNode[] args, ResolvedJavaMethod targetMethod) {
-                GenericInvocationPlugin plugin = graphBuilderConfig.getPlugins().getGenericInvocationPlugin();
-                return plugin != null && plugin.apply(this, targetMethod, args);
+                for (NodePlugin plugin : graphBuilderConfig.getPlugins().getNodePlugins()) {
+                    if (plugin.handleInvoke(this, targetMethod, args)) {
+                        return true;
+                    }
+                }
+                return false;
             }
 
             private boolean tryInline(ValueNode[] args, ResolvedJavaMethod targetMethod, JavaType returnType) {
@@ -2737,27 +2741,27 @@
             private void genLoadIndexed(Kind kind) {
                 ValueNode index = frameState.pop(Kind.Int);
                 ValueNode array = emitExplicitExceptions(frameState.pop(Kind.Object), index);
-                if (!tryLoadIndexedPlugin(kind, index, array)) {
-                    frameState.push(kind, append(genLoadIndexed(array, index, kind)));
+
+                for (NodePlugin plugin : graphBuilderConfig.getPlugins().getNodePlugins()) {
+                    if (plugin.handleLoadIndexed(this, array, index, kind)) {
+                        return;
+                    }
                 }
-            }
-
-            protected boolean tryLoadIndexedPlugin(Kind kind, ValueNode index, ValueNode array) {
-                LoadIndexedPlugin loadIndexedPlugin = graphBuilderConfig.getPlugins().getLoadIndexedPlugin();
-                if (loadIndexedPlugin != null && loadIndexedPlugin.apply(this, array, index, kind)) {
-                    if (TraceParserPlugins.getValue()) {
-                        traceWithContext("used load indexed plugin");
-                    }
-                    return true;
-                } else {
-                    return false;
-                }
+
+                frameState.push(kind, append(genLoadIndexed(array, index, kind)));
             }
 
             private void genStoreIndexed(Kind kind) {
                 ValueNode value = frameState.pop(kind);
                 ValueNode index = frameState.pop(Kind.Int);
                 ValueNode array = emitExplicitExceptions(frameState.pop(Kind.Object), index);
+
+                for (NodePlugin plugin : graphBuilderConfig.getPlugins().getNodePlugins()) {
+                    if (plugin.handleStoreIndexed(this, array, index, kind, value)) {
+                        return;
+                    }
+                }
+
                 genStoreIndexed(array, index, kind, value);
             }
 
@@ -2985,85 +2989,99 @@
                 int cpi = getStream().readCPI();
                 JavaType type = lookupType(cpi, CHECKCAST);
                 ValueNode object = frameState.pop(Kind.Object);
-                if (type instanceof ResolvedJavaType) {
-                    ResolvedJavaType resolvedType = (ResolvedJavaType) type;
-                    JavaTypeProfile profile = getProfileForTypeCheck(resolvedType);
-                    TypeCheckPlugin typeCheckPlugin = this.graphBuilderConfig.getPlugins().getTypeCheckPlugin();
-                    if (typeCheckPlugin == null || !this.parsingIntrinsic() || !typeCheckPlugin.checkCast(this, object, resolvedType, profile)) {
-                        ValueNode checkCastNode = null;
-                        if (profile != null) {
-                            if (profile.getNullSeen().isFalse()) {
-                                object = append(GuardingPiNode.createNullCheck(object));
-                                ResolvedJavaType singleType = profile.asSingleType();
-                                if (singleType != null) {
-                                    LogicNode typeCheck = append(TypeCheckNode.create(singleType, object));
-                                    if (typeCheck.isTautology()) {
-                                        checkCastNode = object;
-                                    } else {
-                                        GuardingPiNode piNode = append(new GuardingPiNode(object, typeCheck, false, DeoptimizationReason.TypeCheckedInliningViolated,
-                                                        DeoptimizationAction.InvalidateReprofile, StampFactory.exactNonNull(singleType)));
-                                        checkCastNode = piNode;
-                                    }
-                                }
+
+                if (!(type instanceof ResolvedJavaType)) {
+                    handleUnresolvedCheckCast(type, object);
+                    return;
+                }
+                ResolvedJavaType resolvedType = (ResolvedJavaType) type;
+                JavaTypeProfile profile = getProfileForTypeCheck(resolvedType);
+
+                for (NodePlugin plugin : graphBuilderConfig.getPlugins().getNodePlugins()) {
+                    if (plugin.handleCheckCast(this, object, resolvedType, profile)) {
+                        return;
+                    }
+                }
+
+                ValueNode checkCastNode = null;
+                if (profile != null) {
+                    if (profile.getNullSeen().isFalse()) {
+                        object = append(GuardingPiNode.createNullCheck(object));
+                        ResolvedJavaType singleType = profile.asSingleType();
+                        if (singleType != null) {
+                            LogicNode typeCheck = append(TypeCheckNode.create(singleType, object));
+                            if (typeCheck.isTautology()) {
+                                checkCastNode = object;
+                            } else {
+                                GuardingPiNode piNode = append(new GuardingPiNode(object, typeCheck, false, DeoptimizationReason.TypeCheckedInliningViolated, DeoptimizationAction.InvalidateReprofile,
+                                                StampFactory.exactNonNull(singleType)));
+                                checkCastNode = piNode;
                             }
                         }
-                        if (checkCastNode == null) {
-                            checkCastNode = append(createCheckCast(resolvedType, object, profile, false));
-                        }
-                        frameState.push(Kind.Object, checkCastNode);
                     }
-                } else {
-                    handleUnresolvedCheckCast(type, object);
                 }
+                if (checkCastNode == null) {
+                    checkCastNode = append(createCheckCast(resolvedType, object, profile, false));
+                }
+                frameState.push(Kind.Object, checkCastNode);
             }
 
             private void genInstanceOf() {
                 int cpi = getStream().readCPI();
                 JavaType type = lookupType(cpi, INSTANCEOF);
                 ValueNode object = frameState.pop(Kind.Object);
-                if (type instanceof ResolvedJavaType) {
-                    ResolvedJavaType resolvedType = (ResolvedJavaType) type;
-                    JavaTypeProfile profile = getProfileForTypeCheck(resolvedType);
-                    TypeCheckPlugin typeCheckPlugin = this.graphBuilderConfig.getPlugins().getTypeCheckPlugin();
-                    if (typeCheckPlugin == null || !typeCheckPlugin.instanceOf(this, object, resolvedType, profile)) {
-                        ValueNode instanceOfNode = null;
-                        if (profile != null) {
-                            if (profile.getNullSeen().isFalse()) {
-                                object = append(GuardingPiNode.createNullCheck(object));
-                                ResolvedJavaType singleType = profile.asSingleType();
-                                if (singleType != null) {
-                                    LogicNode typeCheck = append(TypeCheckNode.create(singleType, object));
-                                    append(new FixedGuardNode(typeCheck, DeoptimizationReason.TypeCheckedInliningViolated, DeoptimizationAction.InvalidateReprofile));
-                                    instanceOfNode = LogicConstantNode.forBoolean(resolvedType.isAssignableFrom(singleType));
-                                }
-                            }
+
+                if (!(type instanceof ResolvedJavaType)) {
+                    handleUnresolvedInstanceOf(type, object);
+                    return;
+                }
+                ResolvedJavaType resolvedType = (ResolvedJavaType) type;
+                JavaTypeProfile profile = getProfileForTypeCheck(resolvedType);
+
+                for (NodePlugin plugin : graphBuilderConfig.getPlugins().getNodePlugins()) {
+                    if (plugin.handleInstanceOf(this, object, resolvedType, profile)) {
+                        return;
+                    }
+                }
+
+                ValueNode instanceOfNode = null;
+                if (profile != null) {
+                    if (profile.getNullSeen().isFalse()) {
+                        object = append(GuardingPiNode.createNullCheck(object));
+                        ResolvedJavaType singleType = profile.asSingleType();
+                        if (singleType != null) {
+                            LogicNode typeCheck = append(TypeCheckNode.create(singleType, object));
+                            append(new FixedGuardNode(typeCheck, DeoptimizationReason.TypeCheckedInliningViolated, DeoptimizationAction.InvalidateReprofile));
+                            instanceOfNode = LogicConstantNode.forBoolean(resolvedType.isAssignableFrom(singleType));
                         }
-                        if (instanceOfNode == null) {
-                            instanceOfNode = createInstanceOf(resolvedType, object, profile);
-                        }
-                        frameState.push(Kind.Int, append(genConditional(genUnique(instanceOfNode))));
                     }
-                } else {
-                    handleUnresolvedInstanceOf(type, object);
                 }
+                if (instanceOfNode == null) {
+                    instanceOfNode = createInstanceOf(resolvedType, object, profile);
+                }
+                frameState.push(Kind.Int, append(genConditional(genUnique(instanceOfNode))));
             }
 
             void genNewInstance(int cpi) {
                 JavaType type = lookupType(cpi, NEW);
-                if (type instanceof ResolvedJavaType && ((ResolvedJavaType) type).isInitialized()) {
-                    ResolvedJavaType[] skippedExceptionTypes = this.graphBuilderConfig.getSkippedExceptionTypes();
-                    if (skippedExceptionTypes != null) {
-                        for (ResolvedJavaType exceptionType : skippedExceptionTypes) {
-                            if (exceptionType.isAssignableFrom((ResolvedJavaType) type)) {
-                                append(new DeoptimizeNode(DeoptimizationAction.None, TransferToInterpreter));
-                                return;
-                            }
+
+                if (!(type instanceof ResolvedJavaType) || !((ResolvedJavaType) type).isInitialized()) {
+                    handleUnresolvedNewInstance(type);
+                    return;
+                }
+                ResolvedJavaType resolvedType = (ResolvedJavaType) type;
+
+                ResolvedJavaType[] skippedExceptionTypes = this.graphBuilderConfig.getSkippedExceptionTypes();
+                if (skippedExceptionTypes != null) {
+                    for (ResolvedJavaType exceptionType : skippedExceptionTypes) {
+                        if (exceptionType.isAssignableFrom(resolvedType)) {
+                            append(new DeoptimizeNode(DeoptimizationAction.None, TransferToInterpreter));
+                            return;
                         }
                     }
-                    frameState.push(Kind.Object, append(createNewInstance((ResolvedJavaType) type, true)));
-                } else {
-                    handleUnresolvedNewInstance(type);
                 }
+
+                frameState.push(Kind.Object, append(createNewInstance(resolvedType, true)));
             }
 
             private void genNewPrimitiveArray(int typeCode) {
@@ -3075,12 +3093,14 @@
             private void genNewObjectArray(int cpi) {
                 JavaType type = lookupType(cpi, ANEWARRAY);
                 ValueNode length = frameState.pop(Kind.Int);
-                if (type instanceof ResolvedJavaType) {
-                    frameState.push(Kind.Object, append(createNewArray((ResolvedJavaType) type, length, true)));
-                } else {
+
+                if (!(type instanceof ResolvedJavaType)) {
                     handleUnresolvedNewObjectArray(type, length);
+                    return;
                 }
-
+                ResolvedJavaType resolvedType = (ResolvedJavaType) type;
+
+                frameState.push(Kind.Object, append(createNewArray(resolvedType, length, true)));
             }
 
             private void genNewMultiArray(int cpi) {
@@ -3090,25 +3110,32 @@
                 for (int i = rank - 1; i >= 0; i--) {
                     dims.set(i, frameState.pop(Kind.Int));
                 }
-                if (type instanceof ResolvedJavaType) {
-                    frameState.push(Kind.Object, append(createNewMultiArray((ResolvedJavaType) type, dims)));
-                } else {
+
+                if (!(type instanceof ResolvedJavaType)) {
                     handleUnresolvedNewMultiArray(type, dims);
+                    return;
                 }
+                ResolvedJavaType resolvedType = (ResolvedJavaType) type;
+
+                frameState.push(Kind.Object, append(createNewMultiArray(resolvedType, dims)));
             }
 
             private void genGetField(JavaField field) {
                 ValueNode receiver = emitExplicitExceptions(frameState.pop(Kind.Object), null);
-                if ((field instanceof ResolvedJavaField) && ((ResolvedJavaField) field).getDeclaringClass().isInitialized()) {
-                    ResolvedJavaField resolvedField = (ResolvedJavaField) field;
-
-                    LoadFieldPlugin loadFieldPlugin = this.graphBuilderConfig.getPlugins().getLoadFieldPlugin();
-                    if (loadFieldPlugin == null || !loadFieldPlugin.apply(this, receiver, resolvedField)) {
-                        frameState.push(field.getKind(), append(genLoadField(receiver, resolvedField)));
+
+                if (!(field instanceof ResolvedJavaField) || !((ResolvedJavaField) field).getDeclaringClass().isInitialized()) {
+                    handleUnresolvedLoadField(field, receiver);
+                    return;
+                }
+                ResolvedJavaField resolvedField = (ResolvedJavaField) field;
+
+                for (NodePlugin plugin : graphBuilderConfig.getPlugins().getNodePlugins()) {
+                    if (plugin.handleLoadField(this, receiver, resolvedField)) {
+                        return;
                     }
-                } else {
-                    handleUnresolvedLoadField(field, receiver);
                 }
+
+                frameState.push(field.getKind(), append(genLoadField(receiver, resolvedField)));
             }
 
             /**
@@ -3137,41 +3164,62 @@
             private void genPutField(JavaField field) {
                 ValueNode value = frameState.pop(field.getKind());
                 ValueNode receiver = emitExplicitExceptions(frameState.pop(Kind.Object), null);
-                if (field instanceof ResolvedJavaField && ((ResolvedJavaField) field).getDeclaringClass().isInitialized()) {
-                    genStoreField(receiver, (ResolvedJavaField) field, value);
-                } else {
+
+                if (!(field instanceof ResolvedJavaField) || !((ResolvedJavaField) field).getDeclaringClass().isInitialized()) {
                     handleUnresolvedStoreField(field, value, receiver);
+                    return;
                 }
+                ResolvedJavaField resolvedField = (ResolvedJavaField) field;
+
+                for (NodePlugin plugin : graphBuilderConfig.getPlugins().getNodePlugins()) {
+                    if (plugin.handleStoreField(this, receiver, resolvedField, value)) {
+                        return;
+                    }
+                }
+
+                genStoreField(receiver, resolvedField, value);
             }
 
             private void genGetStatic(JavaField field) {
-                if (field instanceof ResolvedJavaField && ((ResolvedJavaType) field.getDeclaringClass()).isInitialized()) {
-                    ResolvedJavaField resolvedField = (ResolvedJavaField) field;
-
-                    // Javac does not allow use of "$assertionsDisabled" for a field name but
-                    // Eclipse does in which case a suffix is added to the generated field.
-                    if ((parsingIntrinsic() || graphBuilderConfig.omitAssertions()) && resolvedField.isSynthetic() && resolvedField.getName().startsWith("$assertionsDisabled")) {
-                        frameState.push(field.getKind(), ConstantNode.forBoolean(true, graph));
+                if (!(field instanceof ResolvedJavaField) || !((ResolvedJavaType) field.getDeclaringClass()).isInitialized()) {
+                    handleUnresolvedLoadField(field, null);
+                    return;
+                }
+                ResolvedJavaField resolvedField = (ResolvedJavaField) field;
+
+                /*
+                 * Javac does not allow use of "$assertionsDisabled" for a field name but Eclipse
+                 * does, in which case a suffix is added to the generated field.
+                 */
+                if ((parsingIntrinsic() || graphBuilderConfig.omitAssertions()) && resolvedField.isSynthetic() && resolvedField.getName().startsWith("$assertionsDisabled")) {
+                    frameState.push(field.getKind(), ConstantNode.forBoolean(true, graph));
+                    return;
+                }
+
+                for (NodePlugin plugin : graphBuilderConfig.getPlugins().getNodePlugins()) {
+                    if (plugin.handleLoadStaticField(this, resolvedField)) {
                         return;
                     }
-
-                    LoadFieldPlugin loadFieldPlugin = this.graphBuilderConfig.getPlugins().getLoadFieldPlugin();
-                    if (loadFieldPlugin == null || !loadFieldPlugin.apply(this, resolvedField)) {
-                        frameState.push(field.getKind(), append(genLoadField(null, resolvedField)));
-                    }
-                } else {
-                    handleUnresolvedLoadField(field, null);
                 }
+
+                frameState.push(field.getKind(), append(genLoadField(null, resolvedField)));
             }
 
             private void genPutStatic(JavaField field) {
                 ValueNode value = frameState.pop(field.getKind());
-                if (field instanceof ResolvedJavaField && ((ResolvedJavaType) field.getDeclaringClass()).isInitialized()) {
-                    ResolvedJavaField resolvedField = (ResolvedJavaField) field;
-                    genStoreField(null, resolvedField, value);
-                } else {
+                if (!(field instanceof ResolvedJavaField) || !((ResolvedJavaType) field.getDeclaringClass()).isInitialized()) {
                     handleUnresolvedStoreField(field, value, null);
+                    return;
                 }
+                ResolvedJavaField resolvedField = (ResolvedJavaField) field;
+
+                for (NodePlugin plugin : graphBuilderConfig.getPlugins().getNodePlugins()) {
+                    if (plugin.handleStoreStaticField(this, resolvedField, value)) {
+                        return;
+                    }
+                }
+
+                genStoreField(null, resolvedField, value);
             }
 
             private double[] switchProbability(int numberOfCases, int bci) {
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultGenericInvocationPlugin.java	Fri May 29 17:23:14 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,185 +0,0 @@
-/*
- * 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 static com.oracle.graal.replacements.NodeIntrinsificationPhase.*;
-import static com.oracle.jvmci.meta.MetaUtil.*;
-
-import java.util.*;
-
-import com.oracle.graal.api.replacements.*;
-import com.oracle.graal.compiler.*;
-import com.oracle.graal.compiler.common.type.*;
-import com.oracle.graal.graph.Node.NodeIntrinsic;
-import com.oracle.graal.graphbuilderconf.*;
-import com.oracle.graal.nodeinfo.*;
-import com.oracle.graal.nodeinfo.StructuralInput.MarkerType;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.extended.*;
-import com.oracle.graal.word.*;
-import com.oracle.jvmci.common.*;
-import com.oracle.jvmci.meta.*;
-
-/**
- * An {@link GenericInvocationPlugin} that handles methods annotated by {@link Fold},
- * {@link NodeIntrinsic} and all annotations supported by a given {@link WordOperationPlugin}.
- */
-public class DefaultGenericInvocationPlugin implements GenericInvocationPlugin {
-    protected final NodeIntrinsificationPhase nodeIntrinsification;
-    protected final WordOperationPlugin wordOperationPlugin;
-
-    private final ResolvedJavaType structuralInputType;
-
-    public DefaultGenericInvocationPlugin(MetaAccessProvider metaAccess, NodeIntrinsificationPhase nodeIntrinsification, WordOperationPlugin wordOperationPlugin) {
-        this.nodeIntrinsification = nodeIntrinsification;
-        this.wordOperationPlugin = wordOperationPlugin;
-
-        this.structuralInputType = metaAccess.lookupJavaType(StructuralInput.class);
-    }
-
-    /**
-     * Calls in replacements to methods matching one of these filters are elided. Only void methods
-     * are considered for elision. The use of "snippets" in name of the variable and system property
-     * is purely for legacy reasons.
-     */
-    private static final MethodFilter[] MethodsElidedInSnippets = getMethodsElidedInSnippets();
-
-    private static MethodFilter[] getMethodsElidedInSnippets() {
-        String commaSeparatedPatterns = System.getProperty("graal.MethodsElidedInSnippets");
-        if (commaSeparatedPatterns != null) {
-            return MethodFilter.parse(commaSeparatedPatterns);
-        }
-        return null;
-    }
-
-    public boolean apply(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args) {
-        if (b.parsingIntrinsic() && wordOperationPlugin.apply(b, method, args)) {
-            return true;
-        } else if (b.parsingIntrinsic()) {
-            NodeIntrinsic intrinsic = nodeIntrinsification.getIntrinsic(method);
-            if (intrinsic != null) {
-                Signature sig = method.getSignature();
-                Kind returnKind = sig.getReturnKind();
-                Stamp stamp = StampFactory.forKind(returnKind);
-                if (returnKind == Kind.Object) {
-                    JavaType returnType = sig.getReturnType(method.getDeclaringClass());
-                    if (returnType instanceof ResolvedJavaType) {
-                        ResolvedJavaType resolvedReturnType = (ResolvedJavaType) returnType;
-                        WordTypes wordTypes = wordOperationPlugin.getWordTypes();
-                        if (wordTypes.isWord(resolvedReturnType)) {
-                            stamp = wordTypes.getWordStamp(resolvedReturnType);
-                        } else {
-                            stamp = StampFactory.declared(resolvedReturnType);
-                        }
-                    }
-                }
-
-                return processNodeIntrinsic(b, method, intrinsic, Arrays.asList(args), returnKind, stamp);
-            } else if (nodeIntrinsification.isFoldable(method)) {
-                ResolvedJavaType[] parameterTypes = resolveJavaTypes(method.toParameterTypes(), method.getDeclaringClass());
-                JavaConstant constant = nodeIntrinsification.tryFold(Arrays.asList(args), parameterTypes, method);
-                if (!COULD_NOT_FOLD.equals(constant)) {
-                    if (constant != null) {
-                        // Replace the invoke with the result of the call
-                        b.push(method.getSignature().getReturnKind(), ConstantNode.forConstant(constant, b.getMetaAccess(), b.getGraph()));
-                    } else {
-                        // This must be a void invoke
-                        assert method.getSignature().getReturnKind() == Kind.Void;
-                    }
-                    return true;
-                }
-            } else if (MethodsElidedInSnippets != null) {
-                if (MethodFilter.matches(MethodsElidedInSnippets, method)) {
-                    if (method.getSignature().getReturnKind() != Kind.Void) {
-                        throw new JVMCIError("Cannot elide non-void method " + method.format("%H.%n(%p)"));
-                    }
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    private InputType getInputType(ResolvedJavaType type) {
-        if (type != null && structuralInputType.isAssignableFrom(type)) {
-            MarkerType markerType = type.getAnnotation(MarkerType.class);
-            if (markerType != null) {
-                return markerType.value();
-            } else {
-                throw JVMCIError.shouldNotReachHere(String.format("%s extends StructuralInput, but is not annotated with @MarkerType", type));
-            }
-        } else {
-            return InputType.Value;
-        }
-    }
-
-    protected boolean processNodeIntrinsic(GraphBuilderContext b, ResolvedJavaMethod method, NodeIntrinsic intrinsic, List<ValueNode> args, Kind returnKind, Stamp stamp) {
-        ValueNode res = createNodeIntrinsic(b, method, intrinsic, args, stamp);
-        if (res == null) {
-            return false;
-        }
-        if (res instanceof UnsafeCopyNode) {
-            UnsafeCopyNode copy = (UnsafeCopyNode) res;
-            UnsafeLoadNode value = b.add(new UnsafeLoadNode(copy.sourceObject(), copy.sourceOffset(), copy.accessKind(), copy.getLocationIdentity()));
-            b.add(new UnsafeStoreNode(copy.destinationObject(), copy.destinationOffset(), value, copy.accessKind(), copy.getLocationIdentity()));
-            return true;
-        } else if (res instanceof ForeignCallNode) {
-            /*
-             * Need to update the BCI of a ForeignCallNode so that it gets the stateDuring in the
-             * case that the foreign call can deoptimize. As with all deoptimization, we need a
-             * state in a non-intrinsic method.
-             */
-            GraphBuilderContext nonIntrinsicAncestor = b.getNonIntrinsicAncestor();
-            if (nonIntrinsicAncestor != null) {
-                ForeignCallNode foreign = (ForeignCallNode) res;
-                foreign.setBci(nonIntrinsicAncestor.bci());
-            }
-        }
-
-        boolean nonValueType = false;
-        if (returnKind == Kind.Object && stamp instanceof ObjectStamp) {
-            ResolvedJavaType type = ((ObjectStamp) stamp).type();
-            if (type != null && structuralInputType.isAssignableFrom(type)) {
-                assert res.isAllowedUsageType(getInputType(type));
-                nonValueType = true;
-            }
-        }
-
-        if (returnKind != Kind.Void) {
-            assert nonValueType || res.getKind().getStackKind() != Kind.Void;
-            res = b.addPush(returnKind, res);
-        } else {
-            assert res.getKind().getStackKind() == Kind.Void;
-            res = b.add(res);
-        }
-
-        return true;
-    }
-
-    protected ValueNode createNodeIntrinsic(GraphBuilderContext b, ResolvedJavaMethod method, NodeIntrinsic intrinsic, List<ValueNode> args, Stamp stamp) {
-        ValueNode res = nodeIntrinsification.createIntrinsicNode(args, stamp, method, b.getGraph(), intrinsic);
-        assert res != null || b.getGraph().method().getAnnotation(Snippet.class) != null : String.format(
-                        "Could not create node intrinsic for call to %s as one of the arguments expected to be constant isn't: arguments=%s", method.format("%H.%n(%p)"), args);
-        return res;
-    }
-}
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/MethodHandleInvocationPlugin.java	Fri May 29 17:23:14 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +0,0 @@
-/*
- * 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.graph.*;
-import com.oracle.graal.graphbuilderconf.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.CallTargetNode.InvokeKind;
-import com.oracle.graal.replacements.nodes.*;
-import com.oracle.jvmci.meta.*;
-import com.oracle.jvmci.meta.MethodHandleAccessProvider.IntrinsicMethod;
-
-public class MethodHandleInvocationPlugin implements GenericInvocationPlugin {
-    private final MethodHandleAccessProvider methodHandleAccess;
-    private final GenericInvocationPlugin delegate;
-
-    public MethodHandleInvocationPlugin(MethodHandleAccessProvider methodHandleAccess, GenericInvocationPlugin delegate) {
-        this.methodHandleAccess = methodHandleAccess;
-        this.delegate = delegate;
-    }
-
-    @Override
-    public boolean apply(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args) {
-        IntrinsicMethod intrinsicMethod = methodHandleAccess.lookupMethodHandleIntrinsic(method);
-        if (intrinsicMethod != null) {
-            InvokeKind invokeKind = b.getInvokeKind();
-            if (invokeKind != InvokeKind.Static) {
-                args[0] = b.nullCheckedValue(args[0]);
-            }
-            JavaType invokeReturnType = b.getInvokeReturnType();
-            InvokeNode invoke = MethodHandleNode.tryResolveTargetInvoke(b.getAssumptions(), b.getConstantReflection().getMethodHandleAccess(), intrinsicMethod, method, b.bci(), invokeReturnType, args);
-            if (invoke == null) {
-                MethodHandleNode methodHandleNode = new MethodHandleNode(intrinsicMethod, invokeKind, method, b.bci(), invokeReturnType, args);
-                if (invokeReturnType.getKind() == Kind.Void) {
-                    b.add(methodHandleNode);
-                } else {
-                    b.addPush(invokeReturnType.getKind(), methodHandleNode);
-                }
-            } else {
-                CallTargetNode callTarget = invoke.callTarget();
-                NodeInputList<ValueNode> argumentsList = callTarget.arguments();
-                ValueNode[] newArgs = argumentsList.toArray(new ValueNode[argumentsList.size()]);
-                for (ValueNode arg : newArgs) {
-                    b.recursiveAppend(arg);
-                }
-                b.handleReplacedInvoke(invoke.getInvokeKind(), callTarget.targetMethod(), newArgs);
-            }
-            return true;
-        }
-        return delegate.apply(b, method, args);
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/MethodHandlePlugin.java	Fri May 29 13:19:05 2015 -0700
@@ -0,0 +1,70 @@
+/*
+ * 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.graph.*;
+import com.oracle.graal.graphbuilderconf.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.CallTargetNode.InvokeKind;
+import com.oracle.graal.replacements.nodes.*;
+import com.oracle.jvmci.meta.*;
+import com.oracle.jvmci.meta.MethodHandleAccessProvider.IntrinsicMethod;
+
+public class MethodHandlePlugin implements NodePlugin {
+    private final MethodHandleAccessProvider methodHandleAccess;
+
+    public MethodHandlePlugin(MethodHandleAccessProvider methodHandleAccess) {
+        this.methodHandleAccess = methodHandleAccess;
+    }
+
+    @Override
+    public boolean handleInvoke(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args) {
+        IntrinsicMethod intrinsicMethod = methodHandleAccess.lookupMethodHandleIntrinsic(method);
+        if (intrinsicMethod != null) {
+            InvokeKind invokeKind = b.getInvokeKind();
+            if (invokeKind != InvokeKind.Static) {
+                args[0] = b.nullCheckedValue(args[0]);
+            }
+            JavaType invokeReturnType = b.getInvokeReturnType();
+            InvokeNode invoke = MethodHandleNode.tryResolveTargetInvoke(b.getAssumptions(), b.getConstantReflection().getMethodHandleAccess(), intrinsicMethod, method, b.bci(), invokeReturnType, args);
+            if (invoke == null) {
+                MethodHandleNode methodHandleNode = new MethodHandleNode(intrinsicMethod, invokeKind, method, b.bci(), invokeReturnType, args);
+                if (invokeReturnType.getKind() == Kind.Void) {
+                    b.add(methodHandleNode);
+                } else {
+                    b.addPush(invokeReturnType.getKind(), methodHandleNode);
+                }
+            } else {
+                CallTargetNode callTarget = invoke.callTarget();
+                NodeInputList<ValueNode> argumentsList = callTarget.arguments();
+                ValueNode[] newArgs = argumentsList.toArray(new ValueNode[argumentsList.size()]);
+                for (ValueNode arg : newArgs) {
+                    b.recursiveAppend(arg);
+                }
+                b.handleReplacedInvoke(invoke.getInvokeKind(), callTarget.targetMethod(), newArgs);
+            }
+            return true;
+        }
+        return false;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPlugin.java	Fri May 29 13:19:05 2015 -0700
@@ -0,0 +1,201 @@
+/*
+ * 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 static com.oracle.graal.replacements.NodeIntrinsificationPhase.*;
+import static com.oracle.jvmci.meta.MetaUtil.*;
+
+import java.util.*;
+
+import com.oracle.graal.api.replacements.*;
+import com.oracle.graal.compiler.*;
+import com.oracle.graal.compiler.common.type.*;
+import com.oracle.graal.graph.Node.NodeIntrinsic;
+import com.oracle.graal.graphbuilderconf.*;
+import com.oracle.graal.nodeinfo.*;
+import com.oracle.graal.nodeinfo.StructuralInput.MarkerType;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.word.*;
+import com.oracle.jvmci.common.*;
+import com.oracle.jvmci.meta.*;
+
+/**
+ * An {@link NodePlugin} that handles methods annotated by {@link Fold} and {@link NodeIntrinsic}.
+ */
+public class NodeIntrinsificationPlugin implements NodePlugin {
+    protected final NodeIntrinsificationPhase nodeIntrinsification;
+    private final WordTypes wordTypes;
+    private final ResolvedJavaType structuralInputType;
+    private final boolean mustIntrinsify;
+
+    public NodeIntrinsificationPlugin(MetaAccessProvider metaAccess, NodeIntrinsificationPhase nodeIntrinsification, WordTypes wordTypes, boolean mustIntrinsify) {
+        this.nodeIntrinsification = nodeIntrinsification;
+        this.wordTypes = wordTypes;
+        this.mustIntrinsify = mustIntrinsify;
+        this.structuralInputType = metaAccess.lookupJavaType(StructuralInput.class);
+    }
+
+    /**
+     * Calls in replacements to methods matching one of these filters are elided. Only void methods
+     * are considered for elision. The use of "snippets" in name of the variable and system property
+     * is purely for legacy reasons.
+     */
+    private static final MethodFilter[] MethodsElidedInSnippets = getMethodsElidedInSnippets();
+
+    private static MethodFilter[] getMethodsElidedInSnippets() {
+        String commaSeparatedPatterns = System.getProperty("graal.MethodsElidedInSnippets");
+        if (commaSeparatedPatterns != null) {
+            return MethodFilter.parse(commaSeparatedPatterns);
+        }
+        return null;
+    }
+
+    @Override
+    public boolean handleInvoke(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args) {
+        NodeIntrinsic intrinsic = nodeIntrinsification.getIntrinsic(method);
+        if (intrinsic != null) {
+            Signature sig = method.getSignature();
+            Kind returnKind = sig.getReturnKind();
+            Stamp stamp = StampFactory.forKind(returnKind);
+            if (returnKind == Kind.Object) {
+                JavaType returnType = sig.getReturnType(method.getDeclaringClass());
+                if (returnType instanceof ResolvedJavaType) {
+                    ResolvedJavaType resolvedReturnType = (ResolvedJavaType) returnType;
+                    if (wordTypes.isWord(resolvedReturnType)) {
+                        stamp = wordTypes.getWordStamp(resolvedReturnType);
+                    } else {
+                        stamp = StampFactory.declared(resolvedReturnType);
+                    }
+                }
+            }
+
+            boolean result = processNodeIntrinsic(b, method, intrinsic, Arrays.asList(args), returnKind, stamp);
+            if (!result && mustIntrinsify) {
+                reportIntrinsificationFailure(b, method, args);
+            }
+            return result;
+
+        } else if (nodeIntrinsification.isFoldable(method)) {
+            ResolvedJavaType[] parameterTypes = resolveJavaTypes(method.toParameterTypes(), method.getDeclaringClass());
+            JavaConstant constant = nodeIntrinsification.tryFold(Arrays.asList(args), parameterTypes, method);
+            if (!COULD_NOT_FOLD.equals(constant)) {
+                if (constant != null) {
+                    // Replace the invoke with the result of the call
+                    b.push(method.getSignature().getReturnKind(), ConstantNode.forConstant(constant, b.getMetaAccess(), b.getGraph()));
+                } else {
+                    // This must be a void invoke
+                    assert method.getSignature().getReturnKind() == Kind.Void;
+                }
+                return true;
+            } else if (mustIntrinsify) {
+                reportIntrinsificationFailure(b, method, args);
+            }
+
+        } else if (MethodsElidedInSnippets != null) {
+            if (MethodFilter.matches(MethodsElidedInSnippets, method)) {
+                if (method.getSignature().getReturnKind() != Kind.Void) {
+                    throw new JVMCIError("Cannot elide non-void method " + method.format("%H.%n(%p)"));
+                }
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private static boolean reportIntrinsificationFailure(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args) {
+        StringBuilder msg = new StringBuilder();
+        msg.append("Call in ").append(b.getMethod().format("%H.%n(%p)"));
+        msg.append(" to ").append(method.format("%H.%n(%p)"));
+        msg.append(" cannot be intrisfied or folded, probably because an argument is not a constant. Arguments: ");
+        String sep = "";
+        for (ValueNode node : args) {
+            msg.append(sep).append(node.toString());
+            sep = ", ";
+        }
+        throw new JVMCIError(msg.toString());
+    }
+
+    private InputType getInputType(ResolvedJavaType type) {
+        if (type != null && structuralInputType.isAssignableFrom(type)) {
+            MarkerType markerType = type.getAnnotation(MarkerType.class);
+            if (markerType != null) {
+                return markerType.value();
+            } else {
+                throw JVMCIError.shouldNotReachHere(String.format("%s extends StructuralInput, but is not annotated with @MarkerType", type));
+            }
+        } else {
+            return InputType.Value;
+        }
+    }
+
+    private boolean processNodeIntrinsic(GraphBuilderContext b, ResolvedJavaMethod method, NodeIntrinsic intrinsic, List<ValueNode> args, Kind returnKind, Stamp stamp) {
+        ValueNode res = createNodeIntrinsic(b, method, intrinsic, args, stamp);
+        if (res == null) {
+            return false;
+        }
+        if (res instanceof UnsafeCopyNode) {
+            UnsafeCopyNode copy = (UnsafeCopyNode) res;
+            UnsafeLoadNode value = b.add(new UnsafeLoadNode(copy.sourceObject(), copy.sourceOffset(), copy.accessKind(), copy.getLocationIdentity()));
+            b.add(new UnsafeStoreNode(copy.destinationObject(), copy.destinationOffset(), value, copy.accessKind(), copy.getLocationIdentity()));
+            return true;
+        } else if (res instanceof ForeignCallNode) {
+            /*
+             * Need to update the BCI of a ForeignCallNode so that it gets the stateDuring in the
+             * case that the foreign call can deoptimize. As with all deoptimization, we need a
+             * state in a non-intrinsic method.
+             */
+            GraphBuilderContext nonIntrinsicAncestor = b.getNonIntrinsicAncestor();
+            if (nonIntrinsicAncestor != null) {
+                ForeignCallNode foreign = (ForeignCallNode) res;
+                foreign.setBci(nonIntrinsicAncestor.bci());
+            }
+        }
+
+        boolean nonValueType = false;
+        if (returnKind == Kind.Object && stamp instanceof ObjectStamp) {
+            ResolvedJavaType type = ((ObjectStamp) stamp).type();
+            if (type != null && structuralInputType.isAssignableFrom(type)) {
+                assert res.isAllowedUsageType(getInputType(type));
+                nonValueType = true;
+            }
+        }
+
+        if (returnKind != Kind.Void) {
+            assert nonValueType || res.getKind().getStackKind() != Kind.Void;
+            res = b.addPush(returnKind, res);
+        } else {
+            assert res.getKind().getStackKind() == Kind.Void;
+            res = b.add(res);
+        }
+
+        return true;
+    }
+
+    private ValueNode createNodeIntrinsic(GraphBuilderContext b, ResolvedJavaMethod method, NodeIntrinsic intrinsic, List<ValueNode> args, Stamp stamp) {
+        ValueNode res = nodeIntrinsification.createIntrinsicNode(args, stamp, method, b.getGraph(), intrinsic);
+        assert res != null || b.getGraph().method().getAnnotation(Snippet.class) != null : String.format(
+                        "Could not create node intrinsic for call to %s as one of the arguments expected to be constant isn't: arguments=%s", method.format("%H.%n(%p)"), args);
+        return res;
+    }
+}
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Fri May 29 17:23:14 2015 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Fri May 29 13:19:05 2015 -0700
@@ -105,7 +105,7 @@
             return null;
         }
         if (b.parsingIntrinsic()) {
-            assert !hasGenericInvocationPluginAnnotation(method) : format("%s should have been handled by %s", method.format("%H.%n(%p)"), DefaultGenericInvocationPlugin.class.getName());
+            assert !hasGenericInvocationPluginAnnotation(method) : format("%s should have been handled by %s", method.format("%H.%n(%p)"), NodeIntrinsificationPlugin.class.getName());
 
             assert b.getDepth() < MAX_GRAPH_INLINING_DEPTH : "inlining limit exceeded";
 
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/WordOperationPlugin.java	Fri May 29 17:23:14 2015 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/WordOperationPlugin.java	Fri May 29 13:19:05 2015 -0700
@@ -34,7 +34,9 @@
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.memory.HeapAccess.BarrierType;
+import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.word.*;
 import com.oracle.graal.word.Word.Opcode;
 import com.oracle.graal.word.Word.Operation;
@@ -43,10 +45,10 @@
 import com.oracle.jvmci.meta.*;
 
 /**
- * A {@link GenericInvocationPlugin} for calls to {@linkplain Operation word operations}, and a
- * {@link TypeCheckPlugin} to handle casts between word types.
+ * A plugin for calls to {@linkplain Operation word operations}, as well as all other nodes that
+ * need special handling for {@link Word} types.
  */
-public class WordOperationPlugin implements GenericInvocationPlugin, TypeCheckPlugin {
+public class WordOperationPlugin implements NodePlugin, ParameterPlugin, InlineInvokePlugin {
     protected final WordTypes wordTypes;
     protected final Kind wordKind;
     protected final SnippetReflectionProvider snippetReflection;
@@ -64,7 +66,8 @@
      * @return {@code true} iff {@code method} is annotated with {@link Operation} (and was thus
      *         processed by this method)
      */
-    public boolean apply(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args) {
+    @Override
+    public boolean handleInvoke(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args) {
         if (!wordTypes.isWordOperation(method)) {
             return false;
         }
@@ -73,7 +76,79 @@
     }
 
     @Override
-    public boolean checkCast(GraphBuilderContext b, ValueNode object, ResolvedJavaType type, JavaTypeProfile profile) {
+    public FloatingNode interceptParameter(GraphBuilderContext b, int index, Stamp stamp) {
+        ResolvedJavaType type = StampTool.typeOrNull(stamp);
+        if (wordTypes.isWord(type)) {
+            return new ParameterNode(index, wordTypes.getWordStamp(type));
+        }
+        return null;
+    }
+
+    @Override
+    public void notifyOfNoninlinedInvoke(GraphBuilderContext b, ResolvedJavaMethod method, Invoke invoke) {
+        if (wordTypes.isWord(invoke.asNode())) {
+            invoke.asNode().setStamp(wordTypes.getWordStamp(StampTool.typeOrNull(invoke.asNode())));
+        }
+    }
+
+    @Override
+    public boolean handleLoadField(GraphBuilderContext b, ValueNode receiver, ResolvedJavaField field) {
+        if (field.getType() instanceof ResolvedJavaType && wordTypes.isWord((ResolvedJavaType) field.getType())) {
+            LoadFieldNode loadFieldNode = new LoadFieldNode(receiver, field);
+            loadFieldNode.setStamp(wordTypes.getWordStamp((ResolvedJavaType) field.getType()));
+            b.addPush(field.getKind(), loadFieldNode);
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public boolean handleLoadStaticField(GraphBuilderContext b, ResolvedJavaField staticField) {
+        return handleLoadField(b, null, staticField);
+    }
+
+    @Override
+    public boolean handleLoadIndexed(GraphBuilderContext b, ValueNode array, ValueNode index, Kind elementKind) {
+        ResolvedJavaType arrayType = StampTool.typeOrNull(array);
+        /*
+         * There are cases where the array does not have a known type yet, i.e., the type is null.
+         * In that case we assume it is not a word type.
+         */
+        if (arrayType != null && wordTypes.isWord(arrayType.getComponentType())) {
+            assert elementKind == Kind.Object;
+            b.addPush(elementKind, createLoadIndexedNode(array, index));
+            return true;
+        }
+        return false;
+    }
+
+    protected LoadIndexedNode createLoadIndexedNode(ValueNode array, ValueNode index) {
+        return new LoadIndexedNode(array, index, wordTypes.getWordKind());
+    }
+
+    @Override
+    public boolean handleStoreIndexed(GraphBuilderContext b, ValueNode array, ValueNode index, Kind elementKind, ValueNode value) {
+        ResolvedJavaType arrayType = StampTool.typeOrNull(array);
+        if (arrayType != null && wordTypes.isWord(arrayType.getComponentType())) {
+            assert elementKind == Kind.Object;
+            if (value.getKind() != wordTypes.getWordKind()) {
+                throw b.bailout("Cannot store a non-word value into a word array: " + arrayType.toJavaName(true));
+            }
+            b.add(createStoreIndexedNode(array, index, value));
+            return true;
+        }
+        if (elementKind == Kind.Object && value.getKind() == wordTypes.getWordKind()) {
+            throw b.bailout("Cannot store a word value into a non-word array: " + arrayType.toJavaName(true));
+        }
+        return false;
+    }
+
+    protected StoreIndexedNode createStoreIndexedNode(ValueNode array, ValueNode index, ValueNode value) {
+        return new StoreIndexedNode(array, index, wordTypes.getWordKind(), value);
+    }
+
+    @Override
+    public boolean handleCheckCast(GraphBuilderContext b, ValueNode object, ResolvedJavaType type, JavaTypeProfile profile) {
         if (!wordTypes.isWord(type)) {
             if (object.getKind() != Kind.Object) {
                 throw b.bailout("Cannot cast a word value to a non-word type: " + type.toJavaName(true));
@@ -89,7 +164,7 @@
     }
 
     @Override
-    public boolean instanceOf(GraphBuilderContext b, ValueNode object, ResolvedJavaType type, JavaTypeProfile profile) {
+    public boolean handleInstanceOf(GraphBuilderContext b, ValueNode object, ResolvedJavaType type, JavaTypeProfile profile) {
         if (wordTypes.isWord(type)) {
             throw b.bailout("Cannot use instanceof for word a type: " + type.toJavaName(true));
         } else if (object.getKind() != Kind.Object) {
--- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/ConditionAnchoringTest.java	Fri May 29 17:23:14 2015 +0200
+++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/ConditionAnchoringTest.java	Fri May 29 13:19:05 2015 -0700
@@ -22,12 +22,6 @@
  */
 package com.oracle.graal.truffle.test;
 
-import com.oracle.jvmci.meta.ConstantReflectionProvider;
-import com.oracle.jvmci.meta.ResolvedJavaMethod;
-import com.oracle.jvmci.meta.JavaConstant;
-import com.oracle.jvmci.meta.MetaAccessProvider;
-import com.oracle.jvmci.meta.JavaType;
-import com.oracle.jvmci.meta.ResolvedJavaField;
 import static com.oracle.graal.graph.test.matchers.NodeIterableCount.*;
 import static com.oracle.graal.graph.test.matchers.NodeIterableIsEmpty.*;
 import static org.hamcrest.core.IsInstanceOf.*;
@@ -49,6 +43,7 @@
 import com.oracle.graal.phases.tiers.*;
 import com.oracle.graal.truffle.nodes.*;
 import com.oracle.graal.truffle.substitutions.*;
+import com.oracle.jvmci.meta.*;
 import com.oracle.truffle.api.*;
 import com.oracle.truffle.api.unsafe.*;
 
@@ -146,7 +141,6 @@
         TruffleGraphBuilderPlugins.registerUnsafeAccessImplPlugins(conf.getPlugins().getInvocationPlugins(), false);
         // get UnsafeAccess.getInt inlined
         conf.getPlugins().setInlineInvokePlugin(new InlineEverythingPlugin());
-        conf.getPlugins().setLoadFieldPlugin(new FoldLoadsPlugins(getMetaAccess(), getConstantReflection()));
         return super.editGraphBuilderConfiguration(conf);
     }
 
@@ -156,26 +150,4 @@
             return new InlineInfo(method, false);
         }
     }
-
-    private static final class FoldLoadsPlugins implements LoadFieldPlugin {
-        private final MetaAccessProvider metaAccess;
-        private final ConstantReflectionProvider constantReflection;
-
-        public FoldLoadsPlugins(MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection) {
-            this.metaAccess = metaAccess;
-            this.constantReflection = constantReflection;
-        }
-
-        public boolean apply(GraphBuilderContext graphBuilderContext, ValueNode receiver, ResolvedJavaField field) {
-            if (receiver.isConstant()) {
-                JavaConstant asJavaConstant = receiver.asJavaConstant();
-                return tryConstantFold(graphBuilderContext, metaAccess, constantReflection, field, asJavaConstant);
-            }
-            return false;
-        }
-
-        public boolean apply(GraphBuilderContext graphBuilderContext, ResolvedJavaField staticField) {
-            return tryConstantFold(graphBuilderContext, metaAccess, constantReflection, staticField, null);
-        }
-    }
 }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Fri May 29 17:23:14 2015 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Fri May 29 13:19:05 2015 -0700
@@ -22,13 +22,6 @@
  */
 package com.oracle.graal.truffle;
 
-import com.oracle.jvmci.code.Architecture;
-import com.oracle.jvmci.meta.JavaType;
-import com.oracle.jvmci.meta.JavaConstant;
-import com.oracle.jvmci.meta.ResolvedJavaField;
-import com.oracle.jvmci.meta.ResolvedJavaType;
-import com.oracle.jvmci.meta.ResolvedJavaMethod;
-import com.oracle.jvmci.meta.Kind;
 import static com.oracle.graal.compiler.common.GraalOptions.*;
 import static com.oracle.graal.java.GraphBuilderPhase.Options.*;
 import static com.oracle.graal.truffle.TruffleCompilerOptions.*;
@@ -60,9 +53,11 @@
 import com.oracle.graal.truffle.phases.*;
 import com.oracle.graal.truffle.substitutions.*;
 import com.oracle.graal.virtual.phases.ea.*;
+import com.oracle.jvmci.code.*;
 import com.oracle.jvmci.common.*;
 import com.oracle.jvmci.debug.*;
 import com.oracle.jvmci.debug.Debug.Scope;
+import com.oracle.jvmci.meta.*;
 import com.oracle.jvmci.options.*;
 import com.oracle.truffle.api.*;
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
@@ -134,21 +129,6 @@
         return graph;
     }
 
-    private class InterceptLoadFieldPlugin implements LoadFieldPlugin {
-
-        public boolean apply(GraphBuilderContext builder, ValueNode receiver, ResolvedJavaField field) {
-            if (receiver.isConstant()) {
-                JavaConstant asJavaConstant = receiver.asJavaConstant();
-                return tryConstantFold(builder, providers.getMetaAccess(), providers.getConstantReflection(), field, asJavaConstant);
-            }
-            return false;
-        }
-
-        public boolean apply(GraphBuilderContext builder, ResolvedJavaField staticField) {
-            return tryConstantFold(builder, providers.getMetaAccess(), providers.getConstantReflection(), staticField, null);
-        }
-    }
-
     private class InterceptReceiverPlugin implements ParameterPlugin {
 
         private final Object receiver;
@@ -309,7 +289,6 @@
 
         newConfig.setUseProfiling(false);
         Plugins plugins = newConfig.getPlugins();
-        plugins.setLoadFieldPlugin(new InterceptLoadFieldPlugin());
         plugins.setParameterPlugin(new InterceptReceiverPlugin(callTarget));
         callTarget.setInlining(new TruffleInlining(callTarget, new DefaultInliningPolicy()));
 
@@ -334,7 +313,6 @@
 
         newConfig.setUseProfiling(false);
         Plugins plugins = newConfig.getPlugins();
-        plugins.setLoadFieldPlugin(new InterceptLoadFieldPlugin());
         plugins.setInlineInvokePlugin(new ParsingInlineInvokePlugin((ReplacementsImpl) providers.getReplacements(), parsingInvocationPlugins, loopExplosionPlugin,
                         !PrintTruffleExpansionHistogram.getValue()));