# HG changeset patch # User Tom Rodriguez # Date 1437416488 25200 # Node ID 7abe84b97eaad9d33d0c52ecfe0c54d4c86c6182 # Parent 71a696ca286282d477c4b106539316b008d3873f# Parent 5c350399111efaf482e4aa0b5da34b2c17757d90 Merge diff -r 5c350399111e -r 7abe84b97eaa graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/AbstractObjectStamp.java --- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/AbstractObjectStamp.java Mon Jul 20 17:01:45 2015 +0200 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/AbstractObjectStamp.java Mon Jul 20 11:21:28 2015 -0700 @@ -265,7 +265,7 @@ int result = 1; result = prime * result + super.hashCode(); result = prime * result + (exactType ? 1231 : 1237); - result = prime * result + ((type == null) ? 0 : type.hashCode()); + result = prime * result + ((type == null || type.isJavaLangObject()) ? 0 : type.hashCode()); return result; } @@ -278,7 +278,19 @@ return false; } AbstractObjectStamp other = (AbstractObjectStamp) obj; - if (exactType != other.exactType || !Objects.equals(type, other.type)) { + if (exactType != other.exactType) { + return false; + } + // null == java.lang.Object + if (type == null) { + if (other.type != null && !other.type.isJavaLangObject()) { + return false; + } + } else if (other.type == null) { + if (type != null && !type.isJavaLangObject()) { + return false; + } + } else if (!type.equals(other.type)) { return false; } return super.equals(other); diff -r 5c350399111e -r 7abe84b97eaa graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java Mon Jul 20 17:01:45 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java Mon Jul 20 11:21:28 2015 -0700 @@ -38,6 +38,7 @@ import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.Plugins; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.hotspot.nodes.type.*; import com.oracle.graal.hotspot.word.*; import com.oracle.graal.phases.util.*; import com.oracle.graal.replacements.amd64.*; @@ -76,7 +77,7 @@ try (InitTimer rt = timer("create Lowerer provider")) { lowerer = createLowerer(runtime, metaAccess, foreignCalls, registers, target); } - HotSpotStampProvider stampProvider = new HotSpotStampProvider(); + HotSpotStampProvider stampProvider = new HotSpotStampProvider(target.wordKind); Providers p = new Providers(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, null, stampProvider); try (InitTimer rt = timer("create SnippetReflection provider")) { @@ -86,7 +87,7 @@ replacements = createReplacements(runtime, p, snippetReflection); } try (InitTimer rt = timer("create WordTypes")) { - wordTypes = new HotSpotWordTypes(metaAccess, target.wordKind); + wordTypes = new HotSpotWordTypes(metaAccess, target.wordKind, stampProvider.createHubStamp(false), MethodPointerStamp.method()); } try (InitTimer rt = timer("create GraphBuilderPhase plugins")) { plugins = createGraphBuilderPlugins(runtime, target, constantReflection, foreignCalls, metaAccess, snippetReflection, replacements, wordTypes, stampProvider); @@ -167,15 +168,15 @@ } else { /* * System V Application Binary Interface, AMD64 Architecture Processor Supplement - * + * * Draft Version 0.96 - * + * * http://www.uclibc.org/docs/psABI-x86_64.pdf - * + * * 3.2.1 - * + * * ... - * + * * This subsection discusses usage of each register. Registers %rbp, %rbx and %r12 * through %r15 "belong" to the calling function and the called function is required to * preserve their values. In other words, a called function must preserve these diff -r 5c350399111e -r 7abe84b97eaa graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java Mon Jul 20 17:01:45 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java Mon Jul 20 11:21:28 2015 -0700 @@ -35,6 +35,7 @@ import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.Plugins; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.hotspot.nodes.type.*; import com.oracle.graal.hotspot.word.*; import com.oracle.graal.java.*; import com.oracle.graal.nodes.spi.*; @@ -56,11 +57,11 @@ Value[] nativeABICallerSaveRegisters = createNativeABICallerSaveRegisters(runtime.getConfig(), codeCache.getRegisterConfig()); HotSpotForeignCallsProvider foreignCalls = new SPARCHotSpotForeignCallsProvider(runtime, metaAccess, codeCache, nativeABICallerSaveRegisters); LoweringProvider lowerer = createLowerer(runtime, metaAccess, foreignCalls, registers, target); - HotSpotStampProvider stampProvider = new HotSpotStampProvider(); + HotSpotStampProvider stampProvider = new HotSpotStampProvider(codeCache.getTarget().wordKind); Providers p = new Providers(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, null, stampProvider); HotSpotSnippetReflectionProvider snippetReflection = new HotSpotSnippetReflectionProvider(runtime); HotSpotReplacementsImpl replacements = new HotSpotReplacementsImpl(p, snippetReflection, runtime.getConfig(), target); - HotSpotWordTypes wordTypes = new HotSpotWordTypes(metaAccess, target.wordKind); + HotSpotWordTypes wordTypes = new HotSpotWordTypes(metaAccess, target.wordKind, stampProvider.createHubStamp(false), MethodPointerStamp.method()); Plugins plugins = createGraphBuilderPlugins(runtime, metaAccess, constantReflection, foreignCalls, stampProvider, snippetReflection, replacements, wordTypes); replacements.setGraphBuilderPlugins(plugins); HotSpotSuitesProvider suites = createSuites(runtime, plugins, codeCache); diff -r 5c350399111e -r 7abe84b97eaa graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java Mon Jul 20 17:01:45 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java Mon Jul 20 11:21:28 2015 -0700 @@ -274,7 +274,7 @@ ResolvedJavaType receiverType = invoke.getReceiverType(); if (hsMethod.isInVirtualMethodTable(receiverType)) { Kind wordKind = runtime.getTarget().wordKind; - ValueNode hub = createReadHub(graph, receiver, receiverNullCheck); + ValueNode hub = createReadHub(graph, receiver, receiverNullCheck, tool); ReadNode metaspaceMethod = createReadVirtualMethod(graph, hub, hsMethod, receiverType); // We use LocationNode.ANY_LOCATION for the reads that access the @@ -332,13 +332,13 @@ } @Override - protected ValueNode createReadArrayComponentHub(StructuredGraph graph, ValueNode arrayHub, FixedNode anchor) { + protected ValueNode createReadArrayComponentHub(StructuredGraph graph, ValueNode arrayHub, FixedNode anchor, LoweringTool tool) { /* * Anchor the read of the element klass to the cfg, because it is only valid when arrayClass * is an object class, which might not be the case in other parts of the compiled method. */ AddressNode address = createOffsetAddress(graph, arrayHub, runtime.getConfig().arrayClassElementOffset); - return graph.unique(new FloatingReadNode(address, OBJ_ARRAY_KLASS_ELEMENT_KLASS_LOCATION, null, KlassPointerStamp.klassNonNull(), AbstractBeginNode.prevBegin(anchor))); + return graph.unique(new FloatingReadNode(address, OBJ_ARRAY_KLASS_ELEMENT_KLASS_LOCATION, null, tool.getStampProvider().createHubStamp(true), AbstractBeginNode.prevBegin(anchor))); } @Override @@ -485,11 +485,14 @@ } @Override - protected ValueNode createReadHub(StructuredGraph graph, ValueNode object, GuardingNode guard) { + protected ValueNode createReadHub(StructuredGraph graph, ValueNode object, GuardingNode guard, LoweringTool tool) { + if (tool.getLoweringStage() != LoweringTool.StandardLoweringStage.LOW_TIER) { + return graph.unique(new LoadHubNode(tool.getStampProvider(), object, guard != null ? guard.asNode() : null)); + } HotSpotVMConfig config = runtime.getConfig(); assert !object.isConstant() || object.isNullConstant(); - KlassPointerStamp hubStamp = KlassPointerStamp.klassNonNull(); + KlassPointerStamp hubStamp = (KlassPointerStamp) tool.getStampProvider().createHubStamp(true); if (config.useCompressedClassPointers) { hubStamp = hubStamp.compressed(config.getKlassEncoding()); } diff -r 5c350399111e -r 7abe84b97eaa graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotProviders.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotProviders.java Mon Jul 20 17:01:45 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotProviders.java Mon Jul 20 11:21:28 2015 -0700 @@ -47,7 +47,7 @@ public HotSpotProviders(MetaAccessProvider metaAccess, HotSpotCodeCacheProvider codeCache, ConstantReflectionProvider constantReflection, HotSpotForeignCallsProvider foreignCalls, LoweringProvider lowerer, Replacements replacements, SuitesProvider suites, HotSpotRegistersProvider registers, SnippetReflectionProvider snippetReflection, HotSpotWordTypes wordTypes, Plugins graphBuilderPlugins) { - super(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, new HotSpotStampProvider()); + super(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, new HotSpotStampProvider(codeCache.getTarget().wordKind)); this.suites = suites; this.registers = registers; this.snippetReflection = snippetReflection; diff -r 5c350399111e -r 7abe84b97eaa graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotStampProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotStampProvider.java Mon Jul 20 17:01:45 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotStampProvider.java Mon Jul 20 11:21:28 2015 -0700 @@ -22,17 +22,43 @@ */ package com.oracle.graal.hotspot.meta; +import jdk.internal.jvmci.meta.*; + import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.hotspot.nodes.type.*; import com.oracle.graal.nodes.spi.*; public class HotSpotStampProvider implements StampProvider { + private final KlassPointerStamp klassStamp; + + private final KlassPointerStamp klassNonNullStamp; + + @SuppressWarnings("unused") private final Kind wordKind; + + public HotSpotStampProvider(Kind wordKind) { + this.wordKind = wordKind; + klassStamp = new KlassPointerStamp(false, false, wordKind); + klassNonNullStamp = new KlassPointerStamp(true, false, wordKind); + } + + public KlassPointerStamp klass() { + return klassStamp; + } + + public KlassPointerStamp klassNonNull() { + return klassNonNullStamp; + } + public Stamp createHubStamp(ObjectStamp object) { - return KlassPointerStamp.klassNonNull(); + return klassNonNull(); } public Stamp createMethodStamp() { return MethodPointerStamp.methodNonNull(); } + + public Stamp createHubStamp(boolean nonNull) { + return nonNull ? klassNonNullStamp : klassStamp; + } } diff -r 5c350399111e -r 7abe84b97eaa graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotWordOperationPlugin.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotWordOperationPlugin.java Mon Jul 20 17:01:45 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotWordOperationPlugin.java Mon Jul 20 11:21:28 2015 -0700 @@ -43,17 +43,21 @@ import com.oracle.graal.nodes.memory.address.*; import com.oracle.graal.nodes.type.*; import com.oracle.graal.replacements.*; -import com.oracle.graal.word.*; /** * Extends {@link WordOperationPlugin} to handle {@linkplain HotSpotOperation HotSpot word * operations}. */ class HotSpotWordOperationPlugin extends WordOperationPlugin { - public HotSpotWordOperationPlugin(SnippetReflectionProvider snippetReflection, WordTypes wordTypes) { + + public HotSpotWordOperationPlugin(SnippetReflectionProvider snippetReflection, HotSpotWordTypes wordTypes) { super(snippetReflection, wordTypes); } + HotSpotWordTypes wordTypes() { + return (HotSpotWordTypes) wordTypes; + } + @Override protected LoadIndexedNode createLoadIndexedNode(ValueNode array, ValueNode index) { ResolvedJavaType arrayType = StampTool.typeOrNull(array); @@ -115,17 +119,17 @@ case TO_KLASS_POINTER: assert args.length == 1; - b.addPush(returnKind, new PointerCastNode(KlassPointerStamp.klass(), args[0])); + b.addPush(returnKind, new PointerCastNode(wordTypes().getKlassPointerStamp(), args[0])); break; case TO_METHOD_POINTER: assert args.length == 1; - b.addPush(returnKind, new PointerCastNode(MethodPointerStamp.method(), args[0])); + b.addPush(returnKind, new PointerCastNode(wordTypes().getMethodPointerStamp(), args[0])); break; case READ_KLASS_POINTER: assert args.length == 2 || args.length == 3; - Stamp readStamp = KlassPointerStamp.klass(); + Stamp readStamp = wordTypes().getKlassPointerStamp(); AddressNode address = makeAddress(b, args[0], args[1]); LocationIdentity location; if (args.length == 2) { diff -r 5c350399111e -r 7abe84b97eaa graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CompressionNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CompressionNode.java Mon Jul 20 17:01:45 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CompressionNode.java Mon Jul 20 11:21:28 2015 -0700 @@ -69,6 +69,10 @@ return input.graph().unique(new CompressionNode(CompressionOp.Compress, input, encoding)); } + public static CompressionNode compressNoUnique(ValueNode input, CompressEncoding encoding) { + return new CompressionNode(CompressionOp.Compress, input, encoding); + } + public static CompressionNode uncompress(ValueNode input, CompressEncoding encoding) { return input.graph().unique(new CompressionNode(CompressionOp.Uncompress, input, encoding)); } diff -r 5c350399111e -r 7abe84b97eaa graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/type/KlassPointerStamp.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/type/KlassPointerStamp.java Mon Jul 20 17:01:45 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/type/KlassPointerStamp.java Mon Jul 20 11:21:28 2015 -0700 @@ -33,34 +33,23 @@ public final class KlassPointerStamp extends MetaspacePointerStamp { - private static final KlassPointerStamp KLASS = new KlassPointerStamp(false, false); - - private static final KlassPointerStamp KLASS_NON_NULL = new KlassPointerStamp(true, false); - - private static final KlassPointerStamp KLASS_ALWAYS_NULL = new KlassPointerStamp(false, true); - private final CompressEncoding encoding; - public static KlassPointerStamp klass() { - return KLASS; + private final Kind kind; + + public KlassPointerStamp(boolean nonNull, boolean alwaysNull, Kind kind) { + this(nonNull, alwaysNull, null, kind); } - public static KlassPointerStamp klassNonNull() { - return KLASS_NON_NULL; - } - - private KlassPointerStamp(boolean nonNull, boolean alwaysNull) { - this(nonNull, alwaysNull, null); - } - - private KlassPointerStamp(boolean nonNull, boolean alwaysNull, CompressEncoding encoding) { + private KlassPointerStamp(boolean nonNull, boolean alwaysNull, CompressEncoding encoding, Kind kind) { super(nonNull, alwaysNull); this.encoding = encoding; + this.kind = kind; } @Override protected AbstractPointerStamp copyWith(boolean newNonNull, boolean newAlwaysNull) { - return new KlassPointerStamp(newNonNull, newAlwaysNull, encoding); + return new KlassPointerStamp(newNonNull, newAlwaysNull, encoding, kind); } @Override @@ -79,23 +68,20 @@ public Stamp constant(Constant c, MetaAccessProvider meta) { if (isCompressed()) { if (HotSpotCompressedNullConstant.COMPRESSED_NULL.equals(c)) { - return new KlassPointerStamp(false, true, encoding); + return new KlassPointerStamp(false, true, encoding, kind); } } else { if (JavaConstant.NULL_POINTER.equals(c)) { - return KLASS_ALWAYS_NULL; + return new KlassPointerStamp(false, true, encoding, kind); } } assert c instanceof HotSpotMetaspaceConstant; + assert ((HotSpotMetaspaceConstant) c).isCompressed() == isCompressed(); if (nonNull()) { return this; } - if (isCompressed()) { - return new KlassPointerStamp(true, false, encoding); - } else { - return KLASS_NON_NULL; - } + return new KlassPointerStamp(true, false, encoding, kind); } @Override @@ -126,12 +112,12 @@ public KlassPointerStamp compressed(CompressEncoding newEncoding) { assert !isCompressed(); - return new KlassPointerStamp(nonNull(), alwaysNull(), newEncoding); + return new KlassPointerStamp(nonNull(), alwaysNull(), newEncoding, Kind.Int); } public KlassPointerStamp uncompressed() { assert isCompressed(); - return new KlassPointerStamp(nonNull(), alwaysNull()); + return new KlassPointerStamp(nonNull(), alwaysNull(), Kind.Long); } @Override @@ -176,4 +162,9 @@ } return ret.toString(); } + + @Override + public Kind getStackKind() { + return isCompressed() ? Kind.Int : Kind.Long; + } } diff -r 5c350399111e -r 7abe84b97eaa graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/LoadJavaMirrorWithKlassPhase.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/LoadJavaMirrorWithKlassPhase.java Mon Jul 20 17:01:45 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/LoadJavaMirrorWithKlassPhase.java Mon Jul 20 11:21:28 2015 -0700 @@ -70,7 +70,7 @@ Stamp stamp = StampFactory.exactNonNull(metaAccess.lookupJavaType(Class.class)); if (type instanceof HotSpotResolvedObjectType) { - ConstantNode klass = ConstantNode.forConstant(KlassPointerStamp.klassNonNull(), ((HotSpotResolvedObjectType) type).klass(), metaAccess, graph); + ConstantNode klass = ConstantNode.forConstant(context.getStampProvider().createHubStamp(true), ((HotSpotResolvedObjectType) type).klass(), metaAccess, graph); AddressNode address = graph.unique(new OffsetAddressNode(klass, ConstantNode.forLong(classMirrorOffset, graph))); ValueNode read = graph.unique(new FloatingReadNode(address, CLASS_MIRROR_LOCATION, null, stamp)); diff -r 5c350399111e -r 7abe84b97eaa graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ClassGetHubNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ClassGetHubNode.java Mon Jul 20 17:01:45 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ClassGetHubNode.java Mon Jul 20 11:21:28 2015 -0700 @@ -28,7 +28,6 @@ import com.oracle.graal.compiler.common.calc.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; -import com.oracle.graal.hotspot.nodes.type.*; import com.oracle.graal.hotspot.word.*; import com.oracle.graal.nodeinfo.*; import com.oracle.graal.nodes.*; @@ -48,14 +47,16 @@ public final class ClassGetHubNode extends FloatingGuardedNode implements Lowerable, Canonicalizable, ConvertNode { public static final NodeClass TYPE = NodeClass.create(ClassGetHubNode.class); @Input protected ValueNode clazz; + StampProvider stampProvider; - public ClassGetHubNode(ValueNode clazz) { - this(clazz, null); + public ClassGetHubNode(@InjectedNodeParameter StampProvider stampProvider, ValueNode clazz) { + this(stampProvider, clazz, null); } - public ClassGetHubNode(ValueNode clazz, ValueNode guard) { - super(TYPE, KlassPointerStamp.klass(), (GuardingNode) guard); + public ClassGetHubNode(@InjectedNodeParameter StampProvider stampProvider, ValueNode clazz, ValueNode guard) { + super(TYPE, stampProvider.createHubStamp(false), (GuardingNode) guard); this.clazz = clazz; + this.stampProvider = stampProvider; } @Override @@ -78,7 +79,7 @@ } if (clazz instanceof GetClassNode) { GetClassNode getClass = (GetClassNode) clazz; - return new LoadHubNode(KlassPointerStamp.klassNonNull(), getClass.getObject(), null); + return new LoadHubNode(stampProvider, getClass.getObject(), null); } if (clazz instanceof HubGetClassNode) { // replace _klass._java_mirror._klass -> _klass diff -r 5c350399111e -r 7abe84b97eaa graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java Mon Jul 20 17:01:45 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java Mon Jul 20 11:21:28 2015 -0700 @@ -22,22 +22,29 @@ */ package com.oracle.graal.hotspot.replacements; -import jdk.internal.jvmci.code.*; -import jdk.internal.jvmci.common.*; -import jdk.internal.jvmci.hotspot.*; -import jdk.internal.jvmci.meta.*; import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; import static com.oracle.graal.hotspot.meta.HotSpotForeignCallsProviderImpl.*; import static com.oracle.graal.nodes.extended.BranchProbabilityNode.*; import static jdk.internal.jvmci.common.UnsafeAccess.*; +import jdk.internal.jvmci.code.*; +import jdk.internal.jvmci.common.*; +import jdk.internal.jvmci.hotspot.*; +import jdk.internal.jvmci.meta.Assumptions.AssumptionResult; +import jdk.internal.jvmci.meta.*; import com.oracle.graal.api.replacements.*; import com.oracle.graal.compiler.common.*; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.Node.ConstantNodeParameter; import com.oracle.graal.graph.Node.NodeIntrinsic; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.hotspot.nodes.*; import com.oracle.graal.hotspot.word.*; +import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.memory.*; +import com.oracle.graal.nodes.memory.address.*; +import com.oracle.graal.nodes.type.*; import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.nodes.*; import com.oracle.graal.word.*; @@ -49,6 +56,60 @@ */ public class HotSpotReplacementsUtil { + abstract static class HotSpotOptimizingLocationIdentity extends NamedLocationIdentity implements CanonicalizableLocation { + + HotSpotOptimizingLocationIdentity(String name) { + super(name, true); + } + + @Override + public abstract ValueNode canonicalizeRead(ValueNode read, AddressNode location, ValueNode object, CanonicalizerTool tool); + + protected ValueNode findReadHub(ValueNode object) { + ValueNode base = object; + if (base instanceof CompressionNode) { + base = ((CompressionNode) base).getValue(); + } + if (base instanceof Access) { + Access access = (Access) base; + if (access.getLocationIdentity().equals(HUB_LOCATION)) { + AddressNode address = access.getAddress(); + if (address instanceof OffsetAddressNode) { + OffsetAddressNode offset = (OffsetAddressNode) address; + return offset.getBase(); + } + } + } else if (base instanceof LoadHubNode) { + LoadHubNode loadhub = (LoadHubNode) base; + return loadhub.getValue(); + } + return null; + } + + /** + * Fold reads that convert from Class -> Hub -> Class or vice versa. + * + * @param read + * @param object + * @param otherLocation + * @return an earlier read or the original {@code read} + */ + protected static ValueNode foldIndirection(ValueNode read, ValueNode object, LocationIdentity otherLocation) { + if (object instanceof Access) { + Access access = (Access) object; + if (access.getLocationIdentity().equals(otherLocation)) { + AddressNode address = access.getAddress(); + if (address instanceof OffsetAddressNode) { + OffsetAddressNode offset = (OffsetAddressNode) address; + assert offset.getBase().stamp().isCompatible(read.stamp()); + return offset.getBase(); + } + } + } + return read; + } + } + @Fold public static HotSpotVMConfig config() { return runtime().getConfig(); @@ -296,7 +357,23 @@ return config().jvmAccWrittenFlags; } - public static final LocationIdentity KLASS_LAYOUT_HELPER_LOCATION = NamedLocationIdentity.immutable("Klass::_layout_helper"); + public static final LocationIdentity KLASS_LAYOUT_HELPER_LOCATION = new HotSpotOptimizingLocationIdentity("Klass::_layout_helper") { + @Override + public ValueNode canonicalizeRead(ValueNode read, AddressNode location, ValueNode object, CanonicalizerTool tool) { + ValueNode javaObject = findReadHub(object); + if (javaObject != null) { + if (javaObject.stamp() instanceof ObjectStamp) { + ObjectStamp stamp = (ObjectStamp) javaObject.stamp(); + HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) stamp.javaType(tool.getMetaAccess()); + if (type.isArray() && !type.getComponentType().isPrimitive()) { + int layout = ((HotSpotResolvedObjectTypeImpl) type).layoutHelper(); + return ConstantNode.forInt(layout); + } + } + } + return read; + } + }; @Fold public static int klassLayoutHelperOffset() { @@ -356,7 +433,20 @@ public static final LocationIdentity HUB_WRITE_LOCATION = NamedLocationIdentity.mutable("Hub:write"); - public static final LocationIdentity HUB_LOCATION = NamedLocationIdentity.immutable("Hub"); + public static final LocationIdentity HUB_LOCATION = new HotSpotOptimizingLocationIdentity("Hub") { + @Override + public ValueNode canonicalizeRead(ValueNode read, AddressNode location, ValueNode object, CanonicalizerTool tool) { + ResolvedJavaType constantType = LoadHubNode.findSynonymType(read.graph(), tool.getMetaAccess(), object); + if (constantType != null) { + if (config().useCompressedClassPointers) { + return ConstantNode.forConstant(read.stamp(), ((HotSpotMetaspaceConstant) constantType.getObjectHub()).compress(config().getKlassEncoding()), tool.getMetaAccess()); + } else { + return ConstantNode.forConstant(read.stamp(), constantType.getObjectHub(), tool.getMetaAccess()); + } + } + return read; + } + }; @Fold private static int hubOffset() { @@ -578,6 +668,11 @@ return loadWordFromObjectIntrinsic(object, offset, getWordKind(), identity); } + public static KlassPointer loadKlassFromObject(Object object, int offset, LocationIdentity identity) { + ReplacementsUtil.staticAssert(offset != hubOffset(), "Use loadHubIntrinsic instead of loadWordFromObject"); + return loadKlassFromObjectIntrinsic(object, offset, getWordKind(), identity); + } + /** * Reads the value of a given register. * @@ -597,6 +692,9 @@ @NodeIntrinsic(value = UnsafeLoadNode.class, setStampFromReturnType = true) private static native Word loadWordFromObjectIntrinsic(Object object, long offset, @ConstantNodeParameter Kind wordKind, @ConstantNodeParameter LocationIdentity locationIdentity); + @NodeIntrinsic(value = UnsafeLoadNode.class, setStampFromReturnType = true) + private static native KlassPointer loadKlassFromObjectIntrinsic(Object object, long offset, @ConstantNodeParameter Kind wordKind, @ConstantNodeParameter LocationIdentity locationIdentity); + @NodeIntrinsic(value = LoadHubNode.class) public static native KlassPointer loadHubIntrinsic(Object object, GuardingNode anchor); @@ -647,14 +745,24 @@ return config().klassModifierFlagsOffset; } - public static final LocationIdentity CLASS_KLASS_LOCATION = NamedLocationIdentity.immutable("Class._klass"); + public static final LocationIdentity CLASS_KLASS_LOCATION = new HotSpotOptimizingLocationIdentity("Class._klass") { + @Override + public ValueNode canonicalizeRead(ValueNode read, AddressNode location, ValueNode object, CanonicalizerTool tool) { + return foldIndirection(read, object, CLASS_MIRROR_LOCATION); + } + }; @Fold public static int klassOffset() { return config().klassOffset; } - public static final LocationIdentity CLASS_ARRAY_KLASS_LOCATION = NamedLocationIdentity.mutable("Class._array_klass"); + public static final LocationIdentity CLASS_ARRAY_KLASS_LOCATION = new HotSpotOptimizingLocationIdentity("Class._array_klass") { + @Override + public ValueNode canonicalizeRead(ValueNode read, AddressNode location, ValueNode object, CanonicalizerTool tool) { + return foldIndirection(read, object, ARRAY_KLASS_COMPONENT_MIRROR); + } + }; @Fold public static int arrayKlassOffset() { @@ -846,7 +954,26 @@ } } - public static final LocationIdentity OBJ_ARRAY_KLASS_ELEMENT_KLASS_LOCATION = NamedLocationIdentity.immutable("ObjArrayKlass::_element_klass"); + public static final LocationIdentity OBJ_ARRAY_KLASS_ELEMENT_KLASS_LOCATION = new HotSpotOptimizingLocationIdentity("ObjArrayKlass::_element_klass") { + @Override + public ValueNode canonicalizeRead(ValueNode read, AddressNode location, ValueNode object, CanonicalizerTool tool) { + ValueNode javaObject = findReadHub(object); + if (javaObject != null) { + ResolvedJavaType type = StampTool.typeOrNull(javaObject); + if (type != null && type.isArray()) { + ResolvedJavaType element = type.getComponentType(); + if (element != null && !element.isPrimitive() && !element.getElementalType().isInterface()) { + AssumptionResult leafType = element.findLeafConcreteSubtype(); + if (leafType != null) { + object.graph().getAssumptions().record(leafType); + return ConstantNode.forConstant(read.stamp(), leafType.getResult().getObjectHub(), tool.getMetaAccess()); + } + } + } + } + return read; + } + }; @Fold public static int arrayClassElementOffset() { diff -r 5c350399111e -r 7abe84b97eaa graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java Mon Jul 20 17:01:45 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java Mon Jul 20 11:21:28 2015 -0700 @@ -37,7 +37,6 @@ import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.nodes.*; -import com.oracle.graal.hotspot.nodes.type.*; import com.oracle.graal.hotspot.replacements.TypeCheckSnippetUtils.Hints; import com.oracle.graal.hotspot.word.*; import com.oracle.graal.nodes.*; @@ -229,38 +228,39 @@ @Override protected Arguments makeArguments(InstanceOfUsageReplacer replacer, LoweringTool tool) { + Stamp hubStamp = tool.getStampProvider().createHubStamp(true); if (replacer.instanceOf instanceof InstanceOfNode) { InstanceOfNode instanceOf = (InstanceOfNode) replacer.instanceOf; ValueNode object = instanceOf.getValue(); Assumptions assumptions = instanceOf.graph().getAssumptions(); TypeCheckHints hintInfo = new TypeCheckHints(instanceOf.type(), instanceOf.profile(), assumptions, TypeCheckMinProfileHitProbability.getValue(), TypeCheckMaxHints.getValue()); final HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) instanceOf.type(); - ConstantNode hub = ConstantNode.forConstant(KlassPointerStamp.klassNonNull(), type.klass(), providers.getMetaAccess(), instanceOf.graph()); + ConstantNode hub = ConstantNode.forConstant(hubStamp, type.klass(), providers.getMetaAccess(), instanceOf.graph()); Arguments args; StructuredGraph graph = instanceOf.graph(); if (hintInfo.hintHitProbability >= 1.0 && hintInfo.exact == null) { - Hints hints = createHints(hintInfo, providers.getMetaAccess(), false, graph); + Hints hints = createHints(hintInfo, providers.getMetaAccess(), false, graph, tool); args = new Arguments(instanceofWithProfile, graph.getGuardsStage(), tool.getLoweringStage()); args.add("object", object); - args.addVarargs("hints", KlassPointer.class, KlassPointerStamp.klassNonNull(), hints.hubs); + args.addVarargs("hints", KlassPointer.class, hubStamp, hints.hubs); args.addVarargs("hintIsPositive", boolean.class, StampFactory.forKind(Kind.Boolean), hints.isPositive); } else if (hintInfo.exact != null) { args = new Arguments(instanceofExact, graph.getGuardsStage(), tool.getLoweringStage()); args.add("object", object); - args.add("exactHub", ConstantNode.forConstant(KlassPointerStamp.klassNonNull(), ((HotSpotResolvedObjectType) hintInfo.exact).klass(), providers.getMetaAccess(), graph)); + args.add("exactHub", ConstantNode.forConstant(hubStamp, ((HotSpotResolvedObjectType) hintInfo.exact).klass(), providers.getMetaAccess(), graph)); } else if (type.isPrimaryType()) { args = new Arguments(instanceofPrimary, graph.getGuardsStage(), tool.getLoweringStage()); args.add("hub", hub); args.add("object", object); args.addConst("superCheckOffset", type.superCheckOffset()); } else { - Hints hints = createHints(hintInfo, providers.getMetaAccess(), false, graph); + Hints hints = createHints(hintInfo, providers.getMetaAccess(), false, graph, tool); args = new Arguments(instanceofSecondary, graph.getGuardsStage(), tool.getLoweringStage()); args.add("hub", hub); args.add("object", object); - args.addVarargs("hints", KlassPointer.class, KlassPointerStamp.klassNonNull(), hints.hubs); + args.addVarargs("hints", KlassPointer.class, hubStamp, hints.hubs); args.addVarargs("hintIsPositive", boolean.class, StampFactory.forKind(Kind.Boolean), hints.isPositive); } args.add("trueValue", replacer.trueValue); @@ -275,7 +275,7 @@ ValueNode object = typeCheck.getValue(); Arguments args = new Arguments(instanceofExact, typeCheck.graph().getGuardsStage(), tool.getLoweringStage()); args.add("object", object); - args.add("exactHub", ConstantNode.forConstant(KlassPointerStamp.klassNonNull(), ((HotSpotResolvedObjectType) typeCheck.type()).klass(), providers.getMetaAccess(), typeCheck.graph())); + args.add("exactHub", ConstantNode.forConstant(hubStamp, ((HotSpotResolvedObjectType) typeCheck.type()).klass(), providers.getMetaAccess(), typeCheck.graph())); args.add("trueValue", replacer.trueValue); args.add("falseValue", replacer.falseValue); return args; diff -r 5c350399111e -r 7abe84b97eaa graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java Mon Jul 20 17:01:45 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java Mon Jul 20 11:21:28 2015 -0700 @@ -47,7 +47,6 @@ import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.nodes.*; -import com.oracle.graal.hotspot.nodes.type.*; import com.oracle.graal.hotspot.word.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.debug.*; @@ -197,7 +196,8 @@ @Snippet public static Object allocateArray(KlassPointer hub, int length, Word prototypeMarkWord, @ConstantParameter int headerSize, @ConstantParameter int log2ElementSize, @ConstantParameter boolean fillContents, @ConstantParameter Register threadRegister, @ConstantParameter boolean maybeUnroll, @ConstantParameter String typeContext) { - return allocateArrayImpl(hub, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents, threadRegister, maybeUnroll, typeContext, false); + Object result = allocateArrayImpl(hub, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents, threadRegister, maybeUnroll, typeContext, false); + return piArrayCast(verifyOop(result), length, StampFactory.forNodeIntrinsic()); } private static Object allocateArrayImpl(KlassPointer hub, int length, Word prototypeMarkWord, int headerSize, int log2ElementSize, boolean fillContents, @@ -219,7 +219,7 @@ result = newArray(HotSpotBackend.NEW_ARRAY, hub, length); } profileAllocation("array", allocationSize, typeContext); - return piArrayCast(verifyOop(result), length, StampFactory.forNodeIntrinsic()); + return result; } @NodeIntrinsic(ForeignCallNode.class) @@ -240,7 +240,12 @@ @Snippet public static Object allocateArrayDynamic(Class elementType, int length, @ConstantParameter boolean fillContents, @ConstantParameter Register threadRegister, - @ConstantParameter Kind knownElementKind) { + @ConstantParameter Kind knownElementKind, @ConstantParameter int knownLayoutHelper, Word prototypeMarkWord) { + Object result = allocateArrayDynamicImpl(elementType, length, fillContents, threadRegister, knownElementKind, knownLayoutHelper, prototypeMarkWord); + return result; + } + + private static Object allocateArrayDynamicImpl(Class elementType, int length, boolean fillContents, Register threadRegister, Kind knownElementKind, int knownLayoutHelper, Word prototypeMarkWord) { /* * We only need the dynamic check for void when we have no static information from * knownElementKind. @@ -250,13 +255,11 @@ DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint); } - Word hub = loadWordFromObject(elementType, arrayKlassOffset(), CLASS_ARRAY_KLASS_LOCATION); - if (probability(BranchProbabilityNode.NOT_FREQUENT_PROBABILITY, hub.equal(Word.zero()) || !belowThan(length, MAX_ARRAY_FAST_PATH_ALLOCATION_LENGTH))) { - return dynamicNewArrayStub(DYNAMIC_NEW_ARRAY, elementType, length); + KlassPointer klass = loadKlassFromObject(elementType, arrayKlassOffset(), CLASS_ARRAY_KLASS_LOCATION); + if (probability(BranchProbabilityNode.NOT_FREQUENT_PROBABILITY, klass.isNull() || length < 0)) { + DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint); } - - KlassPointer klass = KlassPointer.fromWord(hub); - int layoutHelper = readLayoutHelper(klass); + int layoutHelper = knownElementKind != Kind.Illegal ? knownLayoutHelper : readLayoutHelper(klass); //@formatter:off // from src/share/vm/oops/klass.hpp: // @@ -272,9 +275,9 @@ int headerSize = (layoutHelper >> layoutHelperHeaderSizeShift()) & layoutHelperHeaderSizeMask(); int log2ElementSize = (layoutHelper >> layoutHelperLog2ElementSizeShift()) & layoutHelperLog2ElementSizeMask(); - Word prototypeMarkWord = hub.readWord(prototypeMarkWordOffset(), PROTOTYPE_MARK_WORD_LOCATION); - return allocateArrayImpl(klass, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents, threadRegister, false, "dynamic type", true); + Object result = allocateArrayImpl(klass, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents, threadRegister, false, "dynamic type", true); + return piArrayCast(verifyOop(result), length, StampFactory.forNodeIntrinsic()); } /** @@ -445,7 +448,7 @@ StructuredGraph graph = newInstanceNode.graph(); HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) newInstanceNode.instanceClass(); assert !type.isArray(); - ConstantNode hub = ConstantNode.forConstant(KlassPointerStamp.klassNonNull(), type.klass(), providers.getMetaAccess(), graph); + ConstantNode hub = ConstantNode.forConstant(tool.getStampProvider().createHubStamp(true), type.klass(), providers.getMetaAccess(), graph); int size = instanceSize(type); Arguments args = new Arguments(allocateInstance, graph.getGuardsStage(), tool.getLoweringStage()); @@ -470,7 +473,7 @@ ResolvedJavaType elementType = newArrayNode.elementType(); HotSpotResolvedObjectType arrayType = (HotSpotResolvedObjectType) elementType.getArrayClass(); Kind elementKind = elementType.getKind(); - ConstantNode hub = ConstantNode.forConstant(KlassPointerStamp.klassNonNull(), arrayType.klass(), providers.getMetaAccess(), graph); + ConstantNode hub = ConstantNode.forConstant(tool.getStampProvider().createHubStamp(true), arrayType.klass(), providers.getMetaAccess(), graph); final int headerSize = runtime.getJVMCIRuntime().getArrayBaseOffset(elementKind); HotSpotLoweringProvider lowerer = (HotSpotLoweringProvider) providers.getLowerer(); int log2ElementSize = CodeUtil.log2(lowerer.arrayScalingFactor(elementKind)); @@ -479,6 +482,7 @@ args.add("hub", hub); ValueNode length = newArrayNode.length(); args.add("length", length.isAlive() ? length : graph.addOrUniqueWithInputs(length)); + assert arrayType.prototypeMarkWord() == lookupArrayClass(tool, Kind.Object).prototypeMarkWord() : "all array types are assumed to have the same prototypeMarkWord"; args.add("prototypeMarkWord", arrayType.prototypeMarkWord()); args.addConst("headerSize", headerSize); args.addConst("log2ElementSize", log2ElementSize); @@ -515,11 +519,20 @@ * parameters cannot be null. */ args.addConst("knownElementKind", newArrayNode.getKnownElementKind() == null ? Kind.Illegal : newArrayNode.getKnownElementKind()); - + if (newArrayNode.getKnownElementKind() != null) { + args.addConst("knownLayoutHelper", lookupArrayClass(tool, newArrayNode.getKnownElementKind()).layoutHelper()); + } else { + args.addConst("knownLayoutHelper", 0); + } + args.add("prototypeMarkWord", lookupArrayClass(tool, Kind.Object).prototypeMarkWord()); SnippetTemplate template = template(args); template.instantiate(providers.getMetaAccess(), newArrayNode, DEFAULT_REPLACER, args); } + private static HotSpotResolvedObjectType lookupArrayClass(LoweringTool tool, Kind kind) { + return (HotSpotResolvedObjectType) tool.getMetaAccess().lookupJavaType(kind == Kind.Object ? Object.class : kind.toJavaClass()).getArrayClass(); + } + public void lower(NewMultiArrayNode newmultiarrayNode, LoweringTool tool) { StructuredGraph graph = newmultiarrayNode.graph(); int rank = newmultiarrayNode.dimensionCount(); @@ -528,7 +541,7 @@ dims[i] = newmultiarrayNode.dimension(i); } HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) newmultiarrayNode.type(); - ConstantNode hub = ConstantNode.forConstant(KlassPointerStamp.klassNonNull(), type.klass(), providers.getMetaAccess(), graph); + ConstantNode hub = ConstantNode.forConstant(tool.getStampProvider().createHubStamp(true), type.klass(), providers.getMetaAccess(), graph); Arguments args = new Arguments(newmultiarray, graph.getGuardsStage(), tool.getLoweringStage()); args.add("hub", hub); diff -r 5c350399111e -r 7abe84b97eaa graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/TypeCheckSnippetUtils.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/TypeCheckSnippetUtils.java Mon Jul 20 17:01:45 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/TypeCheckSnippetUtils.java Mon Jul 20 11:21:28 2015 -0700 @@ -32,9 +32,9 @@ import jdk.internal.jvmci.hotspot.*; import jdk.internal.jvmci.meta.*; -import com.oracle.graal.hotspot.nodes.type.*; import com.oracle.graal.hotspot.word.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.spi.*; import com.oracle.graal.replacements.*; import com.oracle.graal.word.*; @@ -122,13 +122,13 @@ } } - static Hints createHints(TypeCheckHints hints, MetaAccessProvider metaAccess, boolean positiveOnly, StructuredGraph graph) { + static Hints createHints(TypeCheckHints hints, MetaAccessProvider metaAccess, boolean positiveOnly, StructuredGraph graph, LoweringTool tool) { ConstantNode[] hubs = new ConstantNode[hints.hints.length]; boolean[] isPositive = new boolean[hints.hints.length]; int index = 0; for (int i = 0; i < hubs.length; i++) { if (!positiveOnly || hints.hints[i].positive) { - hubs[index] = ConstantNode.forConstant(KlassPointerStamp.klassNonNull(), ((HotSpotResolvedObjectType) hints.hints[i].type).klass(), metaAccess, graph); + hubs[index] = ConstantNode.forConstant(tool.getStampProvider().createHubStamp(true), ((HotSpotResolvedObjectType) hints.hints[i].type).klass(), metaAccess, graph); isPositive[index] = hints.hints[i].positive; index++; } diff -r 5c350399111e -r 7abe84b97eaa graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/arraycopy/ArrayCopySnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/arraycopy/ArrayCopySnippets.java Mon Jul 20 17:01:45 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/arraycopy/ArrayCopySnippets.java Mon Jul 20 11:21:28 2015 -0700 @@ -38,7 +38,6 @@ import com.oracle.graal.api.replacements.*; import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.meta.*; -import com.oracle.graal.hotspot.nodes.type.*; import com.oracle.graal.hotspot.word.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; @@ -525,7 +524,7 @@ } if (snippetInfo == arraycopyPredictedObjectWorkSnippet) { HotSpotResolvedObjectType arrayKlass = (HotSpotResolvedObjectType) tool.getMetaAccess().lookupJavaType(Object[].class); - ValueNode objectArrayKlass = ConstantNode.forConstant(KlassPointerStamp.klassNonNull(), arrayKlass.klass(), tool.getMetaAccess(), arraycopy.graph()); + ValueNode objectArrayKlass = ConstantNode.forConstant(tool.getStampProvider().createHubStamp(true), arrayKlass.klass(), tool.getMetaAccess(), arraycopy.graph()); args.add("objectArrayKlass", objectArrayKlass); args.addConst("counter", arraycopyCallCounters.get(Kind.Object)); args.addConst("copiedCounter", arraycopyCallCopiedCounters.get(Kind.Object)); diff -r 5c350399111e -r 7abe84b97eaa graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java Mon Jul 20 17:01:45 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java Mon Jul 20 11:21:28 2015 -0700 @@ -22,14 +22,14 @@ */ package com.oracle.graal.hotspot.stubs; -import jdk.internal.jvmci.code.*; -import jdk.internal.jvmci.hotspot.*; -import jdk.internal.jvmci.meta.*; import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; import static com.oracle.graal.hotspot.replacements.NewObjectSnippets.*; import static com.oracle.graal.hotspot.stubs.NewInstanceStub.*; import static com.oracle.graal.hotspot.stubs.StubUtil.*; import static jdk.internal.jvmci.hotspot.HotSpotMetaAccessProvider.*; +import jdk.internal.jvmci.code.*; +import jdk.internal.jvmci.hotspot.*; +import jdk.internal.jvmci.meta.*; import com.oracle.graal.api.replacements.*; import com.oracle.graal.graph.Node.ConstantNodeParameter; @@ -37,7 +37,6 @@ import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.nodes.*; -import com.oracle.graal.hotspot.nodes.type.*; import com.oracle.graal.hotspot.replacements.*; import com.oracle.graal.hotspot.word.*; import com.oracle.graal.nodes.*; @@ -64,7 +63,7 @@ Object[] args = new Object[count]; assert checkConstArg(2, "intArrayHub"); assert checkConstArg(3, "threadRegister"); - args[2] = ConstantNode.forConstant(KlassPointerStamp.klassNonNull(), intArrayType.klass(), null); + args[2] = ConstantNode.forConstant(providers.getStampProvider().createHubStamp(true), intArrayType.klass(), null); args[3] = providers.getRegisters().getThreadRegister(); return args; } diff -r 5c350399111e -r 7abe84b97eaa graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java Mon Jul 20 17:01:45 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java Mon Jul 20 11:21:28 2015 -0700 @@ -36,7 +36,6 @@ import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.nodes.*; -import com.oracle.graal.hotspot.nodes.type.*; import com.oracle.graal.hotspot.replacements.*; import com.oracle.graal.hotspot.word.*; import com.oracle.graal.nodes.*; @@ -64,7 +63,7 @@ Object[] args = new Object[count]; assert checkConstArg(1, "intArrayHub"); assert checkConstArg(2, "threadRegister"); - args[1] = ConstantNode.forConstant(KlassPointerStamp.klassNonNull(), intArrayType.klass(), null); + args[1] = ConstantNode.forConstant(providers.getStampProvider().createHubStamp(true), intArrayType.klass(), null); args[2] = providers.getRegisters().getThreadRegister(); return args; } diff -r 5c350399111e -r 7abe84b97eaa graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/word/HotSpotWordTypes.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/word/HotSpotWordTypes.java Mon Jul 20 17:01:45 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/word/HotSpotWordTypes.java Mon Jul 20 11:21:28 2015 -0700 @@ -25,7 +25,6 @@ import jdk.internal.jvmci.meta.*; import com.oracle.graal.compiler.common.type.*; -import com.oracle.graal.hotspot.nodes.type.*; import com.oracle.graal.word.*; /** @@ -48,11 +47,17 @@ */ private final ResolvedJavaType methodPointerType; - public HotSpotWordTypes(MetaAccessProvider metaAccess, Kind wordKind) { + private final Stamp klassPointerStamp; + + private final Stamp methodPointerStamp; + + public HotSpotWordTypes(MetaAccessProvider metaAccess, Kind wordKind, Stamp klassPointerStamp, Stamp methodPointerStamp) { super(metaAccess, wordKind); this.metaspacePointerType = metaAccess.lookupJavaType(MetaspacePointer.class); this.klassPointerType = metaAccess.lookupJavaType(KlassPointer.class); this.methodPointerType = metaAccess.lookupJavaType(MethodPointer.class); + this.klassPointerStamp = klassPointerStamp; + this.methodPointerStamp = methodPointerStamp; } @Override @@ -74,10 +79,18 @@ @Override public Stamp getWordStamp(ResolvedJavaType type) { if (type.equals(klassPointerType)) { - return KlassPointerStamp.klass(); + return klassPointerStamp; } else if (type.equals(methodPointerType)) { - return MethodPointerStamp.method(); + return methodPointerStamp; } return super.getWordStamp(type); } + + public Stamp getKlassPointerStamp() { + return klassPointerStamp; + } + + public Stamp getMethodPointerStamp() { + return methodPointerStamp; + } } diff -r 5c350399111e -r 7abe84b97eaa graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/CanonicalizableLocation.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/CanonicalizableLocation.java Mon Jul 20 11:21:28 2015 -0700 @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2015, 2015, 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.nodes; + +import com.oracle.graal.graph.spi.*; +import com.oracle.graal.nodes.memory.address.*; + +public interface CanonicalizableLocation { + ValueNode canonicalizeRead(ValueNode read, AddressNode location, ValueNode object, CanonicalizerTool tool); +} diff -r 5c350399111e -r 7abe84b97eaa graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java Mon Jul 20 17:01:45 2015 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java Mon Jul 20 11:21:28 2015 -0700 @@ -106,6 +106,23 @@ if (stamp().equals(object().stamp())) { return object(); } + if (getGuard() != null) { + for (Node use : getGuard().asNode().usages()) { + if (use instanceof PiNode) { + PiNode otherPi = (PiNode) use; + if (object() == otherPi.object() && stamp().equals(otherPi.stamp())) { + /* + * Two PiNodes with the same guard and same result, so return the one with + * the more precise piStamp. + */ + Stamp newStamp = piStamp.join(otherPi.piStamp); + if (newStamp.equals(otherPi.piStamp)) { + return otherPi; + } + } + } + } + } return this; } diff -r 5c350399111e -r 7abe84b97eaa graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValuePhiNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValuePhiNode.java Mon Jul 20 17:01:45 2015 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValuePhiNode.java Mon Jul 20 11:21:28 2015 -0700 @@ -25,13 +25,15 @@ import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodeinfo.*; +import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; +import com.oracle.graal.nodes.util.*; /** * Value {@link PhiNode}s merge data flow values at control flow merges. */ @NodeInfo(nameTemplate = "Phi({i#values})") -public class ValuePhiNode extends PhiNode { +public class ValuePhiNode extends PhiNode implements ArrayLengthProvider { public static final NodeClass TYPE = NodeClass.create(ValuePhiNode.class); @Input protected NodeInputList values; @@ -65,4 +67,23 @@ } return updateStamp(valuesStamp); } + + public ValueNode length() { + if (merge() instanceof LoopBeginNode) { + return null; + } + ValueNode length = null; + for (ValueNode input : values()) { + ValueNode l = GraphUtil.arrayLength(input); + if (l == null) { + return null; + } + if (length == null) { + length = l; + } else if (length != l) { + return null; + } + } + return length; + } } diff -r 5c350399111e -r 7abe84b97eaa graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java Mon Jul 20 17:01:45 2015 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java Mon Jul 20 11:21:28 2015 -0700 @@ -67,7 +67,7 @@ this(hubStamp(stampProvider, value), value, guard); } - public LoadHubNode(Stamp stamp, ValueNode value, ValueNode guard) { + private LoadHubNode(Stamp stamp, ValueNode value, ValueNode guard) { super(TYPE, stamp, (GuardingNode) guard); assert value != guard; this.value = value; @@ -75,9 +75,6 @@ @Override public void lower(LoweringTool tool) { - if (tool.getLoweringStage() != LoweringTool.StandardLoweringStage.LOW_TIER) { - return; - } tool.getLowerer().lower(this, tool); } @@ -92,10 +89,18 @@ return this; } - private static ValueNode findSynonym(ValueNode curValue, Stamp stamp, StructuredGraph graph, MetaAccessProvider metaAccess) { + public static ValueNode findSynonym(ValueNode curValue, Stamp stamp, StructuredGraph graph, MetaAccessProvider metaAccess) { + ResolvedJavaType exactType = findSynonymType(graph, metaAccess, curValue); + if (exactType != null) { + return ConstantNode.forConstant(stamp, exactType.getObjectHub(), metaAccess); + } + return null; + } + + public static ResolvedJavaType findSynonymType(StructuredGraph graph, MetaAccessProvider metaAccess, ValueNode curValue) { + ResolvedJavaType exactType = null; if (metaAccess != null && curValue.stamp() instanceof ObjectStamp) { ObjectStamp objectStamp = (ObjectStamp) curValue.stamp(); - ResolvedJavaType exactType = null; if (objectStamp.isExactType()) { exactType = objectStamp.type(); } else if (objectStamp.type() != null && graph != null && graph.getAssumptions() != null) { @@ -105,12 +110,8 @@ graph.getAssumptions().record(leafConcreteSubtype); } } - - if (exactType != null) { - return ConstantNode.forConstant(stamp, exactType.getObjectHub(), metaAccess); - } } - return null; + return exactType; } @Override diff -r 5c350399111e -r 7abe84b97eaa graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/DynamicNewArrayNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/DynamicNewArrayNode.java Mon Jul 20 17:01:45 2015 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/DynamicNewArrayNode.java Mon Jul 20 11:21:28 2015 -0700 @@ -47,12 +47,25 @@ */ protected final Kind knownElementKind; - public DynamicNewArrayNode(ValueNode elementType, ValueNode length, boolean fillContents, Kind knownElementKind) { - this(TYPE, elementType, length, fillContents, knownElementKind, null); + public DynamicNewArrayNode(ValueNode elementType, ValueNode length, boolean fillContents) { + this(TYPE, elementType, length, fillContents, null, null, null); + } + + public DynamicNewArrayNode(@InjectedNodeParameter MetaAccessProvider metaAccess, ValueNode elementType, ValueNode length, boolean fillContents, Kind knownElementKind) { + this(TYPE, elementType, length, fillContents, knownElementKind, null, metaAccess); } - protected DynamicNewArrayNode(NodeClass c, ValueNode elementType, ValueNode length, boolean fillContents, Kind knownElementKind, FrameState stateBefore) { - super(c, StampFactory.objectNonNull(), length, fillContents, stateBefore); + private static Stamp computeStamp(Kind knownElementKind, MetaAccessProvider metaAccess) { + if (knownElementKind != null && metaAccess != null) { + ResolvedJavaType arrayType = metaAccess.lookupJavaType(knownElementKind == Kind.Object ? Object.class : knownElementKind.toJavaClass()).getArrayClass(); + return StampFactory.declaredNonNull(arrayType); + } + return StampFactory.objectNonNull(); + } + + protected DynamicNewArrayNode(NodeClass c, ValueNode elementType, ValueNode length, boolean fillContents, Kind knownElementKind, FrameState stateBefore, + MetaAccessProvider metaAccess) { + super(c, computeStamp(knownElementKind, metaAccess), length, fillContents, stateBefore); this.elementType = elementType; this.knownElementKind = knownElementKind; assert knownElementKind != Kind.Void && knownElementKind != Kind.Illegal; diff -r 5c350399111e -r 7abe84b97eaa graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/memory/ReadNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/memory/ReadNode.java Mon Jul 20 17:01:45 2015 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/memory/ReadNode.java Mon Jul 20 11:21:28 2015 -0700 @@ -133,6 +133,13 @@ return length; } } + if (locationIdentity instanceof CanonicalizableLocation) { + CanonicalizableLocation canonicalize = (CanonicalizableLocation) locationIdentity; + ValueNode result = canonicalize.canonicalizeRead(read, address, object, tool); + assert result != null && result.stamp().isCompatible(read.stamp()); + return result; + } + } return read; } diff -r 5c350399111e -r 7abe84b97eaa graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/StampProvider.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/StampProvider.java Mon Jul 20 17:01:45 2015 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/StampProvider.java Mon Jul 20 11:21:28 2015 -0700 @@ -36,6 +36,11 @@ Stamp createHubStamp(ObjectStamp object); /** + * Create the stamp of a possibly null hub. + */ + Stamp createHubStamp(boolean nonNull); + + /** * Create the stamp of a pointer to a method. */ Stamp createMethodStamp(); diff -r 5c350399111e -r 7abe84b97eaa 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 Mon Jul 20 17:01:45 2015 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultJavaLoweringProvider.java Mon Jul 20 11:21:28 2015 -0700 @@ -87,7 +87,7 @@ } else if (n instanceof ArrayLengthNode) { lowerArrayLengthNode((ArrayLengthNode) n, tool); } else if (n instanceof LoadHubNode) { - lowerLoadHubNode((LoadHubNode) n); + lowerLoadHubNode((LoadHubNode) n, tool); } else if (n instanceof MonitorEnterNode) { lowerMonitorEnterNode((MonitorEnterNode) n, tool, graph); } else if (n instanceof CompareAndSwapNode) { @@ -118,7 +118,7 @@ } private void lowerTypeCheckNode(TypeCheckNode n, LoweringTool tool, StructuredGraph graph) { - ValueNode hub = createReadHub(graph, n.getValue(), null); + ValueNode hub = createReadHub(graph, n.getValue(), null, tool); ValueNode clazz = graph.unique(ConstantNode.forConstant(tool.getStampProvider().createHubStamp((ObjectStamp) n.getValue().stamp()), n.type().getObjectHub(), tool.getMetaAccess())); LogicNode objectEquals = graph.unique(PointerEqualsNode.create(hub, clazz)); n.replaceAndDelete(objectEquals); @@ -270,8 +270,8 @@ */ GuardingNode nullCheck = nullCheckReturn[0]; assert nullCheckReturn[0] != null || createNullCheck(array, storeIndexed, tool) == null; - ValueNode arrayClass = createReadHub(graph, array, nullCheck); - ValueNode componentHub = createReadArrayComponentHub(graph, arrayClass, storeIndexed); + ValueNode arrayClass = createReadHub(graph, array, nullCheck, tool); + ValueNode componentHub = createReadArrayComponentHub(graph, arrayClass, storeIndexed, tool); checkCastNode = graph.add(new CheckCastDynamicNode(componentHub, value, true)); graph.addBeforeFixed(storeIndexed, checkCastNode); value = checkCastNode; @@ -301,12 +301,15 @@ graph.replaceFixedWithFixed(arrayLengthNode, arrayLengthRead); } - protected void lowerLoadHubNode(LoadHubNode loadHub) { + protected void lowerLoadHubNode(LoadHubNode loadHub, LoweringTool tool) { StructuredGraph graph = loadHub.graph(); + if (tool.getLoweringStage() != LoweringTool.StandardLoweringStage.LOW_TIER) { + return; + } if (graph.getGuardsStage().allowsFloatingGuards()) { return; } - ValueNode hub = createReadHub(graph, loadHub.getValue(), loadHub.getGuard()); + ValueNode hub = createReadHub(graph, loadHub.getValue(), loadHub.getGuard(), tool); graph.replaceFloating(loadHub, hub); } @@ -672,9 +675,9 @@ return value; } - protected abstract ValueNode createReadHub(StructuredGraph graph, ValueNode object, GuardingNode guard); + protected abstract ValueNode createReadHub(StructuredGraph graph, ValueNode object, GuardingNode guard, LoweringTool tool); - protected abstract ValueNode createReadArrayComponentHub(StructuredGraph graph, ValueNode arrayHub, FixedNode anchor); + protected abstract ValueNode createReadArrayComponentHub(StructuredGraph graph, ValueNode arrayHub, FixedNode anchor, LoweringTool tool); protected PiNode getBoundsCheckedIndex(AccessIndexedNode n, LoweringTool tool, GuardingNode[] nullCheckReturn) { StructuredGraph graph = n.graph(); diff -r 5c350399111e -r 7abe84b97eaa graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/StandardGraphBuilderPlugins.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/StandardGraphBuilderPlugins.java Mon Jul 20 17:01:45 2015 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/StandardGraphBuilderPlugins.java Mon Jul 20 11:21:28 2015 -0700 @@ -127,7 +127,7 @@ Registration r = new Registration(plugins, Array.class); r.register2("newInstance", Class.class, int.class, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver unused, ValueNode componentType, ValueNode length) { - b.addPush(Kind.Object, new DynamicNewArrayNode(componentType, length, true, null)); + b.addPush(Kind.Object, new DynamicNewArrayNode(componentType, length, true)); return true; } }); diff -r 5c350399111e -r 7abe84b97eaa jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotResolvedObjectType.java --- a/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotResolvedObjectType.java Mon Jul 20 17:01:45 2015 +0200 +++ b/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotResolvedObjectType.java Mon Jul 20 11:21:28 2015 -0700 @@ -88,6 +88,8 @@ long prototypeMarkWord(); + int layoutHelper(); + HotSpotResolvedObjectType getEnclosingType(); ResolvedJavaMethod getClassInitializer(); diff -r 5c350399111e -r 7abe84b97eaa jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotResolvedObjectTypeImpl.java --- a/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotResolvedObjectTypeImpl.java Mon Jul 20 17:01:45 2015 +0200 +++ b/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotResolvedObjectTypeImpl.java Mon Jul 20 11:21:28 2015 -0700 @@ -430,7 +430,7 @@ assert !isInterface(); HotSpotVMConfig config = runtime().getConfig(); - final int layoutHelper = unsafe.getInt(getMetaspaceKlass() + config.klassLayoutHelperOffset); + final int layoutHelper = layoutHelper(); assert layoutHelper > config.klassLayoutHelperNeutralValue : "must be instance"; // See: Klass::layout_helper_size_in_bytes @@ -442,6 +442,11 @@ return needsSlowPath ? -size : size; } + public int layoutHelper() { + HotSpotVMConfig config = runtime().getConfig(); + return unsafe.getInt(getMetaspaceKlass() + config.klassLayoutHelperOffset); + } + public synchronized HotSpotResolvedJavaMethod createMethod(long metaspaceMethod) { HotSpotResolvedJavaMethod method = null; if (methodCache == null) { diff -r 5c350399111e -r 7abe84b97eaa jvmci/jdk.internal.jvmci.meta/src/jdk/internal/jvmci/meta/NamedLocationIdentity.java --- a/jvmci/jdk.internal.jvmci.meta/src/jdk/internal/jvmci/meta/NamedLocationIdentity.java Mon Jul 20 17:01:45 2015 +0200 +++ b/jvmci/jdk.internal.jvmci.meta/src/jdk/internal/jvmci/meta/NamedLocationIdentity.java Mon Jul 20 11:21:28 2015 -0700 @@ -29,18 +29,17 @@ /** * A {@link LocationIdentity} with a name. */ -public final class NamedLocationIdentity extends LocationIdentity implements FormatWithToString { +public class NamedLocationIdentity extends LocationIdentity implements FormatWithToString { /** * Map for asserting all {@link NamedLocationIdentity} instances have a unique name. */ static class DB { - private static final HashMap map = new HashMap<>(); + private static final HashSet map = new HashSet<>(); - static boolean checkUnique(NamedLocationIdentity identity) { - NamedLocationIdentity oldValue = map.put(identity.name, identity); - if (oldValue != null) { - throw new AssertionError("identity " + identity + " already exists"); + static boolean checkUnique(String name) { + if (!map.add(name)) { + throw new AssertionError("identity " + name + " already exists"); } return true; } @@ -49,9 +48,10 @@ private final String name; private final boolean immutable; - private NamedLocationIdentity(String name, boolean immutable) { + protected NamedLocationIdentity(String name, boolean immutable) { this.name = name; this.immutable = immutable; + assert DB.checkUnique(name); } /** @@ -82,9 +82,7 @@ * @param immutable true if the location is immutable */ private static NamedLocationIdentity create(String name, boolean immutable) { - NamedLocationIdentity id = new NamedLocationIdentity(name, immutable); - assert DB.checkUnique(id); - return id; + return new NamedLocationIdentity(name, immutable); } @Override