# HG changeset patch # User Bernhard Urban # Date 1380024693 -7200 # Node ID e53399f1b2cdb98ebfcababa4ee8e29c7a529659 # Parent ac252c4c920bef1f486a169decb46d207e775f10 SnippetTemplate: add assertions regarding memory kills diff -r ac252c4c920b -r e53399f1b2cd graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java Tue Sep 24 14:11:32 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java Tue Sep 24 14:11:33 2013 +0200 @@ -78,6 +78,23 @@ public String toString() { return "Map=" + lastMemorySnapshot.toString(); } + + public boolean isEmpty() { + if (lastMemorySnapshot.size() == 0) { + return true; + } + if (lastMemorySnapshot.size() == 1) { + if (lastMemorySnapshot.get(ANY_LOCATION) instanceof StartNode) { + return true; + } + } + return false; + } + + public Set getLocations() { + return new HashSet<>(lastMemorySnapshot.keySet()); + } + } private final ExecutionMode execmode; diff -r ac252c4c920b -r e53399f1b2cd graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Tue Sep 24 14:11:32 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Tue Sep 24 14:11:33 2013 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.replacements; +import static com.oracle.graal.api.meta.LocationIdentity.*; + import java.lang.reflect.*; import java.util.*; import java.util.concurrent.*; @@ -42,6 +44,7 @@ import com.oracle.graal.nodes.type.*; import com.oracle.graal.nodes.util.*; import com.oracle.graal.phases.common.*; +import com.oracle.graal.phases.common.FloatingReadPhase.MemoryMapImpl; import com.oracle.graal.phases.tiers.*; import com.oracle.graal.replacements.Snippet.ConstantParameter; import com.oracle.graal.replacements.Snippet.VarargsParameter; @@ -773,6 +776,52 @@ } }; + private boolean checkSnippetKills(ScheduledNode replacee) { + if (!replacee.graph().isAfterFloatingReadPhase()) { + // no floating reads yet, ignore locations created while lowering + return true; + } + if (memoryMap == null || ((MemoryMapImpl) memoryMap).isEmpty()) { + // there're no kills in the snippet graph + return true; + } + + Set kills = ((MemoryMapImpl) memoryMap).getLocations(); + + if (replacee instanceof MemoryCheckpoint.Single) { + // check if some node in snippet graph also kills the same location + LocationIdentity locationIdentity = ((MemoryCheckpoint.Single) replacee).getLocationIdentity(); + if (locationIdentity == ANY_LOCATION) { + assert !(memoryMap.getLastLocationAccess(ANY_LOCATION) instanceof StartNode); + } + assert kills.contains(locationIdentity) : replacee + " kills " + locationIdentity + ", but snippet doesn't contain a kill to this location"; + return true; + } + assert !(replacee instanceof MemoryCheckpoint.Multi) : replacee + " multi not supported (yet)"; + + Debug.log("WARNING: %s is not a MemoryCheckpoint, but the snippet graph contains kills (%s). you might want %s to be a MemoryCheckpoint\n", replacee, kills, replacee); + + // remove ANY_LOCATION if it's just a kill by the start node + if (memoryMap.getLastLocationAccess(ANY_LOCATION) instanceof StartNode) { + kills.remove(ANY_LOCATION); + } + + // node can only lower to a ANY_LOCATION kill if the replacee also kills ANY_LOCATION + assert !kills.contains(ANY_LOCATION) : "snippet graph contains a kill to ANY_LOCATION, but replacee (" + replacee + ") doesn't kill ANY_LOCATION. kills: " + kills; + + /* + * kills to other locations than ANY_LOCATION can be still inserted if there aren't any + * floating reads accessing this locations. Example: In HotSpot, InstanceOfNode is lowered + * to a snippet containing a write to SECONDARY_SUPER_CACHE_LOCATION. This is runtime + * specific, so the runtime independent InstanceOfNode can not kill this location. However, + * if no FloatingReadNode is reading from this location, the kill to this location is fine. + */ + for (FloatingReadNode frn : replacee.graph().getNodes(FloatingReadNode.class)) { + assert !(kills.contains(frn.location().getLocationIdentity())) : frn + " reads from " + frn.location().getLocationIdentity() + " but " + replacee + " does not kill this location"; + } + return true; + } + private class DuplicateMapper implements MemoryMap { Map duplicates; @@ -806,6 +855,7 @@ * @return the map of duplicated nodes (original -> duplicate) */ public Map instantiate(MetaAccessProvider runtime, FixedNode replacee, UsageReplacer replacer, Arguments args) { + assert checkSnippetKills(replacee); try (TimerCloseable a = instantiationTimer.start()) { instantiationCounter.increment(); // Inline the snippet nodes, replacing parameters with the given args in the process @@ -898,6 +948,7 @@ * @param args the arguments to be bound to the flattened positional parameters of the snippet */ public void instantiate(MetaAccessProvider runtime, FloatingNode replacee, UsageReplacer replacer, LoweringTool tool, Arguments args) { + assert checkSnippetKills(replacee); try (TimerCloseable a = instantiationTimer.start()) { instantiationCounter.increment();