# HG changeset patch # User Stefan Anzinger # Date 1428002845 -7200 # Node ID 7bf5292dd7ad2d60d10c069e6615b291964fbe2d # Parent b1a8928fc4b94b559faf4d0877117fbc6e23336c# Parent 6f669b9be43c6958b4806cf2f2f93f2543cc526f Merge diff -r b1a8928fc4b9 -r 7bf5292dd7ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ObjectEqualsNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ObjectEqualsNode.java Thu Apr 02 18:45:28 2015 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ObjectEqualsNode.java Thu Apr 02 21:27:25 2015 +0200 @@ -22,7 +22,6 @@ */ package com.oracle.graal.nodes.calc; -import com.oracle.graal.api.meta.Assumptions.AssumptionResult; import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.calc.*; @@ -63,21 +62,10 @@ protected ValueNode canonicalizeSymmetricConstant(CanonicalizerTool tool, Constant constant, ValueNode nonConstant, boolean mirrored) { ResolvedJavaType type = tool.getConstantReflection().asJavaType(constant); if (type != null && nonConstant instanceof GetClassNode) { - if (type.isPrimitive()) { - return LogicConstantNode.forBoolean(false); + if (!type.isPrimitive() && (type.isConcrete() || type.isArray())) { + return TypeCheckNode.create(type, ((GetClassNode) nonConstant).getObject()); } - ResolvedJavaType exactType = type.asExactType(); - if (exactType == null) { - AssumptionResult leafConcreteSubtype = type.findLeafConcreteSubtype(); - if (leafConcreteSubtype != null) { - graph().getAssumptions().record(leafConcreteSubtype); - exactType = leafConcreteSubtype.getResult(); - } - } - - if (type.equals(exactType)) { - return TypeCheckNode.create(exactType, ((GetClassNode) nonConstant).getObject()); - } + return LogicConstantNode.forBoolean(false); } return super.canonicalizeSymmetricConstant(tool, constant, nonConstant, mirrored); } @@ -119,7 +107,7 @@ /* * One of the two objects has identity, the other doesn't. In code, this looks like * "Integer.valueOf(a) == new Integer(b)", which is always false. - * + * * In other words: an object created via valueOf can never be equal to one created * by new in the same compilation unit. */ diff -r b1a8928fc4b9 -r 7bf5292dd7ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatableAccessNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatableAccessNode.java Thu Apr 02 18:45:28 2015 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatableAccessNode.java Thu Apr 02 21:27:25 2015 +0200 @@ -49,12 +49,18 @@ public abstract FloatingAccessNode asFloatingNode(MemoryNode lastLocationAccess); + protected boolean forceFixed; + + public void setForceFixed(boolean flag) { + this.forceFixed = flag; + } + /** * AccessNodes can float only if their location identities are not ANY_LOCATION. Furthermore, in * case G1 is enabled any access (read) to the java.lang.ref.Reference.referent field which has * an attached write barrier with pre-semantics can not also float. */ public boolean canFloat() { - return location().getLocationIdentity().isSingle() && getBarrierType() == BarrierType.NONE; + return !forceFixed && location().getLocationIdentity().isSingle() && getBarrierType() == BarrierType.NONE; } } diff -r b1a8928fc4b9 -r 7bf5292dd7ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/TypeCheckNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/TypeCheckNode.java Thu Apr 02 18:45:28 2015 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/TypeCheckNode.java Thu Apr 02 21:27:25 2015 +0200 @@ -100,7 +100,8 @@ return result; } if (type().equals(inputType)) { - if (!nonNull) { + boolean mightBeNull = !nonNull; + if (exactType && mightBeNull) { // the instanceof matches if the object is non-null, so return true // depending on the null-ness. return LogicNegationNode.create(new IsNullNode(forValue)); @@ -114,7 +115,7 @@ return null; } if (type.equals(inputType)) { - if (nonNull) { + if (nonNull && exactType) { // the type matches, so return true return LogicConstantNode.tautology(); } diff -r b1a8928fc4b9 -r 7bf5292dd7ad graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/InstanceOfTest.java --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/InstanceOfTest.java Thu Apr 02 18:45:28 2015 +0200 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/InstanceOfTest.java Thu Apr 02 21:27:25 2015 +0200 @@ -396,4 +396,20 @@ test("isArrayOfD", cArray); test("isArrayOfD", dArray); } + + @SuppressWarnings("unchecked") + public static String arrayCopyTypeName(T[] original) { + Class newType = (Class) original.getClass(); + if (newType == (Object) Object[].class) { + return Object[].class.getName(); + } else { + return newType.getName(); + } + } + + @Test + public void testArrayCopy() { + test("arrayCopyTypeName", (Object) new Object[]{"one", "two", "three"}); + test("arrayCopyTypeName", (Object) new String[]{"one", "two", "three"}); + } } diff -r b1a8928fc4b9 -r 7bf5292dd7ad graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultJavaLoweringProvider.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultJavaLoweringProvider.java Thu Apr 02 18:45:28 2015 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultJavaLoweringProvider.java Thu Apr 02 21:27:25 2015 +0200 @@ -273,10 +273,7 @@ graph.addAfterFixed(valueAnchorNode, memoryRead); } else { assert load.getKind() != Kind.Illegal; - // An unsafe read must not float outside its block otherwise - // it may float above an explicit null check on its object. - AbstractBeginNode guard = AbstractBeginNode.prevBegin(load); - ReadNode memoryRead = createUnsafeRead(graph, load, guard); + ReadNode memoryRead = createUnsafeRead(graph, load, null); graph.replaceFixedWithFixed(load, memoryRead); } } @@ -295,6 +292,11 @@ } Stamp loadStamp = loadStamp(load.stamp(), readKind, compressible); ReadNode memoryRead = graph.add(new ReadNode(object, location, loadStamp, guard, BarrierType.NONE)); + if (guard == null) { + // An unsafe read must not float otherwise it may float above + // a test guaranteeing the read is safe. + memoryRead.setForceFixed(true); + } ValueNode readValue = implicitLoadConvert(graph, readKind, memoryRead, compressible); load.replaceAtUsages(readValue); return memoryRead; @@ -325,6 +327,9 @@ Stamp loadStamp = loadStamp(read.stamp(), valueKind, read.isCompressible()); ReadNode memoryRead = graph.add(new ReadNode(read.object(), read.location(), loadStamp, read.getBarrierType())); + // An unsafe read must not float otherwise it may float above + // a test guaranteeing the read is safe. + memoryRead.setForceFixed(true); ValueNode readValue = implicitLoadConvert(graph, valueKind, memoryRead, read.isCompressible()); memoryRead.setGuard(read.getGuard()); read.replaceAtUsages(readValue); diff -r b1a8928fc4b9 -r 7bf5292dd7ad graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/WordOperationPlugin.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/WordOperationPlugin.java Thu Apr 02 18:45:28 2015 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/WordOperationPlugin.java Thu Apr 02 21:27:25 2015 +0200 @@ -231,12 +231,12 @@ } public static ValueNode readOp(GraphBuilderContext b, Kind readKind, ValueNode base, LocationNode location, BarrierType barrierType, boolean compressible) { + /* + * A JavaReadNode lowered to a ReadNode that will not float. This means it cannot float + * above an explicit zero check on its base address or any other test that ensures the read + * is safe. + */ JavaReadNode read = b.add(new JavaReadNode(readKind, base, location, barrierType, compressible)); - /* - * The read must not float outside its block otherwise it may float above an explicit zero - * check on its base address. - */ - read.setGuard(AbstractBeginNode.prevBegin(read)); return read; }