1 /* 2 * Copyright (c) 2013, 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 jdk.vm.ci.meta; 24 25 /** 26 * This object holds probability information for a set of items that were profiled at a specific 27 * BCI. The precision of the supplied values may vary, but a runtime that provides this information 28 * should be aware that it will be used to guide performance-critical decisions like speculative 29 * inlining, etc. 30 * 31 * @param <T> a subclass of AbstractProfiledItem 32 * @param <U> the class of the items that are profiled at the specific BCI and for which 33 * probabilities are stored. E.g., a ResolvedJavaType or a ResolvedJavaMethod. 34 */ 35 public abstract class AbstractJavaProfile<T extends AbstractProfiledItem<U>, U> { 36 37 private final double notRecordedProbability; 38 private final T[] pitems; 39 40 public AbstractJavaProfile(double notRecordedProbability, T[] pitems) { 41 this.pitems = pitems; 42 assert !Double.isNaN(notRecordedProbability); 43 this.notRecordedProbability = notRecordedProbability; 44 assert isSorted(); 45 assert totalProbablility() >= 0 && totalProbablility() <= 1.0001 : totalProbablility() + " " + this; 46 } 47 48 private double totalProbablility() { 49 double total = notRecordedProbability; 50 for (T item : pitems) { 51 total += item.probability; 52 } 53 return total; 54 } 55 56 /** 57 * Determines if an array of profiled items are sorted in descending order of their 58 * probabilities. 59 */ 60 private boolean isSorted() { 61 for (int i = 1; i < pitems.length; i++) { 62 if (pitems[i - 1].getProbability() < pitems[i].getProbability()) { 63 return false; 64 } 65 } 66 return true; 67 } 68 69 /** 70 * Returns the estimated probability of all types that could not be recorded due to profiling 71 * limitations. 72 * 73 * @return double value ≥ 0.0 and ≤ 1.0 74 */ 75 public double getNotRecordedProbability() { 76 return notRecordedProbability; 77 } 78 79 protected T[] getItems() { 80 return pitems; 81 } 82 83 /** 84 * Searches for an entry of a given resolved Java type. 85 * 86 * @param type the type for which an entry should be searched 87 * @return the entry or null if no entry for this type can be found 88 */ 89 public T findEntry(ResolvedJavaType type) { 90 if (pitems != null) { 91 for (T pt : pitems) { 92 if (pt.getItem().equals(type)) { 93 return pt; 94 } 95 } 96 } 97 return null; 98 } 99 100 @Override 101 public String toString() { 102 StringBuilder builder = new StringBuilder(); 103 builder.append(this.getClass().getName()); 104 builder.append("["); 105 if (pitems != null) { 106 for (T pt : pitems) { 107 builder.append(pt.toString()); 108 builder.append(", "); 109 } 110 } 111 builder.append(this.notRecordedProbability); 112 builder.append("]"); 113 return builder.toString(); 114 } 115 116 public boolean isIncluded(U item) { 117 if (this.getNotRecordedProbability() > 0.0) { 118 return true; 119 } else { 120 for (int i = 0; i < getItems().length; i++) { 121 T pitem = getItems()[i]; 122 U curType = pitem.getItem(); 123 if (curType == item) { 124 return true; 125 } 126 } 127 } 128 return false; 129 } 130 131 @Override 132 public boolean equals(Object obj) { 133 if (obj == this) { 134 return true; 135 } 136 if (!(obj instanceof AbstractJavaProfile)) { 137 return false; 138 } 139 AbstractJavaProfile<?, ?> that = (AbstractJavaProfile<?, ?>) obj; 140 if (that.notRecordedProbability != notRecordedProbability) { 141 return false; 142 } 143 if (that.pitems.length != pitems.length) { 144 return false; 145 } 146 for (int i = 0; i < pitems.length; ++i) { 147 if (!pitems[i].equals(that.pitems[i])) { 148 return false; 149 } 150 } 151 return true; 152 } 153 154 @Override 155 public int hashCode() { 156 return (int) Double.doubleToLongBits(notRecordedProbability) + pitems.length * 13; 157 } 158 }