1/* 2 * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23package org.graalvm.compiler.microbenchmarks.graal.util; 24 25import static org.graalvm.compiler.microbenchmarks.graal.util.GraalUtil.getGraphFromMethodSpec; 26import static org.graalvm.compiler.microbenchmarks.graal.util.GraalUtil.getNodes; 27 28import java.util.ArrayList; 29import java.util.List; 30 31import org.openjdk.jmh.annotations.Level; 32import org.openjdk.jmh.annotations.Scope; 33import org.openjdk.jmh.annotations.State; 34import org.openjdk.jmh.annotations.TearDown; 35 36import org.graalvm.compiler.graph.Node; 37import org.graalvm.compiler.graph.NodeClass; 38import org.graalvm.compiler.nodes.StructuredGraph; 39 40/** 41 * State providing the nodes in a graph. Subclasses of this class are annotated with 42 * {@link MethodSpec} to specify the Java method that will be parsed to obtain the original graph. 43 */ 44@State(Scope.Benchmark) 45public abstract class NodesState { 46 47 public NodesState() { 48 this.graph = getGraphFromMethodSpec(getClass()); 49 this.nodes = getNodes(graph); 50 this.originalNodes = nodes.clone(); 51 List<Node> vnln = new ArrayList<>(nodes.length); 52 List<NodePair> list2 = new ArrayList<>(nodes.length); 53 for (int i = 0; i < nodes.length; i++) { 54 Node n = nodes[i]; 55 NodeClass<?> nc = n.getNodeClass(); 56 if (nc.valueNumberable() && nc.isLeafNode()) { 57 vnln.add(n); 58 } 59 for (int j = i + i; j < nodes.length; j++) { 60 Node o = nodes[j]; 61 if (o.getClass() == n.getClass()) { 62 list2.add(new NodePair(n, o)); 63 } 64 } 65 } 66 valueNumberableLeafNodes = vnln.toArray(new Node[vnln.size()]); 67 valueEqualsNodePairs = list2.toArray(new NodePair[list2.size()]); 68 } 69 70 /** 71 * Used to check that benchmark does not mutate {@link #nodes}. 72 */ 73 private final Node[] originalNodes; 74 75 /** 76 * The nodes processed by the benchmark. These arrays must be treated as read-only within the 77 * benchmark method. 78 */ 79 public final StructuredGraph graph; 80 public final Node[] nodes; 81 public final Node[] valueNumberableLeafNodes; 82 public final NodePair[] valueEqualsNodePairs; 83 84 public final class NodePair { 85 public final Node n1; 86 public final Node n2; 87 88 public NodePair(Node n1, Node n2) { 89 this.n1 = n1; 90 this.n2 = n2; 91 } 92 } 93 94 private int invocation; 95 96 @TearDown(Level.Invocation) 97 public void afterInvocation() { 98 if (invocation == 0) { 99 // Only need to check the first invocation 100 invocation++; 101 for (int i = 0; i < nodes.length; i++) { 102 if (nodes[i] != originalNodes[i]) { 103 throw new InternalError(String.format("Benchmark method mutated node %d: original=%s, current=%s", i, originalNodes[i], nodes[i])); 104 } 105 } 106 } 107 } 108} 109