changeset 21116:bf8cbbfabdcf

Use snippets for incrementing snippet counters
author Tom Rodriguez <tom.rodriguez@oracle.com>
date Fri, 24 Apr 2015 12:05:38 -0700
parents db96f9915540
children f6f3f44a1830 a17dc2584e81
files graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultJavaLoweringProvider.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetCounter.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetCounterNode.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java
diffstat 4 files changed, 141 insertions(+), 34 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultJavaLoweringProvider.java	Thu Apr 23 22:09:27 2015 -0700
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultJavaLoweringProvider.java	Fri Apr 24 12:05:38 2015 -0700
@@ -67,6 +67,7 @@
 
     public void initialize(Providers providers, SnippetReflectionProvider snippetReflection) {
         boxingSnippets = new BoxingSnippets.Templates(providers, snippetReflection, target);
+        providers.getReplacements().registerSnippetTemplateCache(new SnippetCounterNode.SnippetCounterSnippets.Templates(providers, snippetReflection, target));
     }
 
     @Override
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetCounter.java	Thu Apr 23 22:09:27 2015 -0700
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetCounter.java	Fri Apr 24 12:05:38 2015 -0700
@@ -24,16 +24,9 @@
 
 //JaCoCo Exclude
 
-import static com.oracle.graal.compiler.common.UnsafeAccess.*;
-
 import java.io.*;
 import java.util.*;
 
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.api.replacements.*;
-import com.oracle.graal.compiler.common.*;
-import com.oracle.graal.word.*;
-
 /**
  * A counter that can be safely {@linkplain #inc() incremented} from within a snippet for gathering
  * snippet specific metrics.
@@ -94,15 +87,6 @@
     private final String description;
     private long value;
 
-    @Fold
-    private static int countOffset() {
-        try {
-            return (int) unsafe.objectFieldOffset(SnippetCounter.class.getDeclaredField("value"));
-        } catch (Exception e) {
-            throw new GraalInternalError(e);
-        }
-    }
-
     /**
      * Creates a counter.
      *
@@ -128,20 +112,12 @@
     }
 
     /**
-     * We do not want to use the {@link LocationIdentity} of the {@link #value} field, so that the
-     * usage in snippets is always possible. If a method accesses the counter via the field and the
-     * snippet, the result might not be correct though.
-     */
-    protected static final LocationIdentity SNIPPET_COUNTER_LOCATION = NamedLocationIdentity.mutable("SnippetCounter");
-
-    /**
      * Increments the value of this counter. This method can be safely used in a snippet if it is
      * invoked on a compile-time constant {@link SnippetCounter} object.
      */
     public void inc() {
         if (group != null) {
-            long loadedValue = ObjectAccess.readLong(this, countOffset(), SNIPPET_COUNTER_LOCATION);
-            ObjectAccess.writeLong(this, countOffset(), loadedValue + 1, SNIPPET_COUNTER_LOCATION);
+            SnippetCounterNode.increment(this);
         }
     }
 
@@ -152,6 +128,14 @@
         return value;
     }
 
+    @Override
+    public String toString() {
+        if (group != null) {
+            return "SnippetCounter-" + group.name + ":" + name;
+        }
+        return super.toString();
+    }
+
     /**
      * Prints all the counter groups to a given stream.
      */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetCounterNode.java	Fri Apr 24 12:05:38 2015 -0700
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2013, 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.replacements;
+
+import static com.oracle.graal.compiler.common.UnsafeAccess.*;
+import static com.oracle.graal.replacements.SnippetTemplate.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.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.*;
+import com.oracle.graal.nodeinfo.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.phases.util.*;
+import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates;
+import com.oracle.graal.replacements.SnippetTemplate.Arguments;
+import com.oracle.graal.replacements.SnippetTemplate.SnippetInfo;
+import com.oracle.graal.word.*;
+
+/**
+ * This node can be used to add a counter to the code that will estimate the dynamic number of calls
+ * by adding an increment to the compiled code. This should of course only be used for
+ * debugging/testing purposes.
+ *
+ * A unique counter will be created for each unique name passed to the constructor. Depending on the
+ * value of withContext, the name of the root method is added to the counter's name.
+ */
+@NodeInfo
+public class SnippetCounterNode extends FixedWithNextNode implements Lowerable {
+
+    public static final NodeClass<SnippetCounterNode> TYPE = NodeClass.create(SnippetCounterNode.class);
+
+    @Input protected ValueNode increment;
+
+    protected final SnippetCounter counter;
+
+    public SnippetCounterNode(SnippetCounter counter, ValueNode increment) {
+        super(TYPE, StampFactory.forVoid());
+        this.counter = counter;
+        this.increment = increment;
+    }
+
+    public SnippetCounter getCounter() {
+        return counter;
+    }
+
+    public ValueNode getIncrement() {
+        return increment;
+    }
+
+    @NodeIntrinsic
+    public static native void add(@ConstantNodeParameter SnippetCounter counter, int increment);
+
+    public static void increment(@ConstantNodeParameter SnippetCounter counter) {
+        add(counter, 1);
+    }
+
+    public void lower(LoweringTool tool) {
+        if (graph().getGuardsStage().areFrameStatesAtDeopts()) {
+            SnippetCounterSnippets.Templates templates = tool.getReplacements().getSnippetTemplateCache(SnippetCounterSnippets.Templates.class);
+            templates.lower(this, tool);
+        }
+    }
+
+    static class SnippetCounterSnippets implements Snippets {
+
+        @Fold
+        private static int countOffset() {
+            try {
+                return (int) unsafe.objectFieldOffset(SnippetCounter.class.getDeclaredField("value"));
+            } catch (Exception e) {
+                throw new GraalInternalError(e);
+            }
+        }
+
+        /**
+         * We do not want to use the {@link LocationIdentity} of the {@link SnippetCounter#value}
+         * field, so that the usage in snippets is always possible. If a method accesses the counter
+         * via the field and the snippet, the result might not be correct though.
+         */
+        protected static final LocationIdentity SNIPPET_COUNTER_LOCATION = NamedLocationIdentity.mutable("SnippetCounter");
+
+        @Snippet
+        public static void add(SnippetCounter counter, int increment) {
+            long loadedValue = ObjectAccess.readLong(counter, countOffset(), SNIPPET_COUNTER_LOCATION);
+            ObjectAccess.writeLong(counter, countOffset(), loadedValue + increment, SNIPPET_COUNTER_LOCATION);
+        }
+
+        public static class Templates extends AbstractTemplates {
+
+            private final SnippetInfo add = snippet(SnippetCounterSnippets.class, "add", SNIPPET_COUNTER_LOCATION);
+
+            public Templates(Providers providers, SnippetReflectionProvider snippetReflection, TargetDescription target) {
+                super(providers, snippetReflection, target);
+            }
+
+            public void lower(SnippetCounterNode counter, LoweringTool tool) {
+                StructuredGraph graph = counter.graph();
+                Arguments args = new Arguments(add, graph.getGuardsStage(), tool.getLoweringStage());
+                args.addConst("counter", counter.getCounter());
+                args.add("increment", counter.getIncrement());
+
+                template(args).instantiate(providers.getMetaAccess(), counter, DEFAULT_REPLACER, args);
+            }
+        }
+    }
+
+}
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Thu Apr 23 22:09:27 2015 -0700
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Fri Apr 24 12:05:38 2015 -0700
@@ -23,7 +23,6 @@
 package com.oracle.graal.replacements;
 
 import static com.oracle.graal.api.meta.LocationIdentity.*;
-import static com.oracle.graal.compiler.common.GraalOptions.*;
 import static com.oracle.graal.debug.Debug.*;
 import static com.oracle.graal.phases.common.DeadCodeEliminationPhase.Optionality.*;
 import static com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates.*;
@@ -1016,14 +1015,6 @@
         // node can only lower to a ANY_LOCATION kill if the replacee also kills ANY_LOCATION
         assert !kills.contains(any()) : "snippet graph contains a kill to ANY_LOCATION, but replacee (" + replacee + ") doesn't kill ANY_LOCATION.  kills: " + kills;
 
-        if (SnippetCounters.getValue()) {
-            /*
-             * accesses to snippet counters are artificially introduced and violate the memory
-             * semantics.
-             */
-            kills.remove(SnippetCounter.SNIPPET_COUNTER_LOCATION);
-        }
-
         /*
          * Kills to private locations are safe, since there can be no floating read to these
          * locations except reads that are introduced by the snippet itself or related snippets in