# HG changeset patch # User Lukas Stadler # Date 1312383242 -7200 # Node ID 561f5b2940b1a2402f614657e75643acd528d484 # Parent ccf5e0d9eb61751e64439a7ad657d9e39b73dfa9# Parent 0da7f6b247c987cf3fde1e4e691a9d2edd6e97b2 merge diff -r ccf5e0d9eb61 -r 561f5b2940b1 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LocationNode.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LocationNode.java Wed Aug 03 16:28:05 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LocationNode.java Wed Aug 03 16:54:02 2011 +0200 @@ -43,6 +43,7 @@ index = x; } + public static final Object UNSAFE_ACCESS_LOCATION = new Object(); public static final Object FINAL_LOCATION = new Object(); public static Object getArrayLocation(CiKind elementKind) { @@ -50,6 +51,7 @@ } private int displacement; + private boolean indexScalingEnabled = true; private CiKind valueKind; private Object locationIdentity; @@ -57,6 +59,20 @@ return displacement; } + /** + * @return whether scaling of the index by the value kind's size is enabled (the default) or disabled. + */ + public boolean indexScalingEnabled() { + return indexScalingEnabled; + } + + /** + * Enables or disables scaling of the index by the value kind's size. Has no effect if the index input is not used. + */ + public void setIndexScalingEnabled(boolean enable) { + this.indexScalingEnabled = enable; + } + public static LocationNode create(Object identity, CiKind kind, int displacement, Graph graph) { LocationNode result = new LocationNode(identity, kind, displacement, graph); return graph.ideal(result); @@ -96,7 +112,9 @@ Scale indexScale = Scale.Times1; if (this.index() != null) { indexValue = lirGenerator.load(this.index()); + if (indexScalingEnabled) { indexScale = Scale.fromInt(valueKind.sizeInBytes(lirGenerator.target().wordSize)); + } } return new CiAddress(valueKind, lirGenerator.load(object), indexValue, indexScale, displacement); } diff -r ccf5e0d9eb61 -r 561f5b2940b1 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java Wed Aug 03 16:28:05 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java Wed Aug 03 16:54:02 2011 +0200 @@ -555,7 +555,10 @@ } if (pred instanceof Placeholder) { - pred.replaceAndDelete(((Placeholder) pred).next()); + System.out.println("preds: " + ((Placeholder) pred).next().predecessor()); + FixedNode next = ((Placeholder) pred).next(); + ((Placeholder) pred).setNext(null); + pred.replaceAndDelete(next); } if (returnNode != null) { diff -r ccf5e0d9eb61 -r 561f5b2940b1 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotRuntime.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotRuntime.java Wed Aug 03 16:28:05 2011 +0200 +++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotRuntime.java Wed Aug 03 16:54:02 2011 +0200 @@ -344,6 +344,35 @@ } storeIndexed.replaceAtPredecessors(anchor); storeIndexed.delete(); + } else if (n instanceof UnsafeLoad) { + UnsafeLoad load = (UnsafeLoad) n; + Graph graph = load.graph(); + assert load.kind != CiKind.Illegal; + LocationNode location = LocationNode.create(LocationNode.UNSAFE_ACCESS_LOCATION, load.kind, 0, graph); + location.setIndex(load.offset()); + location.setIndexScalingEnabled(false); + ReadNode memoryRead = new ReadNode(load.kind.stackKind(), load.object(), location, graph); + memoryRead.setGuard((GuardNode) tool.createGuard(new IsNonNull(load.object(), graph))); + FixedNode next = load.next(); + load.setNext(null); + memoryRead.setNext(next); + load.replaceAndDelete(memoryRead); + } else if (n instanceof UnsafeStore) { + UnsafeStore store = (UnsafeStore) n; + Graph graph = store.graph(); + assert store.kind != CiKind.Illegal; + LocationNode location = LocationNode.create(LocationNode.UNSAFE_ACCESS_LOCATION, store.kind, 0, graph); + location.setIndex(store.offset()); + location.setIndexScalingEnabled(false); + WriteNode write = new WriteNode(store.kind.stackKind(), store.object(), store.value(), location, graph); + FieldWriteBarrier barrier = new FieldWriteBarrier(store.object(), graph); + FixedNode next = store.next(); + store.setNext(null); + barrier.setNext(next); + write.setNext(barrier); + write.setStateAfter(store.stateAfter()); + store.replaceAtPredecessors(write); + store.delete(); } } @@ -521,6 +550,29 @@ graph.setReturn(ret); intrinsicGraphs.put(method, graph); } + } else if (holderName.equals("Lsun/misc/Unsafe;")) { + if (fullName.equals("getObject(Ljava/lang/Object;J)Ljava/lang/Object;")) { + CompilerGraph graph = new CompilerGraph(this); + Local object = new Local(CiKind.Object, 1, graph); + Local offset = new Local(CiKind.Long, 2, graph); + UnsafeLoad load = new UnsafeLoad(object, offset, CiKind.Object, graph); + Return ret = new Return(load, graph); + load.setNext(ret); + graph.start().setNext(load); + graph.setReturn(ret); + intrinsicGraphs.put(method, graph); + } else if (fullName.equals("putObject(Ljava/lang/Object;JLjava/lang/Object;)V")) { + CompilerGraph graph = new CompilerGraph(this); + Local object = new Local(CiKind.Object, 1, graph); + Local offset = new Local(CiKind.Long, 2, graph); + Local value = new Local(CiKind.Object, 3, graph); + UnsafeStore store = new UnsafeStore(object, offset, value, CiKind.Object, graph); + Return ret = new Return(null, graph); + store.setNext(ret); + graph.start().setNext(store); + graph.setReturn(ret); + intrinsicGraphs.put(method, graph); + } } if (!intrinsicGraphs.containsKey(method)) { diff -r ccf5e0d9eb61 -r 561f5b2940b1 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/nodes/UnsafeLoad.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/nodes/UnsafeLoad.java Wed Aug 03 16:54:02 2011 +0200 @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2011, 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.max.graal.runtime.nodes; + +import com.oracle.max.graal.compiler.ir.*; +import com.oracle.max.graal.compiler.phases.*; +import com.oracle.max.graal.compiler.phases.LoweringPhase.*; +import com.oracle.max.graal.graph.*; +import com.sun.cri.ci.*; + +/** + * Load of a value from a location specified as an offset relative to an object. + */ +public class UnsafeLoad extends StateSplit { + + @NodeInput + private Value object; + + @NodeInput + private Value offset; + + public Value object() { + return object; + } + + public void setObject(Value x) { + updateUsages(object, x); + object = x; + } + + public Value offset() { + return offset; + } + + public void setOffset(Value x) { + updateUsages(offset, x); + offset = x; + } + + public UnsafeLoad(Value object, Value offset, CiKind kind, Graph graph) { + super(kind, graph); + setObject(object); + setOffset(offset); + } + + @SuppressWarnings("unchecked") + @Override + public T lookup(Class clazz) { + if (clazz == LoweringOp.class) { + return (T) LoweringPhase.DELEGATE_TO_RUNTIME; + } + return super.lookup(clazz); + } + + @Override + public Node copy(Graph into) { + UnsafeLoad x = new UnsafeLoad(null, null, kind, into); + super.copyInto(x); + return x; + } + +} diff -r ccf5e0d9eb61 -r 561f5b2940b1 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/nodes/UnsafeStore.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/nodes/UnsafeStore.java Wed Aug 03 16:54:02 2011 +0200 @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2011, 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.max.graal.runtime.nodes; + +import com.oracle.max.graal.compiler.ir.*; +import com.oracle.max.graal.compiler.phases.*; +import com.oracle.max.graal.compiler.phases.LoweringPhase.*; +import com.oracle.max.graal.graph.*; +import com.sun.cri.ci.*; + +/** + * Store of a value at a location specified as an offset relative to an object. + */ +public class UnsafeStore extends StateSplit { + + @NodeInput + private Value object; + + @NodeInput + private Value offset; + + @NodeInput + private Value value; + + public Value object() { + return object; + } + + public void setObject(Value x) { + updateUsages(object, x); + object = x; + } + + public Value offset() { + return offset; + } + + public void setOffset(Value x) { + updateUsages(offset, x); + offset = x; + } + + public Value value() { + return value; + } + + public void setValue(Value x) { + updateUsages(value, x); + value = x; + } + + public UnsafeStore(Value object, Value offset, Value value, CiKind kind, Graph graph) { + super(kind, graph); + setObject(object); + setOffset(offset); + setValue(value); + } + + @SuppressWarnings("unchecked") + @Override + public T lookup(Class clazz) { + if (clazz == LoweringOp.class) { + return (T) LoweringPhase.DELEGATE_TO_RUNTIME; + } + return super.lookup(clazz); + } + + @Override + public Node copy(Graph into) { + UnsafeStore x = new UnsafeStore(null, null, null, kind, into); + super.copyInto(x); + return x; + } + +}