# HG changeset patch # User Tom Rodriguez # Date 1429902338 25200 # Node ID bf8cbbfabdcfed8a1119a4090d617c99c9a210c0 # Parent db96f9915540bf52437fd767359dbd80c9de551b Use snippets for incrementing snippet counters diff -r db96f9915540 -r bf8cbbfabdcf 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 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 diff -r db96f9915540 -r bf8cbbfabdcf graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetCounter.java --- 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. */ diff -r db96f9915540 -r bf8cbbfabdcf graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetCounterNode.java --- /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 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); + } + } + } + +} diff -r db96f9915540 -r bf8cbbfabdcf 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 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