# HG changeset patch # User Doug Simon # Date 1355435644 -3600 # Node ID d526fa5640c8a106782221c6ec22300254b0e771 # Parent 3fbde10a77b0ef5a2f1495452c1fdcb2224d30f1 replaced manual intrinsification of Object.getClass() with a snippet diff -r 3fbde10a77b0 -r d526fa5640c8 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Thu Dec 13 15:42:30 2012 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Thu Dec 13 22:54:04 2012 +0100 @@ -292,6 +292,7 @@ protected abstract RegisterConfig createRegisterConfig(boolean globalStubConfig); public void installSnippets(SnippetInstaller installer, Assumptions assumptions) { + installer.install(ObjectSnippets.class); installer.install(ClassSnippets.class); installer.install(SystemSnippets.class); installer.install(UnsafeSnippets.class); @@ -703,30 +704,7 @@ public StructuredGraph intrinsicGraph(ResolvedJavaMethod caller, int bci, ResolvedJavaMethod method, List parameters) { ResolvedJavaType holder = method.getDeclaringClass(); String fullName = method.getName() + ((HotSpotSignature) method.getSignature()).asString(); - Kind wordKind = graalRuntime.getTarget().wordKind; - if (MetaUtil.isJavaLangObject(holder)) { - if (fullName.equals("getClass()Ljava/lang/Class;")) { - ValueNode obj = (ValueNode) parameters.get(0); - ObjectStamp stamp = (ObjectStamp) obj.stamp(); - if (stamp.nonNull() && stamp.isExactType()) { - HotSpotResolvedJavaType type = (HotSpotResolvedJavaType) stamp.type(); - StructuredGraph graph = new StructuredGraph(); - ValueNode result = ConstantNode.forObject(type.mirror(), this, graph); - ReturnNode ret = graph.add(new ReturnNode(result)); - graph.start().setNext(ret); - return graph; - } - StructuredGraph graph = new StructuredGraph(); - LocalNode receiver = graph.unique(new LocalNode(0, StampFactory.objectNonNull())); - LoadHubNode hub = graph.add(new LoadHubNode(receiver, wordKind)); - Stamp resultStamp = StampFactory.declaredNonNull(lookupJavaType(Class.class)); - FloatingReadNode result = graph.unique(new FloatingReadNode(hub, LocationNode.create(LocationNode.FINAL_LOCATION, Kind.Object, config.classMirrorOffset, graph), null, resultStamp)); - ReturnNode ret = graph.add(new ReturnNode(result)); - graph.start().setNext(hub); - hub.setNext(ret); - return graph; - } - } else if (holder.equals(lookupJavaType(Thread.class))) { + if (holder.equals(lookupJavaType(Thread.class))) { if (fullName.equals("currentThread()Ljava/lang/Thread;")) { StructuredGraph graph = new StructuredGraph(); ReturnNode ret = graph.add(new ReturnNode(graph.unique(new CurrentThread(config.threadObjectOffset, this)))); diff -r 3fbde10a77b0 -r d526fa5640c8 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/HotSpotSnippetUtils.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/HotSpotSnippetUtils.java Thu Dec 13 15:42:30 2012 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/HotSpotSnippetUtils.java Thu Dec 13 22:54:04 2012 +0100 @@ -248,6 +248,10 @@ return loadWordFromObjectIntrinsic(object, 0, offset, wordKind()); } + public static Object readFinalObject(Word base, @ConstantNodeParameter int displacement) { + return ReadNode.read(base, displacement, LocationNode.FINAL_LOCATION, Kind.Object); + } + @NodeIntrinsic(value = RegisterNode.class, setStampFromReturnType = true) public static native Word registerAsWord(@ConstantNodeParameter Register register); @@ -260,6 +264,7 @@ @NodeIntrinsic(value = LoadHubNode.class, setStampFromReturnType = true) static native Word loadHubIntrinsic(Object object, @ConstantNodeParameter Kind word); + @Fold public static int log2WordSize() { @@ -286,6 +291,12 @@ @Fold public + static int classMirrorOffset() { + return config().classMirrorOffset; + } + + @Fold + public static int klassInstanceSizeOffset() { return config().klassInstanceSizeOffset; } diff -r 3fbde10a77b0 -r d526fa5640c8 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ObjectSnippets.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ObjectSnippets.java Thu Dec 13 22:54:04 2012 +0100 @@ -0,0 +1,42 @@ +/* + * 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.graal.hotspot.snippets; + +import static com.oracle.graal.hotspot.snippets.HotSpotSnippetUtils.*; + +import com.oracle.graal.snippets.*; +import com.oracle.graal.snippets.ClassSubstitution.MethodSubstitution; + +/** + * Snippets for {@link java.lang.Object} methods. + */ +@ClassSubstitution(java.lang.Object.class) +public class ObjectSnippets implements SnippetsInterface { + + @MethodSubstitution("getClass") + public Class getClass_() { + Word hub = loadHub(this); + Object mirror = readFinalObject(hub, classMirrorOffset()); + return (Class) mirror; + } +} diff -r 3fbde10a77b0 -r d526fa5640c8 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 Thu Dec 13 15:42:30 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Thu Dec 13 22:54:04 2012 +0100 @@ -34,10 +34,14 @@ */ public final class ReadNode extends AccessNode implements Node.IterableNodeType, LIRLowerable, Canonicalizable { - public ReadNode(ValueNode object, ValueNode location, Stamp stamp) { + public ReadNode(ValueNode object, LocationNode location, Stamp stamp) { super(object, location, stamp); } + public ReadNode(ValueNode object, int displacement, Object locationIdentity, Kind kind) { + super(object, object.graph().add(new LocationNode(locationIdentity, kind, displacement)), StampFactory.forKind(kind)); + } + @Override public void generate(LIRGeneratorTool gen) { gen.setResult(this, gen.emitLoad(gen.makeAddress(location(), object()), getNullCheck())); @@ -56,24 +60,23 @@ * @return the read value encapsulated in a {@link Constant} object */ public static Constant readUnsafeConstant(Kind kind, Object object, long displacement) { - assert object != null; switch (kind) { case Boolean: - return Constant.forBoolean(unsafe.getBoolean(object, displacement)); + return Constant.forBoolean(object == null ? unsafe.getByte(displacement) != 0 : unsafe.getBoolean(object, displacement)); case Byte: - return Constant.forByte(unsafe.getByte(object, displacement)); + return Constant.forByte(object == null ? unsafe.getByte(displacement) : unsafe.getByte(object, displacement)); case Char: - return Constant.forChar(unsafe.getChar(object, displacement)); + return Constant.forChar(object == null ? unsafe.getChar(displacement) : unsafe.getChar(object, displacement)); case Short: - return Constant.forShort(unsafe.getShort(object, displacement)); + return Constant.forShort(object == null ? unsafe.getShort(displacement) : unsafe.getShort(object, displacement)); case Int: - return Constant.forInt(unsafe.getInt(object, displacement)); + return Constant.forInt(object == null ? unsafe.getInt(displacement) : unsafe.getInt(object, displacement)); case Long: - return Constant.forLong(unsafe.getLong(object, displacement)); + return Constant.forLong(object == null ? unsafe.getLong(displacement) : unsafe.getLong(object, displacement)); case Float: - return Constant.forFloat(unsafe.getFloat(object, displacement)); + return Constant.forFloat(object == null ? unsafe.getFloat(displacement) : unsafe.getFloat(object, displacement)); case Double: - return Constant.forDouble(unsafe.getDouble(object, displacement)); + return Constant.forDouble(object == null ? unsafe.getDouble(displacement) : unsafe.getDouble(object, displacement)); case Object: return Constant.forObject(unsafe.getObject(object, displacement)); default: @@ -83,13 +86,15 @@ public static ValueNode canonicalizeRead(Access read, CanonicalizerTool tool) { MetaAccessProvider runtime = tool.runtime(); - if (runtime != null && read.object() != null && read.object().isConstant() && read.object().kind() == Kind.Object) { + if (runtime != null && read.object() != null && read.object().isConstant()/* && read.object().kind() == Kind.Object*/) { if (read.location().locationIdentity() == LocationNode.FINAL_LOCATION && read.location().getClass() == LocationNode.class) { - Object value = read.object().asConstant().asObject(); - if (value != null) { - long displacement = read.location().displacement(); - Kind kind = read.location().getValueKind(); - Constant constant = readUnsafeConstant(kind, value, displacement); + long displacement = read.location().displacement(); + Kind kind = read.location().getValueKind(); + if (read.object().kind() == Kind.Object) { + Constant constant = readUnsafeConstant(kind, read.object().asConstant().asObject(), displacement); + return ConstantNode.forConstant(constant, runtime, read.node().graph()); + } else if (read.object().kind() == Kind.Long || read.object().kind().getStackKind() == Kind.Int) { + Constant constant = readUnsafeConstant(kind, null, read.object().asConstant().asLong() + displacement); return ConstantNode.forConstant(constant, runtime, read.node().graph()); } } @@ -97,10 +102,15 @@ return (ValueNode) read; } - private ReadNode(ValueNode object, ValueNode location) { - this(object, location, StampFactory.forNodeIntrinsic()); - } - - @NodeIntrinsic - public static native T readMemory(Object object, Object location); + /** + * Reads a value from memory. + * + * @param base the base pointer for the memory access + * @param displacement the displacement of the access + * @param locationIdentity the identity of the access + * @param kind the kind of the value read + * @return the value read from memory + */ + @NodeIntrinsic(setStampFromReturnType = true) + public static native T read(Object base, @ConstantNodeParameter int displacement, @ConstantNodeParameter Object locationIdentity, @ConstantNodeParameter Kind kind); }