# HG changeset patch # User Thomas Wuerthinger # Date 1381106408 -7200 # Node ID e04a86167368338d7da44a2462137a5286da4ff1 # Parent fe71a5ed24c2a0e9394d8c0168c52ec5269cfbbe Add support for unsafe access in early read elimination. diff -r fe71a5ed24c2 -r e04a86167368 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ObjectLocationIdentity.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ObjectLocationIdentity.java Mon Oct 07 01:25:49 2013 +0200 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ObjectLocationIdentity.java Mon Oct 07 02:40:08 2013 +0200 @@ -22,31 +22,31 @@ */ package com.oracle.graal.api.meta; +import java.util.*; + /** * A {@link LocationIdentity} warpping an object. */ -public class ObjectLocationIdentity implements LocationIdentity { +public final class ObjectLocationIdentity implements LocationIdentity { + + private static IdentityHashMap map = new IdentityHashMap<>(); private Object object; - public ObjectLocationIdentity(Object object) { - this.object = object; + public static LocationIdentity create(Object object) { + synchronized (map) { + if (map.containsKey(object)) { + return map.get(object); + } else { + ObjectLocationIdentity locationIdentity = new ObjectLocationIdentity(object); + map.put(object, locationIdentity); + return locationIdentity; + } + } } - @Override - public boolean equals(Object other) { - if (other == this) { - return true; - } else if (other instanceof ObjectLocationIdentity) { - ObjectLocationIdentity objectLocationIdentity = (ObjectLocationIdentity) other; - return objectLocationIdentity.object == object; - } - return false; - } - - @Override - public int hashCode() { - return object.hashCode(); + private ObjectLocationIdentity(Object object) { + this.object = object; } @Override diff -r fe71a5ed24c2 -r e04a86167368 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaField.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaField.java Mon Oct 07 01:25:49 2013 +0200 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaField.java Mon Oct 07 02:40:08 2013 +0200 @@ -29,7 +29,7 @@ * Represents a reference to a resolved Java field. Fields, like methods and types, are resolved * through {@link ConstantPool constant pools}. */ -public interface ResolvedJavaField extends JavaField { +public interface ResolvedJavaField extends JavaField, LocationIdentity { /** * Returns the Java language modifiers for this field, as an integer. The {@link Modifier} class diff -r fe71a5ed24c2 -r e04a86167368 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Mon Oct 07 01:25:49 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Mon Oct 07 02:40:08 2013 +0200 @@ -43,18 +43,6 @@ super(object, location, stamp, guard, barrierType, compressible); } - public ReadNode(ValueNode object, int displacement, LocationIdentity locationIdentity, Kind kind) { - super(object, ConstantLocationNode.create(locationIdentity, kind, displacement, object.graph()), StampFactory.forKind(kind)); - } - - private ReadNode(ValueNode object, ValueNode location, ValueNode guard) { - /* - * Used by node intrinsics. Since the initial value for location is a parameter, i.e., a - * LocalNode, the constructor cannot use the declared type LocationNode. - */ - super(object, location, StampFactory.forNodeIntrinsic(), (GuardingNode) guard, BarrierType.NONE, false); - } - @Override public void generate(LIRGeneratorTool gen) { Value address = location().generateAddress(gen, gen.operand(object())); diff -r fe71a5ed24c2 -r e04a86167368 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java Mon Oct 07 01:25:49 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java Mon Oct 07 02:40:08 2013 +0200 @@ -173,6 +173,8 @@ // Convert deopt to guards. new ConvertDeoptimizeToGuardPhase().apply(graph); + new EarlyReadEliminationPhase(canonicalizerPhase).apply(graph, context); + if (!inliningProgress) { break; } diff -r fe71a5ed24c2 -r e04a86167368 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadMacroNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadMacroNode.java Mon Oct 07 02:40:08 2013 +0200 @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2013, 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.extended.*; +import com.oracle.graal.truffle.nodes.asserts.*; +import com.oracle.truffle.api.*; + +/** + * Macro node for method {@link CompilerDirectives#unsafeCast(Object, Class, boolean)}. + */ +public class CustomizedUnsafeLoadMacroNode extends NeverPartOfCompilationNode implements Canonicalizable { + + 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; + + public CustomizedUnsafeLoadMacroNode(Invoke invoke) { + super(invoke, "The location argument could not be resolved to a constant."); + assert arguments.size() == ARGUMENT_COUNT; + } + + @SuppressWarnings("unused") + @Override + public Node canonical(CanonicalizerTool tool) { + ValueNode locationArgument = arguments.get(LOCATION_ARGUMENT_INDEX); + if (locationArgument.isConstant()) { + ValueNode objectArgument = arguments.get(OBJECT_ARGUMENT_INDEX); + ValueNode offsetArgument = arguments.get(OFFSET_ARGUMENT_INDEX); + ValueNode conditionArgument = arguments.get(CONDITION_ARGUMENT_INDEX); + Object locationIdentityObject = locationArgument.asConstant().asObject(); + LocationIdentity locationIdentity; + if (locationIdentityObject == null) { + locationIdentity = LocationIdentity.ANY_LOCATION; + } else { + locationIdentity = ObjectLocationIdentity.create(locationIdentityObject); + } + return graph().add(new UnsafeLoadNode(objectArgument, offsetArgument, this.stamp().kind(), locationIdentity)); + } + return this; + } +} diff -r fe71a5ed24c2 -r e04a86167368 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadNode.java Mon Oct 07 01:25:49 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2012, 2013, 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.extended.*; -import com.oracle.graal.nodes.spi.*; - -public final class CustomizedUnsafeLoadNode extends UnsafeLoadNode { - - @Input private ValueNode condition; - @Input private ValueNode customLocationIdentity; - - public CustomizedUnsafeLoadNode(ValueNode object, ValueNode offset, Kind accessKind, ValueNode condition, ValueNode customLocationIdentity) { - super(object, offset, accessKind); - this.condition = condition; - this.customLocationIdentity = customLocationIdentity; - } - - public ValueNode getCondition() { - return condition; - } - - public ValueNode getCustomLocationIdentity() { - return customLocationIdentity; - } - - @Override - public Node canonical(CanonicalizerTool tool) { - return this; - } - - @Override - public void virtualize(VirtualizerTool tool) { - super.virtualize(tool); - } - - @SuppressWarnings("unused") - @NodeIntrinsic - public static T load(Object object, long offset, @ConstantNodeParameter Kind kind, boolean condition, Object locationIdentity) { - return UnsafeLoadNode.load(object, offset, kind); - } -} diff -r fe71a5ed24c2 -r e04a86167368 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeStoreMacroNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeStoreMacroNode.java Mon Oct 07 02:40:08 2013 +0200 @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2013, 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.extended.*; +import com.oracle.graal.truffle.nodes.asserts.*; +import com.oracle.truffle.api.*; + +/** + * Macro node for method {@link CompilerDirectives#unsafeCast(Object, Class, boolean)}. + */ +public class CustomizedUnsafeStoreMacroNode extends NeverPartOfCompilationNode implements Canonicalizable { + + 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 VALUE_ARGUMENT_INDEX = 2; + private static final int LOCATION_ARGUMENT_INDEX = 3; + + public CustomizedUnsafeStoreMacroNode(Invoke invoke) { + super(invoke, "The location argument could not be resolved to a constant."); + assert arguments.size() == ARGUMENT_COUNT; + } + + @Override + public Node canonical(CanonicalizerTool tool) { + ValueNode locationArgument = arguments.get(LOCATION_ARGUMENT_INDEX); + if (locationArgument.isConstant()) { + ValueNode objectArgument = arguments.get(OBJECT_ARGUMENT_INDEX); + ValueNode offsetArgument = arguments.get(OFFSET_ARGUMENT_INDEX); + ValueNode valueArgument = arguments.get(VALUE_ARGUMENT_INDEX); + Object locationIdentityObject = locationArgument.asConstant().asObject(); + LocationIdentity locationIdentity; + if (locationIdentityObject == null) { + locationIdentity = LocationIdentity.ANY_LOCATION; + } else { + locationIdentity = ObjectLocationIdentity.create(locationIdentityObject); + } + return graph().add(new UnsafeStoreNode(objectArgument, offsetArgument, valueArgument, valueArgument.stamp().kind(), locationIdentity)); + } + return this; + } +} diff -r fe71a5ed24c2 -r e04a86167368 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeStoreNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeStoreNode.java Mon Oct 07 01:25:49 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2012, 2013, 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.extended.*; -import com.oracle.graal.nodes.spi.*; - -public final class CustomizedUnsafeStoreNode extends UnsafeStoreNode { - - @Input private ValueNode customLocationIdentity; - - public CustomizedUnsafeStoreNode(ValueNode object, ValueNode offset, ValueNode value, Kind accessKind, ValueNode customLocationIdentity) { - super(object, offset, value, accessKind); - this.customLocationIdentity = customLocationIdentity; - } - - public ValueNode getCustomLocationIdentity() { - return customLocationIdentity; - } - - @Override - public Node canonical(CanonicalizerTool tool) { - return this; - } - - @Override - public void virtualize(VirtualizerTool tool) { - super.virtualize(tool); - } - - @SuppressWarnings("unused") - @NodeIntrinsic - public static void store(Object object, long offset, Object value, @ConstantNodeParameter Kind kind, Object customLocationIdentity) { - UnsafeStoreNode.store(object, offset, value, kind); - } - - @SuppressWarnings("unused") - @NodeIntrinsic - public static void store(Object object, long offset, boolean value, @ConstantNodeParameter Kind kind, Object customLocationIdentity) { - UnsafeStoreNode.store(object, offset, value, kind); - } - - @SuppressWarnings("unused") - @NodeIntrinsic - public static void store(Object object, long offset, byte value, @ConstantNodeParameter Kind kind, Object customLocationIdentity) { - UnsafeStoreNode.store(object, offset, value, kind); - } - - @SuppressWarnings("unused") - @NodeIntrinsic - public static void store(Object object, long offset, char value, @ConstantNodeParameter Kind kind, Object customLocationIdentity) { - UnsafeStoreNode.store(object, offset, value, kind); - } - - @SuppressWarnings("unused") - @NodeIntrinsic - public static void store(Object object, long offset, double value, @ConstantNodeParameter Kind kind, Object customLocationIdentity) { - UnsafeStoreNode.store(object, offset, value, kind); - } - - @SuppressWarnings("unused") - @NodeIntrinsic - public static void store(Object object, long offset, float value, @ConstantNodeParameter Kind kind, Object customLocationIdentity) { - UnsafeStoreNode.store(object, offset, value, kind); - } - - @SuppressWarnings("unused") - @NodeIntrinsic - public static void store(Object object, long offset, int value, @ConstantNodeParameter Kind kind, Object customLocationIdentity) { - UnsafeStoreNode.store(object, offset, value, kind); - } - - @SuppressWarnings("unused") - @NodeIntrinsic - public static void store(Object object, long offset, long value, @ConstantNodeParameter Kind kind, Object customLocationIdentity) { - UnsafeStoreNode.store(object, offset, value, kind); - } - - @SuppressWarnings("unused") - @NodeIntrinsic - public static void store(Object object, long offset, short value, @ConstantNodeParameter Kind kind, Object customLocationIdentity) { - UnsafeStoreNode.store(object, offset, value, kind); - } -} diff -r fe71a5ed24c2 -r e04a86167368 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 Mon Oct 07 01:25:49 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/CompilerDirectivesSubstitutions.java Mon Oct 07 02:40:08 2013 +0200 @@ -66,78 +66,48 @@ @MacroSubstitution(macro = UnsafeTypeCastMacroNode.class, isStatic = true) public static native Object unsafeCast(Object value, Class clazz, boolean condition); - @MethodSubstitution - public static boolean unsafeGetBoolean(Object receiver, long offset, boolean condition, Object locationIdentity) { - return CustomizedUnsafeLoadNode.load(receiver, offset, Kind.Boolean, condition, locationIdentity); - } + @MacroSubstitution(macro = CustomizedUnsafeLoadMacroNode.class, isStatic = true) + public static native boolean unsafeGetBoolean(Object receiver, long offset, boolean condition, Object locationIdentity); - @MethodSubstitution - public static byte unsafeGetByte(Object receiver, long offset, boolean condition, Object locationIdentity) { - return CustomizedUnsafeLoadNode.load(receiver, offset, Kind.Byte, condition, locationIdentity); - } + @MacroSubstitution(macro = CustomizedUnsafeLoadMacroNode.class, isStatic = true) + public static native byte unsafeGetByte(Object receiver, long offset, boolean condition, Object locationIdentity); - @MethodSubstitution - public static short unsafeGetShort(Object receiver, long offset, boolean condition, Object locationIdentity) { - return CustomizedUnsafeLoadNode.load(receiver, offset, Kind.Short, condition, locationIdentity); - } + @MacroSubstitution(macro = CustomizedUnsafeLoadMacroNode.class, isStatic = true) + public static native short unsafeGetShort(Object receiver, long offset, boolean condition, Object locationIdentity); - @MethodSubstitution - public static int unsafeGetInt(Object receiver, long offset, boolean condition, Object locationIdentity) { - return CustomizedUnsafeLoadNode.load(receiver, offset, Kind.Int, condition, locationIdentity); - } + @MacroSubstitution(macro = CustomizedUnsafeLoadMacroNode.class, isStatic = true) + public static native int unsafeGetInt(Object receiver, long offset, boolean condition, Object locationIdentity); - @MethodSubstitution - public static float unsafeGetFloat(Object receiver, long offset, boolean condition, Object locationIdentity) { - return CustomizedUnsafeLoadNode.load(receiver, offset, Kind.Float, condition, locationIdentity); - } + @MacroSubstitution(macro = CustomizedUnsafeLoadMacroNode.class, isStatic = true) + public static native float unsafeGetFloat(Object receiver, long offset, boolean condition, Object locationIdentity); - @MethodSubstitution - public static double unsafeGetDouble(Object receiver, long offset, boolean condition, Object locationIdentity) { - return CustomizedUnsafeLoadNode.load(receiver, offset, Kind.Double, condition, locationIdentity); - } + @MacroSubstitution(macro = CustomizedUnsafeLoadMacroNode.class, isStatic = true) + public static native double unsafeGetDouble(Object receiver, long offset, boolean condition, Object locationIdentity); - @MethodSubstitution - public static Object unsafeGetObject(Object receiver, long offset, boolean condition, Object locationIdentity) { - return CustomizedUnsafeLoadNode.load(receiver, offset, Kind.Object, condition, locationIdentity); - } + @MacroSubstitution(macro = CustomizedUnsafeLoadMacroNode.class, isStatic = true) + public static native Object unsafeGetObject(Object receiver, long offset, boolean condition, Object locationIdentity); - @MethodSubstitution - public static void unsafePutBoolean(Object receiver, long offset, boolean value, Object locationIdentity) { - CustomizedUnsafeStoreNode.store(receiver, offset, value, Kind.Boolean, locationIdentity); - } + @MacroSubstitution(macro = CustomizedUnsafeStoreMacroNode.class, isStatic = true) + public static native void unsafePutBoolean(Object receiver, long offset, boolean value, Object locationIdentity); - @MethodSubstitution - public static void unsafePutByte(Object receiver, long offset, byte value, Object locationIdentity) { - CustomizedUnsafeStoreNode.store(receiver, offset, value, Kind.Byte, locationIdentity); - } + @MacroSubstitution(macro = CustomizedUnsafeStoreMacroNode.class, isStatic = true) + public static native void unsafePutByte(Object receiver, long offset, byte value, Object locationIdentity); - @MethodSubstitution - public static void unsafePutShort(Object receiver, long offset, short value, Object locationIdentity) { - CustomizedUnsafeStoreNode.store(receiver, offset, value, Kind.Short, locationIdentity); - } + @MacroSubstitution(macro = CustomizedUnsafeStoreMacroNode.class, isStatic = true) + public static native void unsafePutShort(Object receiver, long offset, short value, Object locationIdentity); - @MethodSubstitution - public static void unsafePutInt(Object receiver, long offset, int value, Object locationIdentity) { - CustomizedUnsafeStoreNode.store(receiver, offset, value, Kind.Int, locationIdentity); - } + @MacroSubstitution(macro = CustomizedUnsafeStoreMacroNode.class, isStatic = true) + public static native void unsafePutInt(Object receiver, long offset, int value, Object locationIdentity); - @MethodSubstitution - public static void unsafePutLong(Object receiver, long offset, long value, Object locationIdentity) { - CustomizedUnsafeStoreNode.store(receiver, offset, value, Kind.Long, locationIdentity); - } + @MacroSubstitution(macro = CustomizedUnsafeStoreMacroNode.class, isStatic = true) + public static native void unsafePutLong(Object receiver, long offset, long value, Object locationIdentity); - @MethodSubstitution - public static void unsafePutFloat(Object receiver, long offset, float value, Object locationIdentity) { - CustomizedUnsafeStoreNode.store(receiver, offset, value, Kind.Float, locationIdentity); - } + @MacroSubstitution(macro = CustomizedUnsafeStoreMacroNode.class, isStatic = true) + public static native void unsafePutFloat(Object receiver, long offset, float value, Object locationIdentity); - @MethodSubstitution - public static void unsafePutDouble(Object receiver, long offset, double value, Object locationIdentity) { - CustomizedUnsafeStoreNode.store(receiver, offset, value, Kind.Double, locationIdentity); - } + @MacroSubstitution(macro = CustomizedUnsafeStoreMacroNode.class, isStatic = true) + public static native void unsafePutDouble(Object receiver, long offset, double value, Object locationIdentity); - @MethodSubstitution - public static void unsafePutObject(Object receiver, long offset, Object value, Object locationIdentity) { - CustomizedUnsafeStoreNode.store(receiver, offset, value, Kind.Object, locationIdentity); - } + @MacroSubstitution(macro = CustomizedUnsafeStoreMacroNode.class, isStatic = true) + public static native void unsafePutObject(Object receiver, long offset, Object value, Object locationIdentity); } diff -r fe71a5ed24c2 -r e04a86167368 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationBlockState.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationBlockState.java Mon Oct 07 01:25:49 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationBlockState.java Mon Oct 07 02:40:08 2013 +0200 @@ -64,14 +64,14 @@ public abstract boolean conflicts(LocationIdentity other); } - static class LoadCacheEntry extends CacheEntry { + static class LoadCacheEntry extends CacheEntry { - public LoadCacheEntry(ValueNode object, ResolvedJavaField identity) { + public LoadCacheEntry(ValueNode object, LocationIdentity identity) { super(object, identity); } @Override - public CacheEntry duplicateWithObject(ValueNode newObject) { + public CacheEntry duplicateWithObject(ValueNode newObject) { return new LoadCacheEntry(newObject, identity); } diff -r fe71a5ed24c2 -r e04a86167368 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationClosure.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationClosure.java Mon Oct 07 01:25:49 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationClosure.java Mon Oct 07 02:40:08 2013 +0200 @@ -81,7 +81,7 @@ effects.deleteFixedNode(store); deleted = true; } - state.killReadCache((LocationIdentity) store.field()); + state.killReadCache(store.field()); state.addCacheEntry(identifier, value); } else { processIdentity(state, ANY_LOCATION); @@ -100,6 +100,20 @@ state.addCacheEntry(identifier, read); } } + } else if (node instanceof UnsafeLoadNode) { + UnsafeLoadNode load = (UnsafeLoadNode) node; + if (load.offset().isConstant() && load.getLocationIdentity() != LocationIdentity.ANY_LOCATION) { + ValueNode object = GraphUtil.unproxify(load.object()); + LoadCacheEntry identifier = new LoadCacheEntry(object, load.getLocationIdentity()); + ValueNode cachedValue = state.getCacheEntry(identifier); + if (cachedValue != null) { + effects.replaceAtUsages(load, cachedValue); + addScalarAlias(load, cachedValue); + deleted = true; + } else { + state.addCacheEntry(identifier, load); + } + } } else if (node instanceof WriteNode) { WriteNode write = (WriteNode) node; if (write.location() instanceof ConstantLocationNode) { @@ -117,6 +131,23 @@ } else { processIdentity(state, write.location().getLocationIdentity()); } + } else if (node instanceof UnsafeStoreNode) { + UnsafeStoreNode write = (UnsafeStoreNode) node; + if (write.offset().isConstant() && write.getLocationIdentity() != LocationIdentity.ANY_LOCATION) { + ValueNode object = GraphUtil.unproxify(write.object()); + LoadCacheEntry identifier = new LoadCacheEntry(object, write.getLocationIdentity()); + ValueNode cachedValue = state.getCacheEntry(identifier); + + ValueNode value = getScalarAlias(write.value()); + if (GraphUtil.unproxify(value) == GraphUtil.unproxify(cachedValue)) { + effects.deleteFixedNode(write); + deleted = true; + } + processIdentity(state, write.getLocationIdentity()); + state.addCacheEntry(identifier, value); + } else { + processIdentity(state, write.getLocationIdentity()); + } } else if (node instanceof MemoryCheckpoint.Single) { LocationIdentity identity = ((MemoryCheckpoint.Single) node).getLocationIdentity(); processIdentity(state, identity);