# HG changeset patch # User Andreas Woess # Date 1392392753 -3600 # Node ID fca29edf5667642efc1d256dbc4c859d5899c57a # Parent 1541afe9cf15b5e6ce91b25b923ef812c7a0e191 experimental CompilerDirectives.unsafeGetFinal* diff -r 1541afe9cf15 -r fca29edf5667 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadFinalNode.java --- /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 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); + } +} diff -r 1541afe9cf15 -r fca29edf5667 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/CompilerDirectivesSubstitutions.java --- 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); } diff -r 1541afe9cf15 -r fca29edf5667 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerDirectives.java --- 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)