changeset 7160:d526fa5640c8

replaced manual intrinsification of Object.getClass() with a snippet
author Doug Simon <doug.simon@oracle.com>
date Thu, 13 Dec 2012 22:54:04 +0100
parents 3fbde10a77b0
children 97025e0b202d
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/HotSpotSnippetUtils.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ObjectSnippets.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java
diffstat 4 files changed, 87 insertions(+), 46 deletions(-) [+]
line wrap: on
line diff
--- 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<? extends Node> 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))));
--- 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;
     }
--- /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;
+    }
+}
--- 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> 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> T read(Object base, @ConstantNodeParameter int displacement, @ConstantNodeParameter Object locationIdentity, @ConstantNodeParameter Kind kind);
 }