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  */
  23 package org.graalvm.compiler.salver.util;
  24 
  25 import static org.graalvm.compiler.debug.GraalDebugConfig.asJavaMethod;
  26 
  27 import java.util.ArrayList;
  28 
  29 import org.graalvm.compiler.debug.Debug;
  30 import org.graalvm.compiler.debug.DebugDumpScope;
  31 import org.graalvm.compiler.graph.Graph;
  32 import org.graalvm.compiler.salver.util.MethodContext.Item;
  33 
  34 import jdk.vm.ci.meta.JavaMethod;
  35 
  36 public 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 }