changeset 13956:fca29edf5667

experimental CompilerDirectives.unsafeGetFinal*
author Andreas Woess <andreas.woess@jku.at>
date Fri, 14 Feb 2014 16:45:53 +0100
parents 1541afe9cf15
children 5f077aa050c7
files graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadFinalNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/CompilerDirectivesSubstitutions.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerDirectives.java
diffstat 3 files changed, 271 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadFinalNode.java	Fri Feb 14 16:45:53 2014 +0100
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.truffle.nodes.typesystem;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.java.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.truffle.api.*;
+
+/**
+ * Macro node for method {@link CompilerDirectives#unsafeGetFinalObject} and friends.
+ */
+public class CustomizedUnsafeLoadFinalNode extends FixedWithNextNode implements Canonicalizable, Virtualizable, Lowerable {
+    private static final int ARGUMENT_COUNT = 4;
+    private static final int OBJECT_ARGUMENT_INDEX = 0;
+    private static final int OFFSET_ARGUMENT_INDEX = 1;
+    private static final int CONDITION_ARGUMENT_INDEX = 2;
+    private static final int LOCATION_ARGUMENT_INDEX = 3;
+
+    @Input private ValueNode object;
+    @Input private ValueNode offset;
+    @Input private ValueNode condition;
+    @Input private ValueNode location;
+    private final Kind accessKind;
+
+    public CustomizedUnsafeLoadFinalNode(Invoke invoke) {
+        super(invoke.asNode().stamp());
+        NodeInputList<ValueNode> arguments = invoke.callTarget().arguments();
+        assert arguments.size() == ARGUMENT_COUNT;
+        this.object = arguments.get(OBJECT_ARGUMENT_INDEX);
+        this.offset = arguments.get(OFFSET_ARGUMENT_INDEX);
+        this.condition = arguments.get(CONDITION_ARGUMENT_INDEX);
+        this.location = arguments.get(LOCATION_ARGUMENT_INDEX);
+        this.accessKind = ((MethodCallTargetNode) invoke.callTarget()).targetMethod().getSignature().getReturnKind();
+    }
+
+    @Override
+    public Node canonical(CanonicalizerTool tool) {
+        if (object.isConstant() && !object.isNullConstant() && offset.isConstant()) {
+            Constant constant = tool.getConstantReflection().readUnsafeConstant(accessKind, object.asConstant().asObject(), offset.asConstant().asLong(), accessKind == Kind.Object);
+            return ConstantNode.forConstant(constant, tool.getMetaAccess(), graph());
+        }
+        return this;
+    }
+
+    /**
+     * @see UnsafeLoadNode#virtualize(VirtualizerTool)
+     */
+    @Override
+    public void virtualize(VirtualizerTool tool) {
+        State state = tool.getObjectState(object);
+        if (state != null && state.getState() == EscapeState.Virtual) {
+            ValueNode offsetValue = tool.getReplacedValue(offset);
+            if (offsetValue.isConstant()) {
+                long constantOffset = offsetValue.asConstant().asLong();
+                int entryIndex = state.getVirtualObject().entryIndexForOffset(constantOffset);
+                if (entryIndex != -1) {
+                    ValueNode entry = state.getEntry(entryIndex);
+                    if (entry.kind() == kind() || state.getVirtualObject().entryKind(entryIndex) == accessKind) {
+                        tool.replaceWith(entry);
+                    }
+                }
+            }
+        }
+    }
+
+    @Override
+    public void lower(LoweringTool tool) {
+        CompareNode compare = CompareNode.createCompareNode(graph(), Condition.EQ, condition, ConstantNode.forBoolean(true, graph()));
+        Object locationIdentityObject = location.asConstant().asObject();
+        LocationIdentity locationIdentity;
+        if (locationIdentityObject == null) {
+            locationIdentity = LocationIdentity.ANY_LOCATION;
+        } else {
+            locationIdentity = ObjectLocationIdentity.create(locationIdentityObject);
+        }
+        UnsafeLoadNode result = graph().add(new UnsafeLoadNode(object, offset, accessKind, locationIdentity, compare));
+        graph().replaceFixedWithFixed(this, result);
+        result.lower(tool);
+    }
+}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/CompilerDirectivesSubstitutions.java	Thu Feb 13 15:01:48 2014 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/CompilerDirectivesSubstitutions.java	Fri Feb 14 16:45:53 2014 +0100
@@ -125,4 +125,25 @@
 
     @MacroSubstitution(macro = CustomizedUnsafeStoreMacroNode.class, isStatic = true)
     public static native void unsafePutObject(Object receiver, long offset, Object value, Object locationIdentity);
+
+    @MacroSubstitution(macro = CustomizedUnsafeLoadFinalNode.class, isStatic = true)
+    public static native boolean unsafeGetFinalBoolean(Object receiver, long offset, boolean condition, Object locationIdentity);
+
+    @MacroSubstitution(macro = CustomizedUnsafeLoadFinalNode.class, isStatic = true)
+    public static native byte unsafeGetFinalByte(Object receiver, long offset, boolean condition, Object locationIdentity);
+
+    @MacroSubstitution(macro = CustomizedUnsafeLoadFinalNode.class, isStatic = true)
+    public static native short unsafeGetFinalShort(Object receiver, long offset, boolean condition, Object locationIdentity);
+
+    @MacroSubstitution(macro = CustomizedUnsafeLoadFinalNode.class, isStatic = true)
+    public static native int unsafeGetFinalInt(Object receiver, long offset, boolean condition, Object locationIdentity);
+
+    @MacroSubstitution(macro = CustomizedUnsafeLoadFinalNode.class, isStatic = true)
+    public static native float unsafeGetFinalFloat(Object receiver, long offset, boolean condition, Object locationIdentity);
+
+    @MacroSubstitution(macro = CustomizedUnsafeLoadFinalNode.class, isStatic = true)
+    public static native double unsafeGetFinalDouble(Object receiver, long offset, boolean condition, Object locationIdentity);
+
+    @MacroSubstitution(macro = CustomizedUnsafeLoadFinalNode.class, isStatic = true)
+    public static native Object unsafeGetFinalObject(Object receiver, long offset, boolean condition, Object locationIdentity);
 }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerDirectives.java	Thu Feb 13 15:01:48 2014 +0100
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerDirectives.java	Fri Feb 14 16:45:53 2014 +0100
@@ -444,6 +444,150 @@
     }
 
     /**
+     * Unsafe access to a final boolean value within an object. The condition parameter gives a hint
+     * to the compiler under which circumstances this access can be moved to an earlier location in
+     * the program. The location identity gives a hint to the compiler for improved global value
+     * numbering.
+     * 
+     * @param receiver the object that is accessed
+     * @param offset the offset at which to access the object in bytes
+     * @param condition the condition that makes this access safe also at an earlier location in the
+     *            program
+     * @param locationIdentity the location identity token that can be used for improved global
+     *            value numbering or null
+     * @return the accessed value
+     */
+    public static boolean unsafeGetFinalBoolean(Object receiver, long offset, boolean condition, Object locationIdentity) {
+        return UNSAFE.getBoolean(receiver, offset);
+    }
+
+    /**
+     * Unsafe access to a final byte value within an object. The condition parameter gives a hint to
+     * the compiler under which circumstances this access can be moved to an earlier location in the
+     * program. The location identity gives a hint to the compiler for improved global value
+     * numbering.
+     * 
+     * @param receiver the object that is accessed
+     * @param offset the offset at which to access the object in bytes
+     * @param condition the condition that makes this access safe also at an earlier location in the
+     *            program
+     * @param locationIdentity the location identity token that can be used for improved global
+     *            value numbering or null
+     * @return the accessed value
+     */
+    public static byte unsafeGetFinalByte(Object receiver, long offset, boolean condition, Object locationIdentity) {
+        return UNSAFE.getByte(receiver, offset);
+    }
+
+    /**
+     * Unsafe access to a final short value within an object. The condition parameter gives a hint
+     * to the compiler under which circumstances this access can be moved to an earlier location in
+     * the program. The location identity gives a hint to the compiler for improved global value
+     * numbering.
+     * 
+     * @param receiver the object that is accessed
+     * @param offset the offset at which to access the object in bytes
+     * @param condition the condition that makes this access safe also at an earlier location in the
+     *            program
+     * @param locationIdentity the location identity token that can be used for improved global
+     *            value numbering or null
+     * @return the accessed value
+     */
+    public static short unsafeGetFinalShort(Object receiver, long offset, boolean condition, Object locationIdentity) {
+        return UNSAFE.getShort(receiver, offset);
+    }
+
+    /**
+     * Unsafe access to a final int value within an object. The condition parameter gives a hint to
+     * the compiler under which circumstances this access can be moved to an earlier location in the
+     * program. The location identity gives a hint to the compiler for improved global value
+     * numbering.
+     * 
+     * @param receiver the object that is accessed
+     * @param offset the offset at which to access the object in bytes
+     * @param condition the condition that makes this access safe also at an earlier location in the
+     *            program
+     * @param locationIdentity the location identity token that can be used for improved global
+     *            value numbering or null
+     * @return the accessed value
+     */
+    public static int unsafeGetFinalInt(Object receiver, long offset, boolean condition, Object locationIdentity) {
+        return UNSAFE.getInt(receiver, offset);
+    }
+
+    /**
+     * Unsafe access to a final long value within an object. The condition parameter gives a hint to
+     * the compiler under which circumstances this access can be moved to an earlier location in the
+     * program. The location identity gives a hint to the compiler for improved global value
+     * numbering.
+     * 
+     * @param receiver the object that is accessed
+     * @param offset the offset at which to access the object in bytes
+     * @param condition the condition that makes this access safe also at an earlier location in the
+     *            program
+     * @param locationIdentity the location identity token that can be used for improved global
+     *            value numbering or null
+     * @return the accessed value
+     */
+    public static long unsafeGetFinalLong(Object receiver, long offset, boolean condition, Object locationIdentity) {
+        return UNSAFE.getLong(receiver, offset);
+    }
+
+    /**
+     * Unsafe access to a final float value within an object. The condition parameter gives a hint
+     * to the compiler under which circumstances this access can be moved to an earlier location in
+     * the program. The location identity gives a hint to the compiler for improved global value
+     * numbering.
+     * 
+     * @param receiver the object that is accessed
+     * @param offset the offset at which to access the object in bytes
+     * @param condition the condition that makes this access safe also at an earlier location in the
+     *            program
+     * @param locationIdentity the location identity token that can be used for improved global
+     *            value numbering or null
+     * @return the accessed value
+     */
+    public static float unsafeGetFinalFloat(Object receiver, long offset, boolean condition, Object locationIdentity) {
+        return UNSAFE.getFloat(receiver, offset);
+    }
+
+    /**
+     * Unsafe access to a final double value within an object. The condition parameter gives a hint
+     * to the compiler under which circumstances this access can be moved to an earlier location in
+     * the program. The location identity gives a hint to the compiler for improved global value
+     * numbering.
+     * 
+     * @param receiver the object that is accessed
+     * @param offset the offset at which to access the object in bytes
+     * @param condition the condition that makes this access safe also at an earlier location in the
+     *            program
+     * @param locationIdentity the location identity token that can be used for improved global
+     *            value numbering or null
+     * @return the accessed value
+     */
+    public static double unsafeGetFinalDouble(Object receiver, long offset, boolean condition, Object locationIdentity) {
+        return UNSAFE.getDouble(receiver, offset);
+    }
+
+    /**
+     * Unsafe access to a final Object value within an object. The condition parameter gives a hint
+     * to the compiler under which circumstances this access can be moved to an earlier location in
+     * the program. The location identity gives a hint to the compiler for improved global value
+     * numbering.
+     * 
+     * @param receiver the object that is accessed
+     * @param offset the offset at which to access the object in bytes
+     * @param condition the condition that makes this access safe also at an earlier location in the
+     *            program
+     * @param locationIdentity the location identity token that can be used for improved global
+     *            value numbering or null
+     * @return the accessed value
+     */
+    public static Object unsafeGetFinalObject(Object receiver, long offset, boolean condition, Object locationIdentity) {
+        return UNSAFE.getObject(receiver, offset);
+    }
+
+    /**
      * Marks methods that are considered slowpath and should therefore not be inlined by default.
      */
     @Retention(RetentionPolicy.RUNTIME)