changeset 5358:8b5ef24da264

canonicalize load from a compile-constant, immutable array
author Doug Simon <doug.simon@oracle.com>
date Fri, 04 May 2012 16:54:27 +0200
parents a250ca83684e
children 4bfdf8cf87af 88cd108e0164
files graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java
diffstat 1 files changed, 23 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java	Fri May 04 16:52:58 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java	Fri May 04 16:54:27 2012 +0200
@@ -22,17 +22,21 @@
  */
 package com.oracle.graal.nodes.java;
 
-import com.oracle.max.cri.ci.*;
+import java.lang.reflect.*;
+
+import sun.misc.*;
+
 import com.oracle.graal.cri.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
+import com.oracle.max.cri.ci.*;
 
 /**
  * The {@code LoadIndexedNode} represents a read from an element of an array.
  */
-public final class LoadIndexedNode extends AccessIndexedNode implements Lowerable, Node.IterableNodeType {
+public final class LoadIndexedNode extends AccessIndexedNode implements Canonicalizable, Lowerable, Node.IterableNodeType {
 
     /**
      * Creates a new LoadIndexedNode.
@@ -62,4 +66,21 @@
     public void lower(CiLoweringTool tool) {
         tool.getRuntime().lower(this, tool);
     }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (index().isConstant() && array().isConstant() && !array().isNullConstant()) {
+            CiConstant arrayConst = array().asConstant();
+            if (tool.isImmutable(arrayConst)) {
+                int index = index().asConstant().asInt();
+                Object array = arrayConst.asObject();
+                int length = Array.getLength(array);
+                if (index >= 0 && index < length) {
+                    return ConstantNode.forCiConstant(elementKind().readUnsafeConstant(array,
+                                    Unsafe.ARRAY_OBJECT_BASE_OFFSET + index * Unsafe.ARRAY_OBJECT_INDEX_SCALE), tool.runtime(), graph());
+                }
+            }
+        }
+        return this;
+    }
 }