1 /* 2 * Copyright (c) 2009, 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 */ 24 package com.sun.hotspot.tools.compiler; 25 26 import java.io.PrintStream; 27 import java.util.ArrayList; 28 import java.util.List; 29 30 /** 31 * Represents an uncommon trap encountered during a compilation. 32 */ 33 class UncommonTrapEvent extends BasicLogEvent { 34 35 private final String reason; 36 private final String action; 37 38 /** 39 * Denote how many times this trap has been encountered. 40 */ 41 private int count; 42 43 /** 44 * The name of the bytecode instruction at which the trap occurred. 45 */ 46 private String bytecode; 47 48 private List<String> jvmsMethods = new ArrayList<>(); 49 50 private List<Integer> jvmsBCIs = new ArrayList<>(); 51 52 UncommonTrapEvent(double s, String i, String r, String a, int c) { 53 super(s, i); 54 reason = r; 55 action = a; 56 count = c; 57 } 58 59 public void updateCount(UncommonTrapEvent trap) { 60 setCount(Math.max(getCount(), trap.getCount())); 61 } 62 63 public void print(PrintStream stream, boolean printID) { 64 if (printID) { 65 stream.print(getId() + " "); 66 } 67 stream.printf("uncommon trap %s %s %s\n", bytecode, getReason(), getAction()); 68 int indent = 2; 69 for (int j = 0; j < jvmsMethods.size(); j++) { 70 for (int i = 0; i < indent; i++) { 71 stream.print(' '); 72 } 73 stream.println("@ " + jvmsBCIs.get(j) + " " + jvmsMethods.get(j)); 74 indent += 2; 75 } 76 } 77 78 79 public String getReason() { 80 return reason; 81 } 82 83 public String getAction() { 84 return action; 85 } 86 87 public int getCount() { 88 return count; 89 } 90 91 public void setCount(int count) { 92 this.count = count; 93 } 94 95 /** 96 * Set the compilation for this event. This involves identifying the call 97 * site to which this uncommon trap event belongs. In addition to setting 98 * the {@link #compilation} link, this method will consequently also set 99 * the {@link #bytecode} field. 100 */ 101 public void setCompilation(Compilation compilation) { 102 super.setCompilation(compilation); 103 // Attempt to associate a bytecode with with this trap 104 CallSite site = compilation.getCall(); 105 int i = 0; 106 try { 107 List<UncommonTrap> traps = site.getTraps(); 108 while (i + 1 < jvmsMethods.size()) { 109 if (!jvmsMethods.get(i).equals(site.getMethod().getFullName())) { 110 throw new InternalError(jvmsMethods.get(i) + " != " + site.getMethod().getFullName()); 111 } 112 CallSite result = null; 113 for (CallSite call : site.getCalls()) { 114 if (call.getBci() == jvmsBCIs.get(i) && 115 call.getMethod().getFullName().equals(jvmsMethods.get(i + 1)) && 116 call.getReceiver() == null) { 117 result = call; 118 i++; 119 break; 120 } 121 } 122 if (result == null) { 123 throw new InternalError("couldn't find call site"); 124 } 125 site = result; 126 traps = site.getTraps(); 127 } 128 for (UncommonTrap trap : traps) { 129 if (trap.getBCI() == jvmsBCIs.get(i) && 130 trap.getReason().equals(getReason()) && 131 trap.getAction().equals(getAction())) { 132 bytecode = trap.getBytecode(); 133 return; 134 } 135 } 136 throw new InternalError("couldn't find bytecode"); 137 } catch (Exception e) { 138 bytecode = "<unknown>"; 139 } 140 } 141 142 public void addMethodAndBCI(String method, int bci) { 143 jvmsMethods.add(0, method); 144 jvmsBCIs.add(0, bci); 145 } 146 147 }