changeset 19500:b828f1f74625

add graph builder plugins for Unsafe and Word
author Doug Simon <doug.simon@oracle.com>
date Thu, 19 Feb 2015 11:22:44 +0100
parents 787a3c7235ef
children 97940c4ee511
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotHostBackend.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/HotSpotSuitesProvider.java graal/com.oracle.graal.java/src/com/oracle/graal/java/StandardGraphBuilderPlugins.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/StandardGraphBuilderPlugins.java
diffstat 5 files changed, 408 insertions(+), 126 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotHostBackend.java	Thu Feb 19 11:21:40 2015 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotHostBackend.java	Thu Feb 19 11:22:44 2015 +0100
@@ -33,6 +33,7 @@
 import com.oracle.graal.hotspot.stubs.*;
 import com.oracle.graal.java.*;
 import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.replacements.*;
 
 /**
  * Common functionality of HotSpot host backends.
@@ -73,7 +74,7 @@
         try (InitTimer st = timer("graphBuilderPlugins.initialize")) {
             GraphBuilderPhase phase = (GraphBuilderPhase) providers.getSuites().getDefaultGraphBuilderSuite().findPhase(GraphBuilderPhase.class).previous();
             InvocationPlugins plugins = phase.getGraphBuilderConfig().getInvocationPlugins();
-            registerInvocationPlugins(providers.getMetaAccess(), plugins);
+            registerInvocationPlugins(providers, plugins);
         }
 
         try (InitTimer st = timer("foreignCalls.initialize")) {
@@ -105,8 +106,8 @@
         }
     }
 
-    protected void registerInvocationPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) {
-        StandardGraphBuilderPlugins.registerInvocationPlugins(metaAccess, plugins);
-        HotSpotGraphBuilderPlugins.registerInvocationPlugins(metaAccess, plugins);
+    protected void registerInvocationPlugins(HotSpotProviders providers, InvocationPlugins plugins) {
+        StandardGraphBuilderPlugins.registerInvocationPlugins(providers.getMetaAccess(), plugins);
+        HotSpotGraphBuilderPlugins.registerInvocationPlugins(providers, plugins);
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java	Thu Feb 19 11:21:40 2015 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java	Thu Feb 19 11:22:44 2015 +0100
@@ -22,27 +22,39 @@
  */
 package com.oracle.graal.hotspot.meta;
 
+import static com.oracle.graal.api.meta.LocationIdentity.*;
 import static com.oracle.graal.java.GraphBuilderContext.*;
+import static java.lang.Character.*;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.compiler.common.type.*;
+import com.oracle.graal.hotspot.nodes.type.*;
 import com.oracle.graal.hotspot.replacements.*;
+import com.oracle.graal.hotspot.word.*;
 import com.oracle.graal.java.*;
 import com.oracle.graal.java.GraphBuilderPlugin.InvocationPlugin;
 import com.oracle.graal.java.InvocationPlugins.Registration;
 import com.oracle.graal.java.InvocationPlugins.Registration.Receiver;
 import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.HeapAccess.BarrierType;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.options.*;
+import com.oracle.graal.word.*;
+import com.oracle.graal.word.nodes.*;
 
 /**
  * Provides HotSpot specific {@link InvocationPlugin}s.
  */
 public class HotSpotGraphBuilderPlugins {
-    public static void registerInvocationPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) {
+    public static void registerInvocationPlugins(HotSpotProviders providers, InvocationPlugins plugins) {
+        MetaAccessProvider metaAccess = providers.getMetaAccess();
+        SnippetReflectionProvider snippetReflection = providers.getSnippetReflection();
+        Kind wordKind = providers.getCodeCache().getTarget().wordKind;
+
         // Object.class
         Registration r = new Registration(plugins, metaAccess, Object.class);
         r.register1("getClass", Receiver.class, new InvocationPlugin() {
@@ -103,5 +115,130 @@
                 return false;
             }
         });
+
+        // MetaspacePointer.class
+        r = new Registration(plugins, metaAccess, MetaspacePointer.class);
+        r.register1("isNull", Receiver.class, new InvocationPlugin() {
+            public boolean apply(GraphBuilderContext builder, ValueNode pointer) {
+                assert pointer.stamp() instanceof MetaspacePointerStamp;
+                IsNullNode isNull = builder.append(new IsNullNode(pointer));
+                ConstantNode trueValue = builder.append(ConstantNode.forBoolean(true));
+                ConstantNode falseValue = builder.append(ConstantNode.forBoolean(false));
+                builder.push(Kind.Boolean.getStackKind(), builder.append(new ConditionalNode(isNull, trueValue, falseValue)));
+                return true;
+            }
+        });
+        r.register1("asWord", Receiver.class, new InvocationPlugin() {
+            public boolean apply(GraphBuilderContext builder, ValueNode pointer) {
+                builder.append(new PointerCastNode(StampFactory.forKind(wordKind), pointer));
+                return true;
+            }
+        });
+        r.register2("readObject", Receiver.class, int.class, new ReadOp(snippetReflection, wordKind, Kind.Object, BarrierType.NONE, true));
+        r.register3("readObject", Receiver.class, int.class, LocationIdentity.class, new ReadOp(snippetReflection, wordKind, Kind.Object, BarrierType.NONE, true));
+        r.register3("readObject", Receiver.class, int.class, BarrierType.class, new ReadOp(snippetReflection, wordKind, Kind.Object, BarrierType.NONE, true));
+        r.register2("readObject", Receiver.class, WordBase.class, new ReadOp(snippetReflection, wordKind, Kind.Object, BarrierType.NONE, true));
+        r.register3("readObject", Receiver.class, WordBase.class, LocationIdentity.class, new ReadOp(snippetReflection, wordKind, Kind.Object, BarrierType.NONE, true));
+        r.register3("readObject", Receiver.class, WordBase.class, BarrierType.class, new ReadOp(snippetReflection, wordKind, Kind.Object, BarrierType.NONE, true));
+
+        registerWordOpPlugins(r, snippetReflection, wordKind, Kind.Byte, Kind.Short, Kind.Char, Kind.Int, Kind.Float, Kind.Long, Kind.Double);
+    }
+
+    protected static void registerWordOpPlugins(Registration r, SnippetReflectionProvider snippetReflection, Kind wordKind, Kind... kinds) {
+        for (Kind kind : kinds) {
+            String kindName = kind.getJavaName();
+            kindName = toUpperCase(kindName.charAt(0)) + kindName.substring(1);
+            String getName = "read" + kindName;
+            // String putName = "write" + kindName;
+            r.register2(getName, Receiver.class, int.class, new ReadOp(snippetReflection, wordKind, kind));
+            r.register3(getName, Receiver.class, int.class, LocationIdentity.class, new ReadOp(snippetReflection, wordKind, kind));
+        }
+    }
+
+    static class ReadOp implements InvocationPlugin {
+        final SnippetReflectionProvider snippetReflection;
+        final Kind wordKind;
+        final Kind resultKind;
+        final BarrierType barrierType;
+        final boolean compressible;
+
+        public ReadOp(SnippetReflectionProvider snippetReflection, Kind wordKind, Kind resultKind, BarrierType barrierType, boolean compressible) {
+            this.snippetReflection = snippetReflection;
+            this.wordKind = wordKind;
+            this.resultKind = resultKind;
+            this.barrierType = barrierType;
+            this.compressible = compressible;
+        }
+
+        public ReadOp(SnippetReflectionProvider snippetReflection, Kind wordKind, Kind resultKind) {
+            this(snippetReflection, wordKind, resultKind, BarrierType.NONE, false);
+        }
+
+        public boolean apply(GraphBuilderContext builder, ValueNode pointer, ValueNode offset) {
+            LocationNode location = makeLocation(builder, offset, ANY_LOCATION, wordKind);
+            builder.push(resultKind, builder.append(readOp(builder, resultKind, pointer, location, barrierType, compressible)));
+            return true;
+        }
+
+        public boolean apply(GraphBuilderContext builder, ValueNode pointer, ValueNode offset, ValueNode locationIdentityArg) {
+            assert locationIdentityArg.isConstant();
+            LocationIdentity locationIdentity = snippetReflection.asObject(LocationIdentity.class, locationIdentityArg.asJavaConstant());
+            LocationNode location = makeLocation(builder, offset, locationIdentity, wordKind);
+            builder.push(resultKind, builder.append(readOp(builder, resultKind, pointer, location, barrierType, compressible)));
+            return true;
+        }
+    }
+
+    public static ValueNode readOp(GraphBuilderContext builder, Kind readKind, ValueNode base, LocationNode location, BarrierType barrierType, boolean compressible) {
+        JavaReadNode read = builder.append(new JavaReadNode(readKind, base, location, barrierType, compressible));
+        /*
+         * The read must not float outside its block otherwise it may float above an explicit zero
+         * check on its base address.
+         */
+        read.setGuard(builder.getCurrentBlockGuard());
+        return read;
+    }
+
+    public static LocationNode makeLocation(GraphBuilderContext builder, ValueNode offset, LocationIdentity locationIdentity, Kind wordKind) {
+        return builder.append(new IndexedLocationNode(locationIdentity, 0, fromSigned(builder, offset, wordKind), 1));
+    }
+
+    public static LocationNode makeLocation(GraphBuilderContext builder, ValueNode offset, ValueNode locationIdentity, Kind wordKind) {
+        if (locationIdentity.isConstant()) {
+            return makeLocation(builder, offset, builder.getSnippetReflection().asObject(LocationIdentity.class, locationIdentity.asJavaConstant()), wordKind);
+        }
+        return builder.append(new SnippetLocationNode(builder.getSnippetReflection(), locationIdentity, builder.append(ConstantNode.forLong(0)), fromSigned(builder, offset, wordKind),
+                        builder.append(ConstantNode.forInt(1))));
+    }
+
+    public static ValueNode fromUnsigned(GraphBuilderContext builder, ValueNode value, Kind wordKind) {
+        return convert(builder, value, wordKind, true);
+    }
+
+    public static ValueNode fromSigned(GraphBuilderContext builder, ValueNode value, Kind wordKind) {
+        return convert(builder, value, wordKind, false);
+    }
+
+    public static ValueNode toUnsigned(GraphBuilderContext builder, ValueNode value, Kind toKind) {
+        return convert(builder, value, toKind, true);
+    }
+
+    public static ValueNode convert(GraphBuilderContext builder, ValueNode value, Kind toKind, boolean unsigned) {
+        if (value.getKind() == toKind) {
+            return value;
+        }
+
+        if (toKind == Kind.Int) {
+            assert value.getKind() == Kind.Long;
+            return builder.append(new NarrowNode(value, 32));
+        } else {
+            assert toKind == Kind.Long;
+            assert value.getKind().getStackKind() == Kind.Int;
+            if (unsigned) {
+                return builder.append(new ZeroExtendNode(value, 64));
+            } else {
+                return builder.append(new SignExtendNode(value, 64));
+            }
+        }
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSuitesProvider.java	Thu Feb 19 11:21:40 2015 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSuitesProvider.java	Thu Feb 19 11:22:44 2015 +0100
@@ -22,14 +22,21 @@
  */
 package com.oracle.graal.hotspot.meta;
 
+import static com.oracle.graal.api.meta.MetaUtil.*;
 import static com.oracle.graal.compiler.common.GraalOptions.*;
+import static com.oracle.graal.replacements.NodeIntrinsificationPhase.*;
+
+import java.util.*;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.common.type.*;
+import com.oracle.graal.graph.Node.NodeIntrinsic;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.bridge.*;
 import com.oracle.graal.hotspot.phases.*;
 import com.oracle.graal.java.*;
 import com.oracle.graal.java.GraphBuilderConfiguration.DebugInfoMode;
+import com.oracle.graal.java.GraphBuilderPlugin.AnnotatedInvocationPlugin;
 import com.oracle.graal.java.GraphBuilderPlugin.InlineInvokePlugin;
 import com.oracle.graal.java.GraphBuilderPlugin.LoadFieldPlugin;
 import com.oracle.graal.lir.phases.*;
@@ -39,6 +46,7 @@
 import com.oracle.graal.options.DerivedOptionValue.OptionSupplier;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.tiers.*;
+import com.oracle.graal.replacements.*;
 
 /**
  * HotSpot implementation of {@link SuitesProvider}.
@@ -104,6 +112,20 @@
         return ret;
     }
 
+    NodeIntrinsificationPhase intrinsifier;
+
+    NodeIntrinsificationPhase getIntrinsifier() {
+        if (intrinsifier == null) {
+            HotSpotProviders providers = runtime.getHostProviders();
+            intrinsifier = new NodeIntrinsificationPhase(providers, providers.getSnippetReflection());
+        }
+        return intrinsifier;
+    }
+
+    MetaAccessProvider getMetaAccess() {
+        return runtime.getHostProviders().getMetaAccess();
+    }
+
     protected PhaseSuite<HighTierContext> createGraphBuilderSuite(MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, Replacements replacements) {
         PhaseSuite<HighTierContext> suite = new PhaseSuite<>();
         GraphBuilderConfiguration config = GraphBuilderConfiguration.getDefault();
@@ -127,12 +149,57 @@
                     if (subst != null) {
                         return subst;
                     }
+                    if (builder.parsingReplacement() && method.getAnnotation(NodeIntrinsic.class) == null) {
+                        return method;
+                    }
                     if (method.hasBytecodes() && method.getCode().length <= TrivialInliningSize.getValue() && depth < InlineDuringParsingMaxDepth.getValue()) {
                         return method;
                     }
                     return null;
                 }
             });
+            config.setAnnotatedInvocationPlugin(new AnnotatedInvocationPlugin() {
+                public boolean apply(GraphBuilderContext builder, ResolvedJavaMethod method, ValueNode[] args) {
+                    if (builder.parsingReplacement()) {
+                        @SuppressWarnings("hiding")
+                        NodeIntrinsificationPhase intrinsifier = getIntrinsifier();
+                        NodeIntrinsic intrinsic = intrinsifier.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) {
+                                    stamp = StampFactory.declared((ResolvedJavaType) returnType);
+                                }
+                            }
+
+                            ValueNode res = intrinsifier.createIntrinsicNode(Arrays.asList(args), stamp, method, builder.getGraph(), intrinsic);
+                            res = builder.append(res);
+                            if (res.getKind().getStackKind() != Kind.Void) {
+                                builder.push(returnKind.getStackKind(), res);
+                            }
+                            return true;
+                        } else if (intrinsifier.isFoldable(method)) {
+                            ResolvedJavaType[] parameterTypes = resolveJavaTypes(method.toParameterTypes(), method.getDeclaringClass());
+                            JavaConstant constant = intrinsifier.tryFold(Arrays.asList(args), parameterTypes, method);
+                            if (!COULD_NOT_FOLD.equals(constant)) {
+                                if (constant != null) {
+                                    // Replace the invoke with the result of the call
+                                    ConstantNode res = builder.append(ConstantNode.forConstant(constant, getMetaAccess()));
+                                    builder.push(res.getKind().getStackKind(), builder.append(res));
+                                } else {
+                                    // This must be a void invoke
+                                    assert method.getSignature().getReturnKind() == Kind.Void;
+                                }
+                                return true;
+                            }
+                        }
+                    }
+                    return false;
+                }
+            });
         }
         suite.appendPhase(new GraphBuilderPhase(config));
         return suite;
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/StandardGraphBuilderPlugins.java	Thu Feb 19 11:21:40 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,121 +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.java;
-
-import static com.oracle.graal.java.GraphBuilderContext.*;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.java.GraphBuilderPlugin.InvocationPlugin;
-import com.oracle.graal.java.InvocationPlugins.Registration;
-import com.oracle.graal.java.InvocationPlugins.Registration.Receiver;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.calc.*;
-import com.oracle.graal.nodes.extended.*;
-import com.oracle.graal.nodes.java.*;
-
-/**
- * Provides non-runtime specific {@link InvocationPlugin}s.
- */
-public class StandardGraphBuilderPlugins {
-    public static void registerInvocationPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) {
-        Registration r = new Registration(plugins, metaAccess, Object.class);
-        r.register1("<init>", Receiver.class, new InvocationPlugin() {
-            public boolean apply(GraphBuilderContext builder, ValueNode object) {
-                if (RegisterFinalizerNode.mayHaveFinalizer(object, builder.getAssumptions())) {
-                    builder.append(new RegisterFinalizerNode(object));
-                }
-                return true;
-            }
-        });
-
-        r = new Registration(plugins, metaAccess, Math.class);
-        r.register1("abs", Float.TYPE, new InvocationPlugin() {
-            public boolean apply(GraphBuilderContext builder, ValueNode value) {
-                builder.push(Kind.Float, builder.append(new AbsNode(value)));
-                return true;
-            }
-        });
-        r.register1("abs", Double.TYPE, new InvocationPlugin() {
-            public boolean apply(GraphBuilderContext builder, ValueNode value) {
-                builder.push(Kind.Double, builder.append(new AbsNode(value)));
-                return true;
-            }
-        });
-        r.register1("sqrt", Double.TYPE, new InvocationPlugin() {
-            public boolean apply(GraphBuilderContext builder, ValueNode value) {
-                builder.push(Kind.Double, builder.append(new SqrtNode(value)));
-                return true;
-            }
-        });
-
-        for (Kind kind : Kind.values()) {
-            if (kind.isPrimitive() && kind != Kind.Void) {
-                new BoxPlugin(kind).register(metaAccess, plugins);
-                new UnboxPlugin(kind).register(metaAccess, plugins);
-            }
-        }
-
-        GraalDirectivePlugins.registerInvocationPlugins(metaAccess, plugins);
-    }
-
-    static class BoxPlugin implements InvocationPlugin {
-
-        private final Kind kind;
-
-        BoxPlugin(Kind kind) {
-            this.kind = kind;
-        }
-
-        public boolean apply(GraphBuilderContext builder, ValueNode value) {
-            ResolvedJavaType resultType = builder.getMetaAccess().lookupJavaType(kind.toBoxedJavaClass());
-            builder.push(Kind.Object, builder.append(new BoxNode(value, resultType, kind)));
-            return true;
-        }
-
-        void register(MetaAccessProvider metaAccess, InvocationPlugins plugins) {
-            ResolvedJavaMethod method = Registration.resolve(metaAccess, kind.toBoxedJavaClass(), "valueOf", kind.toJavaClass());
-            plugins.register(method, this);
-        }
-    }
-
-    static class UnboxPlugin implements InvocationPlugin {
-
-        private final Kind kind;
-
-        UnboxPlugin(Kind kind) {
-            this.kind = kind;
-        }
-
-        public boolean apply(GraphBuilderContext builder, ValueNode value) {
-            ValueNode valueNode = UnboxNode.create(builder.getMetaAccess(), builder.getConstantReflection(), nullCheckedValue(builder, value), kind);
-            builder.push(kind.getStackKind(), builder.append(valueNode));
-            return true;
-        }
-
-        void register(MetaAccessProvider metaAccess, InvocationPlugins plugins) {
-            String name = kind.toJavaClass().getSimpleName() + "Value";
-            ResolvedJavaMethod method = Registration.resolve(metaAccess, kind.toBoxedJavaClass(), name);
-            plugins.register(method, this);
-        }
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/StandardGraphBuilderPlugins.java	Thu Feb 19 11:22:44 2015 +0100
@@ -0,0 +1,198 @@
+/*
+ * 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.api.code.MemoryBarriers.*;
+import static com.oracle.graal.java.GraphBuilderContext.*;
+import static java.lang.Character.*;
+import sun.misc.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.java.*;
+import com.oracle.graal.java.GraphBuilderPlugin.InvocationPlugin;
+import com.oracle.graal.java.InvocationPlugins.Registration;
+import com.oracle.graal.java.InvocationPlugins.Registration.Receiver;
+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.replacements.nodes.*;
+
+/**
+ * Provides non-runtime specific {@link InvocationPlugin}s.
+ */
+public class StandardGraphBuilderPlugins {
+    public static void registerInvocationPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) {
+        Registration r = new Registration(plugins, metaAccess, Object.class);
+        r.register1("<init>", Receiver.class, new InvocationPlugin() {
+            public boolean apply(GraphBuilderContext builder, ValueNode object) {
+                if (RegisterFinalizerNode.mayHaveFinalizer(object, builder.getAssumptions())) {
+                    builder.append(new RegisterFinalizerNode(object));
+                }
+                return true;
+            }
+        });
+
+        r = new Registration(plugins, metaAccess, Math.class);
+        r.register1("abs", Float.TYPE, new InvocationPlugin() {
+            public boolean apply(GraphBuilderContext builder, ValueNode value) {
+                builder.push(Kind.Float, builder.append(new AbsNode(value)));
+                return true;
+            }
+        });
+        r.register1("abs", Double.TYPE, new InvocationPlugin() {
+            public boolean apply(GraphBuilderContext builder, ValueNode value) {
+                builder.push(Kind.Double, builder.append(new AbsNode(value)));
+                return true;
+            }
+        });
+        r.register1("sqrt", Double.TYPE, new InvocationPlugin() {
+            public boolean apply(GraphBuilderContext builder, ValueNode value) {
+                builder.push(Kind.Double, builder.append(new SqrtNode(value)));
+                return true;
+            }
+        });
+
+        for (Kind kind : Kind.values()) {
+            if (kind.isPrimitive() && kind != Kind.Void) {
+                new BoxPlugin(kind).register(metaAccess, plugins);
+                new UnboxPlugin(kind).register(metaAccess, plugins);
+            }
+        }
+
+        r = new Registration(plugins, metaAccess, Unsafe.class);
+        for (Kind kind : Kind.values()) {
+            if ((kind.isPrimitive() && kind != Kind.Void) || kind == Kind.Object) {
+                String kindName = kind.getJavaName();
+                kindName = toUpperCase(kindName.charAt(0)) + kindName.substring(1);
+                String getName = "get" + kindName;
+                String putName = "put" + kindName;
+                r.register3(getName, Receiver.class, Object.class, long.class, new UnsafeGetPlugin(kind, false));
+                r.register4(putName, Receiver.class, Object.class, long.class, kind == Kind.Object ? Object.class : kind.toJavaClass(), new UnsafePutPlugin(kind, false));
+                r.register3(getName + "Volatile", Receiver.class, Object.class, long.class, new UnsafeGetPlugin(kind, true));
+                r.register4(putName + "Volatile", Receiver.class, Object.class, long.class, kind == Kind.Object ? Object.class : kind.toJavaClass(), new UnsafePutPlugin(kind, true));
+                if (kind != Kind.Boolean && kind != Kind.Object) {
+                    r.register2(getName, Receiver.class, long.class, new UnsafeGetPlugin(kind, false));
+                    r.register3(putName, Receiver.class, long.class, kind.toJavaClass(), new UnsafePutPlugin(kind, false));
+                }
+            }
+        }
+        GraalDirectivePlugins.registerInvocationPlugins(metaAccess, plugins);
+    }
+
+    static class BoxPlugin implements InvocationPlugin {
+
+        private final Kind kind;
+
+        BoxPlugin(Kind kind) {
+            this.kind = kind;
+        }
+
+        public boolean apply(GraphBuilderContext builder, ValueNode value) {
+            ResolvedJavaType resultType = builder.getMetaAccess().lookupJavaType(kind.toBoxedJavaClass());
+            builder.push(Kind.Object, builder.append(new BoxNode(value, resultType, kind)));
+            return true;
+        }
+
+        void register(MetaAccessProvider metaAccess, InvocationPlugins plugins) {
+            ResolvedJavaMethod method = Registration.resolve(metaAccess, kind.toBoxedJavaClass(), "valueOf", kind.toJavaClass());
+            plugins.register(method, this);
+        }
+    }
+
+    static class UnboxPlugin implements InvocationPlugin {
+
+        private final Kind kind;
+
+        UnboxPlugin(Kind kind) {
+            this.kind = kind;
+        }
+
+        public boolean apply(GraphBuilderContext builder, ValueNode value) {
+            ValueNode valueNode = UnboxNode.create(builder.getMetaAccess(), builder.getConstantReflection(), nullCheckedValue(builder, value), kind);
+            builder.push(kind.getStackKind(), builder.append(valueNode));
+            return true;
+        }
+
+        void register(MetaAccessProvider metaAccess, InvocationPlugins plugins) {
+            String name = kind.toJavaClass().getSimpleName() + "Value";
+            ResolvedJavaMethod method = Registration.resolve(metaAccess, kind.toBoxedJavaClass(), name);
+            plugins.register(method, this);
+        }
+    }
+
+    static class UnsafeGetPlugin implements InvocationPlugin {
+
+        private final Kind returnKind;
+        private final boolean isVolatile;
+
+        public UnsafeGetPlugin(Kind returnKind, boolean isVolatile) {
+            this.returnKind = returnKind;
+            this.isVolatile = isVolatile;
+        }
+
+        public boolean apply(GraphBuilderContext builder, ValueNode ignoredUnsafe, ValueNode address) {
+            builder.push(returnKind.getStackKind(), builder.append(new DirectReadNode(address, returnKind)));
+            return true;
+        }
+
+        public boolean apply(GraphBuilderContext builder, ValueNode ignoredUnsafe, ValueNode object, ValueNode offset) {
+            if (isVolatile) {
+                builder.append(new MembarNode(JMM_PRE_VOLATILE_READ));
+            }
+            builder.push(returnKind.getStackKind(), builder.append(new UnsafeLoadNode(object, offset, returnKind, LocationIdentity.ANY_LOCATION)));
+            if (isVolatile) {
+                builder.append(new MembarNode(JMM_POST_VOLATILE_READ));
+            }
+            return true;
+        }
+    }
+
+    static class UnsafePutPlugin implements InvocationPlugin {
+
+        private final Kind kind;
+        private final boolean isVolatile;
+
+        public UnsafePutPlugin(Kind kind, boolean isVolatile) {
+            this.kind = kind;
+            this.isVolatile = isVolatile;
+        }
+
+        public boolean apply(GraphBuilderContext builder, ValueNode ignoredUnsafe, ValueNode address, ValueNode value) {
+            builder.append(new DirectStoreNode(address, value, kind));
+            return true;
+        }
+
+        public boolean apply(GraphBuilderContext builder, ValueNode ignoredUnsafe, ValueNode object, ValueNode offset, ValueNode value) {
+            if (isVolatile) {
+                builder.append(new MembarNode(JMM_PRE_VOLATILE_WRITE));
+            }
+            builder.append(new UnsafeStoreNode(object, offset, value, kind, LocationIdentity.ANY_LOCATION));
+            if (isVolatile) {
+                builder.append(new MembarNode(JMM_PRE_VOLATILE_WRITE));
+            }
+            return true;
+        }
+
+    }
+}