changeset 23215:131ca5e519b0

Implement capped cache SnippetTemplate with LRU eviction
author Stefan Anzinger <stefan.anzinger@oracle.com>
date Wed, 23 Dec 2015 13:06:05 +0100
parents ac8468dccb81
children 16b472b9ca55
files graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java
diffstat 1 files changed, 18 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Wed Dec 23 12:58:30 2015 +0100
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Wed Dec 23 13:06:05 2015 +0100
@@ -25,7 +25,6 @@
 import static com.oracle.graal.compiler.common.GraalOptions.UseGraalInstrumentation;
 import static com.oracle.graal.debug.Debug.applyFormattingFlagsAndWidth;
 import static com.oracle.graal.phases.common.DeadCodeEliminationPhase.Optionality.Required;
-import static com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates.UseSnippetTemplateCache;
 import static java.util.FormattableFlags.ALTERNATE;
 import static jdk.vm.ci.meta.LocationIdentity.any;
 
@@ -38,10 +37,10 @@
 import java.util.Formattable;
 import java.util.Formatter;
 import java.util.HashSet;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.function.Predicate;
 import java.util.stream.Collectors;
@@ -66,7 +65,6 @@
 import com.oracle.graal.debug.DebugCloseable;
 import com.oracle.graal.debug.DebugMetric;
 import com.oracle.graal.debug.DebugTimer;
-import com.oracle.graal.debug.TTY;
 import com.oracle.graal.graph.Graph.Mark;
 import com.oracle.graal.graph.Node;
 import com.oracle.graal.graph.NodeClass;
@@ -216,16 +214,6 @@
             assert method.isStatic() : "snippet method must be static: " + method.format("%H.%n");
         }
 
-        private int templateCount;
-
-        void notifyNewTemplate() {
-            templateCount++;
-            if (templateCount == MaxTemplatesPerSnippet) {
-                TTY.printf("WARNING: Exceeded %d templates for snippet %s%n" + "         Adjust maximum with %s system property%n", MaxTemplatesPerSnippet, method.format("%h.%n(%p)"),
-                                MAX_TEMPLATES_PER_SNIPPET_PROPERTY_NAME);
-            }
-        }
-
         public ResolvedJavaMethod getMethod() {
             return method;
         }
@@ -548,18 +536,17 @@
     public abstract static class AbstractTemplates implements com.oracle.graal.api.replacements.SnippetTemplateCache {
 
         static final boolean UseSnippetTemplateCache = Boolean.parseBoolean(System.getProperty("graal.useSnippetTemplateCache", "true"));
-
         protected final Providers providers;
         protected final SnippetReflectionProvider snippetReflection;
         protected final TargetDescription target;
-        private final ConcurrentHashMap<CacheKey, SnippetTemplate> templates;
+        private final Map<CacheKey, SnippetTemplate> templates;
 
         protected AbstractTemplates(Providers providers, SnippetReflectionProvider snippetReflection, TargetDescription target) {
             this.providers = providers;
             this.snippetReflection = snippetReflection;
             this.target = target;
             if (UseSnippetTemplateCache) {
-                this.templates = new ConcurrentHashMap<>();
+                this.templates = Collections.synchronizedMap(new LRUCache<>(MaxTemplatesPerSnippet, MaxTemplatesPerSnippet));
             } else {
                 this.templates = null;
             }
@@ -615,6 +602,21 @@
         }
     }
 
+    private static final class LRUCache<K, V> extends LinkedHashMap<K, V> {
+        private static final long serialVersionUID = 1L;
+        private final int maxCacheSize;
+
+        public LRUCache(int initialCapacity, int maxCacheSize) {
+            super(initialCapacity, 0.75F, true);
+            this.maxCacheSize = maxCacheSize;
+        }
+
+        @Override
+        protected boolean removeEldestEntry(java.util.Map.Entry<K, V> eldest) {
+            return size() > maxCacheSize;
+        }
+    }
+
     // These values must be compared with equals() not '==' to support replay compilation.
     private static final Object UNUSED_PARAMETER = "UNUSED_PARAMETER";
     private static final Object CONSTANT_PARAMETER = "CONSTANT_PARAMETER";
@@ -858,9 +860,6 @@
             }
 
             Debug.metric("SnippetTemplateNodeCount[%#s]", args).add(nodes.size());
-            if (UseSnippetTemplateCache && args.cacheable) {
-                args.info.notifyNewTemplate();
-            }
             Debug.dump(snippet, "SnippetTemplate final state");
 
         } catch (Throwable ex) {