001/* 002 * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 004 * 005 * This code is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU General Public License version 2 only, as 007 * published by the Free Software Foundation. 008 * 009 * This code is distributed in the hope that it will be useful, but WITHOUT 010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 011 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 012 * version 2 for more details (a copy is included in the LICENSE file that 013 * accompanied this code). 014 * 015 * You should have received a copy of the GNU General Public License version 016 * 2 along with this work; if not, write to the Free Software Foundation, 017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 018 * 019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 020 * or visit www.oracle.com if you need additional information or have any 021 * questions. 022 */ 023package com.oracle.graal.nodes.debug; 024 025import jdk.internal.jvmci.common.*; 026 027import com.oracle.graal.compiler.common.type.*; 028import com.oracle.graal.graph.*; 029import com.oracle.graal.lir.*; 030import com.oracle.graal.lir.gen.*; 031import com.oracle.graal.nodeinfo.*; 032import com.oracle.graal.nodes.*; 033import com.oracle.graal.nodes.spi.*; 034 035/** 036 * This node can be used to add a counter to the code that will estimate the dynamic number of calls 037 * by adding an increment to the compiled code. This should of course only be used for 038 * debugging/testing purposes. 039 * 040 * A unique counter will be created for each unique name passed to the constructor. Depending on the 041 * value of withContext, the name of the root method is added to the counter's name. 042 */ 043@NodeInfo 044public class DynamicCounterNode extends FixedWithNextNode implements LIRLowerable { 045 046 public static final NodeClass<DynamicCounterNode> TYPE = NodeClass.create(DynamicCounterNode.class); 047 @Input ValueNode increment; 048 049 protected final String name; 050 protected final String group; 051 protected final boolean withContext; 052 053 public DynamicCounterNode(String name, String group, ValueNode increment, boolean withContext) { 054 this(TYPE, name, group, increment, withContext); 055 } 056 057 protected DynamicCounterNode(NodeClass<? extends DynamicCounterNode> c, String name, String group, ValueNode increment, boolean withContext) { 058 super(c, StampFactory.forVoid()); 059 this.name = name; 060 this.group = group; 061 this.increment = increment; 062 this.withContext = withContext; 063 } 064 065 public ValueNode getIncrement() { 066 return increment; 067 } 068 069 public String getName() { 070 return name; 071 } 072 073 public String getGroup() { 074 return group; 075 } 076 077 public boolean isWithContext() { 078 return withContext; 079 } 080 081 public static void addCounterBefore(String group, String name, long increment, boolean withContext, FixedNode position) { 082 StructuredGraph graph = position.graph(); 083 graph.addBeforeFixed(position, position.graph().add(new DynamicCounterNode(name, group, ConstantNode.forLong(increment, position.graph()), withContext))); 084 } 085 086 @NodeIntrinsic 087 public static native void counter(@ConstantNodeParameter String name, @ConstantNodeParameter String group, long increment, @ConstantNodeParameter boolean addContext); 088 089 public void generate(NodeLIRBuilderTool generator) { 090 LIRGeneratorTool lirGen = generator.getLIRGeneratorTool(); 091 String nameWithContext; 092 if (isWithContext()) { 093 nameWithContext = getName() + " @ "; 094 if (graph().method() != null) { 095 StackTraceElement stackTraceElement = graph().method().asStackTraceElement(0); 096 if (stackTraceElement != null) { 097 nameWithContext += " " + stackTraceElement.toString(); 098 } else { 099 nameWithContext += graph().method().format("%h.%n"); 100 } 101 } 102 if (graph().name != null) { 103 nameWithContext += " (" + graph().name + ")"; 104 } 105 106 } else { 107 nameWithContext = getName(); 108 } 109 LIRInstruction counterOp = lirGen.createBenchmarkCounter(nameWithContext, getGroup(), generator.operand(increment)); 110 if (counterOp != null) { 111 lirGen.append(counterOp); 112 } else { 113 throw JVMCIError.unimplemented("Benchmark counters not enabled or not implemented by the back end."); 114 } 115 } 116 117}