--- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PEReadEliminationClosure.java 2017-08-03 22:42:56.851702376 -0700 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PEReadEliminationClosure.java 2017-08-03 22:42:56.752697937 -0700 @@ -31,6 +31,7 @@ import org.graalvm.compiler.core.common.cfg.Loop; import org.graalvm.compiler.core.common.spi.ConstantFieldProvider; +import org.graalvm.compiler.core.common.type.Stamp; import org.graalvm.compiler.graph.Node; import org.graalvm.compiler.nodes.AbstractBeginNode; import org.graalvm.compiler.nodes.FieldLocationIdentity; @@ -130,9 +131,9 @@ return false; } - private boolean processStore(FixedNode store, ValueNode object, LocationIdentity identity, int index, ValueNode value, PEReadEliminationBlockState state, GraphEffectList effects) { + private boolean processStore(FixedNode store, ValueNode object, LocationIdentity identity, int index, JavaKind kind, ValueNode value, PEReadEliminationBlockState state, GraphEffectList effects) { ValueNode unproxiedObject = GraphUtil.unproxify(object); - ValueNode cachedValue = state.getReadCache(object, identity, index, this); + ValueNode cachedValue = state.getReadCache(object, identity, index, kind, this); ValueNode finalValue = getScalarAlias(value); boolean result = false; @@ -141,15 +142,17 @@ result = true; } state.killReadCache(identity, index); - state.addReadCache(unproxiedObject, identity, index, finalValue, this); + state.addReadCache(unproxiedObject, identity, index, kind, finalValue, this); return result; } - private boolean processLoad(FixedNode load, ValueNode object, LocationIdentity identity, int index, PEReadEliminationBlockState state, GraphEffectList effects) { + private boolean processLoad(FixedNode load, ValueNode object, LocationIdentity identity, int index, JavaKind kind, PEReadEliminationBlockState state, GraphEffectList effects) { ValueNode unproxiedObject = GraphUtil.unproxify(object); - ValueNode cachedValue = state.getReadCache(unproxiedObject, identity, index, this); + ValueNode cachedValue = state.getReadCache(unproxiedObject, identity, index, kind, this); if (cachedValue != null) { - if (!load.stamp().isCompatible(cachedValue.stamp())) { + Stamp loadStamp = load.stamp(); + Stamp cachedValueStamp = cachedValue.stamp(); + if (!loadStamp.isCompatible(cachedValueStamp)) { /* * Can either be the first field of a two slot write to a one slot field which would * have a non compatible stamp or the second load which will see Illegal. @@ -164,7 +167,7 @@ return true; } } else { - state.addReadCache(unproxiedObject, identity, index, load, this); + state.addReadCache(unproxiedObject, identity, index, kind, load, this); return false; } } @@ -177,13 +180,13 @@ int index = VirtualArrayNode.entryIndexForOffset(offset, load.accessKind(), type.getComponentType(), Integer.MAX_VALUE); ValueNode object = GraphUtil.unproxify(load.object()); LocationIdentity location = NamedLocationIdentity.getArrayLocation(type.getComponentType().getJavaKind()); - ValueNode cachedValue = state.getReadCache(object, location, index, this); + ValueNode cachedValue = state.getReadCache(object, location, index, load.accessKind(), this); if (cachedValue != null && load.stamp().isCompatible(cachedValue.stamp())) { effects.replaceAtUsages(load, cachedValue, load); addScalarAlias(load, cachedValue); return true; } else { - state.addReadCache(object, location, index, load, this); + state.addReadCache(object, location, index, load.accessKind(), load, this); } } } @@ -197,7 +200,7 @@ if (store.offset().isConstant()) { long offset = store.offset().asJavaConstant().asLong(); int index = VirtualArrayNode.entryIndexForOffset(offset, store.accessKind(), type.getComponentType(), Integer.MAX_VALUE); - return processStore(store, store.object(), location, index, store.value(), state, effects); + return processStore(store, store.object(), location, index, store.accessKind(), store.value(), state, effects); } else { processIdentity(state, location); } @@ -208,7 +211,7 @@ } private boolean processArrayLength(ArrayLengthNode length, PEReadEliminationBlockState state, GraphEffectList effects) { - return processLoad(length, length.array(), ARRAY_LENGTH_LOCATION, -1, state, effects); + return processLoad(length, length.array(), ARRAY_LENGTH_LOCATION, -1, JavaKind.Int, state, effects); } private boolean processStoreField(StoreFieldNode store, PEReadEliminationBlockState state, GraphEffectList effects) { @@ -216,7 +219,7 @@ state.killReadCache(); return false; } - return processStore(store, store.object(), new FieldLocationIdentity(store.field()), -1, store.value(), state, effects); + return processStore(store, store.object(), new FieldLocationIdentity(store.field()), -1, store.field().getJavaKind(), store.value(), state, effects); } private boolean processLoadField(LoadFieldNode load, PEReadEliminationBlockState state, GraphEffectList effects) { @@ -224,14 +227,14 @@ state.killReadCache(); return false; } - return processLoad(load, load.object(), new FieldLocationIdentity(load.field()), -1, state, effects); + return processLoad(load, load.object(), new FieldLocationIdentity(load.field()), -1, load.field().getJavaKind(), state, effects); } private boolean processStoreIndexed(StoreIndexedNode store, PEReadEliminationBlockState state, GraphEffectList effects) { LocationIdentity arrayLocation = NamedLocationIdentity.getArrayLocation(store.elementKind()); if (store.index().isConstant()) { int index = ((JavaConstant) store.index().asConstant()).asInt(); - return processStore(store, store.array(), arrayLocation, index, store.value(), state, effects); + return processStore(store, store.array(), arrayLocation, index, store.elementKind(), store.value(), state, effects); } else { state.killReadCache(arrayLocation, -1); } @@ -242,13 +245,13 @@ if (load.index().isConstant()) { int index = ((JavaConstant) load.index().asConstant()).asInt(); LocationIdentity arrayLocation = NamedLocationIdentity.getArrayLocation(load.elementKind()); - return processLoad(load, load.array(), arrayLocation, index, state, effects); + return processLoad(load, load.array(), arrayLocation, index, load.elementKind(), state, effects); } return false; } private boolean processUnbox(UnboxNode unbox, PEReadEliminationBlockState state, GraphEffectList effects) { - return processLoad(unbox, unbox.getValue(), UNBOX_LOCATIONS.get(unbox.getBoxingKind()), -1, state, effects); + return processLoad(unbox, unbox.getValue(), UNBOX_LOCATIONS.get(unbox.getBoxingKind()), -1, unbox.getBoxingKind(), state, effects); } private static void processIdentity(PEReadEliminationBlockState state, LocationIdentity identity) { @@ -290,7 +293,7 @@ if (object != null) { Pair pair = firstValueSet.get(object); while (pair != null) { - initialState.addReadCache(pair.getLeft(), entry.identity, entry.index, initialState.getReadCache().get(entry), this); + initialState.addReadCache(pair.getLeft(), entry.identity, entry.index, entry.kind, initialState.getReadCache().get(entry), this); pair = (Pair) pair.getRight(); } } @@ -307,7 +310,7 @@ MapCursor entry = exitState.getReadCache().getEntries(); while (entry.advance()) { if (initialState.getReadCache().get(entry.getKey()) != entry.getValue()) { - ValueNode value = exitState.getReadCache(entry.getKey().object, entry.getKey().identity, entry.getKey().index, this); + ValueNode value = exitState.getReadCache(entry.getKey().object, entry.getKey().identity, entry.getKey().index, entry.getKey().kind, this); assert value != null : "Got null from read cache, entry's value:" + entry.getValue(); if (!(value instanceof ProxyNode) || ((ProxyNode) value).proxyPoint() != exitNode) { ProxyNode proxy = new ValueProxyNode(value, exitNode); @@ -366,7 +369,7 @@ PhiNode phiNode = getPhi(key, value.stamp().unrestricted()); mergeEffects.addFloatingNode(phiNode, "mergeReadCache"); for (int i = 0; i < states.size(); i++) { - ValueNode v = states.get(i).getReadCache(key.object, key.identity, key.index, PEReadEliminationClosure.this); + ValueNode v = states.get(i).getReadCache(key.object, key.identity, key.index, key.kind, PEReadEliminationClosure.this); assert phiNode.stamp().isCompatible(v.stamp()) : "Cannot create read elimination phi for inputs with incompatible stamps."; setPhiInput(phiNode, i, v); } @@ -383,19 +386,19 @@ if (phi.getStackKind() == JavaKind.Object) { for (ReadCacheEntry entry : states.get(0).readCache.getKeys()) { if (entry.object == getPhiValueAt(phi, 0)) { - mergeReadCachePhi(phi, entry.identity, entry.index, states); + mergeReadCachePhi(phi, entry.identity, entry.index, entry.kind, states); } } } } } - private void mergeReadCachePhi(PhiNode phi, LocationIdentity identity, int index, List states) { + private void mergeReadCachePhi(PhiNode phi, LocationIdentity identity, int index, JavaKind kind, List states) { ValueNode[] values = new ValueNode[states.size()]; - values[0] = states.get(0).getReadCache(getPhiValueAt(phi, 0), identity, index, PEReadEliminationClosure.this); + values[0] = states.get(0).getReadCache(getPhiValueAt(phi, 0), identity, index, kind, PEReadEliminationClosure.this); if (values[0] != null) { for (int i = 1; i < states.size(); i++) { - ValueNode value = states.get(i).getReadCache(getPhiValueAt(phi, i), identity, index, PEReadEliminationClosure.this); + ValueNode value = states.get(i).getReadCache(getPhiValueAt(phi, i), identity, index, kind, PEReadEliminationClosure.this); // e.g. unsafe loads / stores with same identity and different access kinds see // mergeReadCache(states) if (value == null || !values[i - 1].stamp().isCompatible(value.stamp())) { @@ -404,12 +407,12 @@ values[i] = value; } - PhiNode phiNode = getPhi(new ReadCacheEntry(identity, phi, index), values[0].stamp().unrestricted()); + PhiNode phiNode = getPhi(new ReadCacheEntry(identity, phi, index, kind), values[0].stamp().unrestricted()); mergeEffects.addFloatingNode(phiNode, "mergeReadCachePhi"); for (int i = 0; i < values.length; i++) { setPhiInput(phiNode, i, values[i]); } - newState.readCache.put(new ReadCacheEntry(identity, phi, index), phiNode); + newState.readCache.put(new ReadCacheEntry(identity, phi, index, kind), phiNode); } } }