# HG changeset patch # User Gilles Duboscq # Date 1343662624 25200 # Node ID 77196bba55758fb5139742a4563fd0f2665a10bd # Parent 191e08da4de43cc918263ed94017a648ea1eaf4f Change one more GraalCodeCacheProvider to MetaAccessProvider Add static methods to BoxingMethodPool In the default inlining policy for snippets, do not inline boxing Factor arraycopy code diff -r 191e08da4de4 -r 77196bba5575 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/IterativeCheckCastEliminationPhase.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/IterativeCheckCastEliminationPhase.java Thu Jul 26 17:47:09 2012 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/IterativeCheckCastEliminationPhase.java Mon Jul 30 08:37:04 2012 -0700 @@ -25,18 +25,18 @@ import java.util.*; import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.Graph.InputChangedListener; import com.oracle.graal.graph.*; -import com.oracle.graal.graph.Graph.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; public class IterativeCheckCastEliminationPhase extends Phase { private final TargetDescription target; - private final GraalCodeCacheProvider runtime; + private final MetaAccessProvider runtime; private final Assumptions assumptions; - public IterativeCheckCastEliminationPhase(TargetDescription target, GraalCodeCacheProvider runtime, Assumptions assumptions) { + public IterativeCheckCastEliminationPhase(TargetDescription target, MetaAccessProvider runtime, Assumptions assumptions) { this.target = target; this.runtime = runtime; this.assumptions = assumptions; diff -r 191e08da4de4 -r 77196bba5575 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ArrayCopySnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ArrayCopySnippets.java Thu Jul 26 17:47:09 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ArrayCopySnippets.java Mon Jul 30 08:37:04 2012 -0700 @@ -38,17 +38,17 @@ private static final Kind VECTOR_KIND = Kind.Long; private static final long VECTOR_SIZE = arrayIndexScale(Kind.Long); - //@Snippet + @Snippet public static void vectorizedCopy(Object src, int srcPos, Object dest, int destPos, int length, @ConstantParameter("baseKind") Kind baseKind) { int header = arrayBaseOffset(baseKind); - long byteLength = length * arrayIndexScale(baseKind); + int elementSize = arrayIndexScale(baseKind); + long byteLength = length * elementSize; long nonVectorBytes = byteLength % VECTOR_SIZE; - long srcOffset = srcPos * arrayIndexScale(baseKind); - long destOffset = destPos * arrayIndexScale(baseKind); + long srcOffset = srcPos * elementSize; + long destOffset = destPos * elementSize; if (src == dest && srcPos < destPos) { // bad aliased case - for (long i = byteLength - 1; i > byteLength - 1 - nonVectorBytes; i--) { - Byte a = UnsafeLoadNode.load(src, header, i + srcOffset, Kind.Byte); - UnsafeStoreNode.store(dest, header, i + destOffset, a.byteValue(), Kind.Byte); + for (long i = byteLength - elementSize; i >= byteLength - nonVectorBytes; i -= elementSize) { + UnsafeStoreNode.store(dest, header, i + destOffset, UnsafeLoadNode.load(src, header, i + srcOffset, baseKind), baseKind); } long vectorLength = byteLength - nonVectorBytes; for (long i = vectorLength - VECTOR_SIZE; i >= 0; i -= VECTOR_SIZE) { @@ -56,9 +56,8 @@ UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), VECTOR_KIND); } } else { - for (long i = 0; i < nonVectorBytes; i++) { - Byte a = UnsafeLoadNode.load(src, header, i + srcOffset, Kind.Byte); - UnsafeStoreNode.store(dest, header, i + destOffset, a.byteValue(), Kind.Byte); + for (long i = 0; i < nonVectorBytes; i += elementSize) { + UnsafeStoreNode.store(dest, header, i + destOffset, UnsafeLoadNode.load(src, header, i + srcOffset, baseKind), baseKind); } for (long i = nonVectorBytes; i < byteLength; i += VECTOR_SIZE) { Long a = UnsafeLoadNode.load(src, header, i + srcOffset, VECTOR_KIND); @@ -75,32 +74,7 @@ if (srcPos < 0 || destPos < 0 || length < 0 || srcPos + length > src.length || destPos + length > dest.length) { throw new IndexOutOfBoundsException(); } - Kind baseKind = Kind.Byte; - int header = arrayBaseOffset(baseKind); - long byteLength = length * arrayIndexScale(baseKind); - long nonVectorBytes = byteLength % VECTOR_SIZE; - long srcOffset = srcPos * arrayIndexScale(baseKind); - long destOffset = destPos * arrayIndexScale(baseKind); - if (src == dest && srcPos < destPos) { // bad aliased case - for (long i = byteLength - arrayIndexScale(Kind.Byte); i >= byteLength - nonVectorBytes; i -= arrayIndexScale(Kind.Byte)) { - Byte a = UnsafeLoadNode.load(src, header, i + srcOffset, Kind.Byte); - UnsafeStoreNode.store(dest, header, i + destOffset, a.byteValue(), Kind.Byte); - } - long vectorLength = byteLength - nonVectorBytes; - for (long i = vectorLength - VECTOR_SIZE; i >= 0; i -= VECTOR_SIZE) { - Long a = UnsafeLoadNode.load(src, header, i + srcOffset, VECTOR_KIND); - UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), VECTOR_KIND); - } - } else { - for (long i = 0; i < nonVectorBytes; i += arrayIndexScale(Kind.Byte)) { - Byte a = UnsafeLoadNode.load(src, header, i + srcOffset, Kind.Byte); - UnsafeStoreNode.store(dest, header, i + destOffset, a.byteValue(), Kind.Byte); - } - for (long i = nonVectorBytes; i < byteLength; i += VECTOR_SIZE) { - Long a = UnsafeLoadNode.load(src, header, i + srcOffset, VECTOR_KIND); - UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), VECTOR_KIND); - } - } + vectorizedCopy(src, srcPos, dest, destPos, length, Kind.Byte); } @Snippet @@ -111,32 +85,7 @@ if (srcPos < 0 || destPos < 0 || length < 0 || srcPos + length > src.length || destPos + length > dest.length) { throw new IndexOutOfBoundsException(); } - Kind baseKind = Kind.Char; - int header = arrayBaseOffset(baseKind); - long byteLength = length * arrayIndexScale(baseKind); - long nonVectorBytes = byteLength % VECTOR_SIZE; - long srcOffset = srcPos * arrayIndexScale(baseKind); - long destOffset = destPos * arrayIndexScale(baseKind); - if (src == dest && srcPos < destPos) { // bad aliased case - for (long i = byteLength - arrayIndexScale(Kind.Char); i >= byteLength - nonVectorBytes; i -= arrayIndexScale(Kind.Char)) { - Character a = UnsafeLoadNode.load(src, header, i + srcOffset, Kind.Char); - UnsafeStoreNode.store(dest, header, i + destOffset, a.charValue(), Kind.Char); - } - long vectorLength = byteLength - nonVectorBytes; - for (long i = vectorLength - VECTOR_SIZE; i >= 0; i -= VECTOR_SIZE) { - Long a = UnsafeLoadNode.load(src, header, i + srcOffset, VECTOR_KIND); - UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), VECTOR_KIND); - } - } else { - for (long i = 0; i < nonVectorBytes; i += arrayIndexScale(Kind.Char)) { - Character a = UnsafeLoadNode.load(src, header, i + srcOffset, Kind.Char); - UnsafeStoreNode.store(dest, header, i + destOffset, a.charValue(), Kind.Char); - } - for (long i = nonVectorBytes; i < byteLength; i += VECTOR_SIZE) { - Long a = UnsafeLoadNode.load(src, header, i + srcOffset, VECTOR_KIND); - UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), VECTOR_KIND); - } - } + vectorizedCopy(src, srcPos, dest, destPos, length, Kind.Char); } @Snippet @@ -147,32 +96,7 @@ if (srcPos < 0 || destPos < 0 || length < 0 || srcPos + length > src.length || destPos + length > dest.length) { throw new IndexOutOfBoundsException(); } - Kind baseKind = Kind.Short; - int header = arrayBaseOffset(baseKind); - long byteLength = length * arrayIndexScale(baseKind); - long nonVectorBytes = byteLength % VECTOR_SIZE; - long srcOffset = srcPos * arrayIndexScale(baseKind); - long destOffset = destPos * arrayIndexScale(baseKind); - if (src == dest && srcPos < destPos) { // bad aliased case - for (long i = byteLength - arrayIndexScale(Kind.Short); i >= byteLength - nonVectorBytes; i -= arrayIndexScale(Kind.Short)) { - Short a = UnsafeLoadNode.load(src, header, i + srcOffset, Kind.Short); - UnsafeStoreNode.store(dest, header, i + destOffset, a.shortValue(), Kind.Short); - } - long vectorLength = byteLength - nonVectorBytes; - for (long i = vectorLength - VECTOR_SIZE; i >= 0; i -= VECTOR_SIZE) { - Long a = UnsafeLoadNode.load(src, header, i + srcOffset, VECTOR_KIND); - UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), VECTOR_KIND); - } - } else { - for (long i = 0; i < nonVectorBytes; i += arrayIndexScale(Kind.Short)) { - Short a = UnsafeLoadNode.load(src, header, i + srcOffset, Kind.Short); - UnsafeStoreNode.store(dest, header, i + destOffset, a.shortValue(), Kind.Short); - } - for (long i = nonVectorBytes; i < byteLength; i += VECTOR_SIZE) { - Long a = UnsafeLoadNode.load(src, header, i + srcOffset, VECTOR_KIND); - UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), VECTOR_KIND); - } - } + vectorizedCopy(src, srcPos, dest, destPos, length, Kind.Short); } @Snippet @@ -183,32 +107,7 @@ if (srcPos < 0 || destPos < 0 || length < 0 || srcPos + length > src.length || destPos + length > dest.length) { throw new IndexOutOfBoundsException(); } - Kind baseKind = Kind.Int; - int header = arrayBaseOffset(baseKind); - long byteLength = length * arrayIndexScale(baseKind); - long nonVectorBytes = byteLength % VECTOR_SIZE; - long srcOffset = srcPos * arrayIndexScale(baseKind); - long destOffset = destPos * arrayIndexScale(baseKind); - if (src == dest && srcPos < destPos) { // bad aliased case - for (long i = byteLength - arrayIndexScale(Kind.Int); i >= byteLength - nonVectorBytes; i -= arrayIndexScale(Kind.Int)) { - Integer a = UnsafeLoadNode.load(src, header, i + srcOffset, Kind.Int); - UnsafeStoreNode.store(dest, header, i + destOffset, a.intValue(), Kind.Int); - } - long vectorLength = byteLength - nonVectorBytes; - for (long i = vectorLength - VECTOR_SIZE; i >= 0; i -= VECTOR_SIZE) { - Long a = UnsafeLoadNode.load(src, header, i + srcOffset, VECTOR_KIND); - UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), VECTOR_KIND); - } - } else { - for (long i = 0; i < nonVectorBytes; i += arrayIndexScale(Kind.Int)) { - Integer a = UnsafeLoadNode.load(src, header, i + srcOffset, Kind.Int); - UnsafeStoreNode.store(dest, header, i + destOffset, a.intValue(), Kind.Int); - } - for (long i = nonVectorBytes; i < byteLength; i += VECTOR_SIZE) { - Long a = UnsafeLoadNode.load(src, header, i + srcOffset, VECTOR_KIND); - UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), VECTOR_KIND); - } - } + vectorizedCopy(src, srcPos, dest, destPos, length, Kind.Int); } @Snippet @@ -219,32 +118,7 @@ if (srcPos < 0 || destPos < 0 || length < 0 || srcPos + length > src.length || destPos + length > dest.length) { throw new IndexOutOfBoundsException(); } - Kind baseKind = Kind.Float; - int header = arrayBaseOffset(baseKind); - long byteLength = length * arrayIndexScale(baseKind); - long nonVectorBytes = byteLength % VECTOR_SIZE; - long srcOffset = srcPos * arrayIndexScale(baseKind); - long destOffset = destPos * arrayIndexScale(baseKind); - if (src == dest && srcPos < destPos) { // bad aliased case - for (long i = byteLength - arrayIndexScale(Kind.Float); i >= byteLength - nonVectorBytes; i -= arrayIndexScale(Kind.Float)) { - Float a = UnsafeLoadNode.load(src, header, i + srcOffset, Kind.Float); - UnsafeStoreNode.store(dest, header, i + destOffset, a.floatValue(), Kind.Float); - } - long vectorLength = byteLength - nonVectorBytes; - for (long i = vectorLength - VECTOR_SIZE; i >= 0; i -= VECTOR_SIZE) { - Long a = UnsafeLoadNode.load(src, header, i + srcOffset, VECTOR_KIND); - UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), VECTOR_KIND); - } - } else { - for (long i = 0; i < nonVectorBytes; i += arrayIndexScale(Kind.Float)) { - Float a = UnsafeLoadNode.load(src, header, i + srcOffset, Kind.Float); - UnsafeStoreNode.store(dest, header, i + destOffset, a.floatValue(), Kind.Float); - } - for (long i = nonVectorBytes; i < byteLength; i += VECTOR_SIZE) { - Long a = UnsafeLoadNode.load(src, header, i + srcOffset, VECTOR_KIND); - UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), VECTOR_KIND); - } - } + vectorizedCopy(src, srcPos, dest, destPos, length, Kind.Float); } @Snippet diff -r 191e08da4de4 -r 77196bba5575 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxingMethodPool.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxingMethodPool.java Thu Jul 26 17:47:09 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxingMethodPool.java Mon Jul 30 08:37:04 2012 -0700 @@ -22,11 +22,32 @@ */ package com.oracle.graal.nodes.extended; +import java.lang.reflect.*; import java.util.*; +import java.util.Map.Entry; import com.oracle.graal.api.meta.*; public class BoxingMethodPool { + private static final Map boxings = new HashMap<>(); + private static class BoxingMethod { + final Class type; + final String unboxMethod; + public BoxingMethod(Class< ? > type, String unboxMethod) { + this.type = type; + this.unboxMethod = unboxMethod; + } + } + static { + boxings.put(Kind.Boolean, new BoxingMethod(Boolean.class, "booleanValue")); + boxings.put(Kind.Byte, new BoxingMethod(Byte.class, "byteValue")); + boxings.put(Kind.Char, new BoxingMethod(Character.class, "charValue")); + boxings.put(Kind.Short, new BoxingMethod(Short.class, "shortValue")); + boxings.put(Kind.Int, new BoxingMethod(Integer.class, "intValue")); + boxings.put(Kind.Long, new BoxingMethod(Long.class, "longValue")); + boxings.put(Kind.Float, new BoxingMethod(Float.class, "floatValue")); + boxings.put(Kind.Double, new BoxingMethod(Double.class, "doubleValue")); + } private final Set specialMethods = new HashSet<>(); private final MetaAccessProvider runtime; @@ -41,14 +62,11 @@ private void initialize() { try { - initialize(Kind.Boolean, Boolean.class, "booleanValue"); - initialize(Kind.Byte, Byte.class, "byteValue"); - initialize(Kind.Char, Character.class, "charValue"); - initialize(Kind.Short, Short.class, "shortValue"); - initialize(Kind.Int, Integer.class, "intValue"); - initialize(Kind.Long, Long.class, "longValue"); - initialize(Kind.Float, Float.class, "floatValue"); - initialize(Kind.Double, Double.class, "doubleValue"); + for (Entry entry : boxings.entrySet()) { + Kind kind = entry.getKey(); + BoxingMethod boxing = entry.getValue(); + initialize(kind, boxing.type, boxing.unboxMethod); + } } catch (SecurityException e) { throw new RuntimeException(e); } catch (NoSuchMethodException e) { @@ -98,4 +116,38 @@ public ResolvedJavaField getBoxField(Kind kind) { return boxFields[kind.ordinal()]; } + + public static boolean isSpecialMethodStatic(ResolvedJavaMethod method) { + return isUnboxingMethodStatic(method) || isBoxingMethodStatic(method); + } + + public static boolean isBoxingMethodStatic(ResolvedJavaMethod method) { + Signature signature = method.signature(); + if (!Modifier.isStatic(method.accessFlags()) + || signature.returnKind() == Kind.Object + || signature.argumentCount(false) != 1) { + return false; + } + Kind kind = signature.argumentKindAt(0); + BoxingMethod boxing = boxings.get(kind); + if (boxing == null) { + return false; + } + return method.holder().toJava() == boxing.type && method.name().equals("valueOf"); + } + + public static boolean isUnboxingMethodStatic(ResolvedJavaMethod method) { + Signature signature = method.signature(); + if (signature.returnKind() == Kind.Object + || signature.argumentCount(false) != 0 + || Modifier.isStatic(method.accessFlags())) { + return false; + } + Kind kind = signature.returnKind(); + BoxingMethod boxing = boxings.get(kind); + if (boxing == null) { + return false; + } + return method.holder().toJava() == boxing.type && method.name().equals(boxing.unboxMethod); + } } diff -r 191e08da4de4 -r 77196bba5575 graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Snippet.java --- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Snippet.java Thu Jul 26 17:47:09 2012 +0200 +++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Snippet.java Mon Jul 30 08:37:04 2012 -0700 @@ -27,6 +27,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.Node.NodeIntrinsic; +import com.oracle.graal.nodes.extended.*; import com.oracle.graal.snippets.Word.Operation; import com.oracle.graal.snippets.nodes.*; @@ -86,6 +87,9 @@ if (method.getAnnotation(Operation.class) != null) { return false; } + if (BoxingMethodPool.isSpecialMethodStatic(method)) { + return false; + } return true; } }; diff -r 191e08da4de4 -r 77196bba5575 graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/BitScanForwardNode.java --- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/BitScanForwardNode.java Thu Jul 26 17:47:09 2012 +0200 +++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/BitScanForwardNode.java Mon Jul 30 08:37:04 2012 -0700 @@ -66,5 +66,4 @@ gen.append(new AMD64BitScanOp(IntrinsicOpcode.BSF, result, gen.operand(value))); gen.setResult(this, result); } - }