Mercurial > hg > graal-jvmci-8
changeset 3475:0da7f6b247c9
Intrinsify Unsafe.getObject(Object,long) and Unsafe.putObject(Object,long,Object)
author | Peter Hofer <peter.hofer@jku.at> |
---|---|
date | Wed, 03 Aug 2011 16:28:19 +0200 |
parents | b9f76db5ac53 |
children | 65981c23c1d6 561f5b2940b1 |
files | graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LocationNode.java graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotRuntime.java graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/nodes/UnsafeLoad.java graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/nodes/UnsafeStore.java |
diffstat | 4 files changed, 237 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LocationNode.java Mon Aug 01 13:56:56 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LocationNode.java Wed Aug 03 16:28:19 2011 +0200 @@ -34,6 +34,7 @@ private static final int INPUT_INDEX = 0; private static final int SUCCESSOR_COUNT = 0; + public static final Object UNSAFE_ACCESS_LOCATION = new Object(); public static final Object FINAL_LOCATION = new Object(); public static Object getArrayLocation(CiKind elementKind) { @@ -41,6 +42,7 @@ } private int displacement; + private boolean indexScalingEnabled = true; private CiKind valueKind; private Object locationIdentity; @@ -48,6 +50,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 Value index() { return (Value) inputs().get(super.inputCount() + INPUT_INDEX); } @@ -95,7 +111,9 @@ Scale indexScale = Scale.Times1; if (this.index() != null) { indexValue = lirGenerator.load(this.index()); - indexScale = Scale.fromInt(valueKind.sizeInBytes(lirGenerator.target().wordSize)); + if (indexScalingEnabled) { + indexScale = Scale.fromInt(valueKind.sizeInBytes(lirGenerator.target().wordSize)); + } } return new CiAddress(valueKind, lirGenerator.load(object), indexValue, indexScale, displacement); }
--- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotRuntime.java Mon Aug 01 13:56:56 2011 +0200 +++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotRuntime.java Wed Aug 03 16:28:19 2011 +0200 @@ -337,6 +337,31 @@ } 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))); + memoryRead.setNext(load.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); + barrier.setNext(store.next()); + write.setNext(barrier); + write.setStateAfter(store.stateAfter()); + store.replaceAtPredecessors(write); + store.delete(); } } @@ -514,6 +539,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)) {
--- /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:28:19 2011 +0200 @@ -0,0 +1,80 @@ +/* + * 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 { + + private static final int INPUT_COUNT = 2; + private static final int INPUT_OBJECT = 0; + private static final int INPUT_OFFSET = 1; + + private static final int SUCCESSOR_COUNT = 0; + + public UnsafeLoad(Value object, Value offset, CiKind kind, Graph graph) { + super(kind, INPUT_COUNT, SUCCESSOR_COUNT, graph); + setObject(object); + setOffset(offset); + } + + public Value object() { + return (Value) inputs().get(super.inputCount() + INPUT_OBJECT); + } + + public Value setObject(Value object) { + return (Value) inputs().set(super.inputCount() + INPUT_OBJECT, object); + } + + public Value offset() { + return (Value) inputs().get(super.inputCount() + INPUT_OFFSET); + } + + public Value setOffset(Value offset) { + return (Value) inputs().set(super.inputCount() + INPUT_OFFSET, offset); + } + + @SuppressWarnings("unchecked") + @Override + public <T extends Op> T lookup(Class<T> 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; + } + +}
--- /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:28:19 2011 +0200 @@ -0,0 +1,90 @@ +/* + * 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 { + + private static final int INPUT_COUNT = 3; + private static final int INPUT_OBJECT = 0; + private static final int INPUT_OFFSET = 1; + private static final int INPUT_VALUE = 2; + + private static final int SUCCESSOR_COUNT = 0; + + public UnsafeStore(Value object, Value offset, Value value, CiKind kind, Graph graph) { + super(kind, INPUT_COUNT, SUCCESSOR_COUNT, graph); + setObject(object); + setOffset(offset); + setValue(value); + } + + public Value object() { + return (Value) inputs().get(super.inputCount() + INPUT_OBJECT); + } + + public Value setObject(Value object) { + return (Value) inputs().set(super.inputCount() + INPUT_OBJECT, object); + } + + public Value offset() { + return (Value) inputs().get(super.inputCount() + INPUT_OFFSET); + } + + public Value setOffset(Value offset) { + return (Value) inputs().set(super.inputCount() + INPUT_OFFSET, offset); + } + + public Value value() { + return (Value) inputs().get(super.inputCount() + INPUT_VALUE); + } + + public Value setValue(Value value) { + return (Value) inputs().set(super.inputCount() + INPUT_VALUE, value); + } + + @SuppressWarnings("unchecked") + @Override + public <T extends Op> T lookup(Class<T> 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; + } + +}