1/* 2 * Copyright (c) 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.salver.util; 24 25import static org.graalvm.compiler.debug.GraalDebugConfig.asJavaMethod; 26 27import java.util.ArrayList; 28 29import org.graalvm.compiler.debug.Debug; 30import org.graalvm.compiler.debug.DebugDumpScope; 31import org.graalvm.compiler.graph.Graph; 32import org.graalvm.compiler.salver.util.MethodContext.Item; 33 34import jdk.vm.ci.meta.JavaMethod; 35 36public class MethodContext extends ArrayList<Item> { 37 38 private static final long serialVersionUID = 1L; 39 40 public static final class Item { 41 42 private String name; 43 private JavaMethod method; 44 private int debugId; 45 46 private Item(String name, JavaMethod method, int debugId) { 47 this.name = name; 48 this.method = method; 49 this.debugId = debugId; 50 } 51 52 private Item(JavaMethod method) { 53 this(method.format("%H::%n(%p)"), method, -1); 54 } 55 56 private Item(String name) { 57 this(name, null, -1); 58 } 59 60 public String getName() { 61 return name; 62 } 63 64 public JavaMethod getMethod() { 65 return method; 66 } 67 68 public int getDebugId() { 69 return debugId; 70 } 71 } 72 73 public MethodContext() { 74 Object lastMethodOrGraph = null; 75 for (Object obj : Debug.context()) { 76 JavaMethod method = asJavaMethod(obj); 77 if (method != null) { 78 JavaMethod lastAsMethod = asJavaMethod(lastMethodOrGraph); 79 if (lastAsMethod == null || !lastAsMethod.equals(method)) { 80 add(new Item(method)); 81 } else { 82 /* 83 * This prevents multiple adjacent method context objects for the same method 84 * from resulting in multiple IGV tree levels. This works on the assumption that 85 * real inlining debug scopes will have a graph context object between the 86 * inliner and inlinee context objects. 87 */ 88 } 89 } else if (obj instanceof DebugDumpScope) { 90 DebugDumpScope debugDumpScope = (DebugDumpScope) obj; 91 if (debugDumpScope.decorator && !isEmpty()) { 92 try { 93 get(size() - 1).debugId = Integer.parseInt(debugDumpScope.name); 94 } catch (NumberFormatException e) { 95 // Ignore 96 } 97 } else { 98 add(new Item(debugDumpScope.name)); 99 } 100 } 101 if (obj instanceof JavaMethod || obj instanceof Graph) { 102 lastMethodOrGraph = obj; 103 } 104 } 105 if (isEmpty()) { 106 add(new Item("Top Scope")); 107 } 108 } 109 110 public boolean itemEquals(int index, MethodContext context) { 111 Item i1 = get(index); 112 Item i2 = context != null ? context.get(index) : null; 113 if (i1 != null && i2 != null && i1.name != null && i2.name != null) { 114 return i1.name.equals(i2.name) && i1.debugId == i2.debugId; 115 } 116 return false; 117 } 118} 119