001 /* 002 * This file is part of the Jikes RVM project (http://jikesrvm.org). 003 * 004 * This file is licensed to You under the Eclipse Public License (EPL); 005 * You may not use this file except in compliance with the License. You 006 * may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/eclipse-1.0.php 009 * 010 * See the COPYRIGHT.txt file distributed with this work for information 011 * regarding copyright ownership. 012 */ 013 package org.jikesrvm.adaptive.util; 014 015 import java.util.Collection; 016 import java.util.HashMap; 017 import java.util.List; 018 import java.util.ListIterator; 019 import org.jikesrvm.classloader.Atom; 020 import org.jikesrvm.classloader.RVMMethod; 021 import org.jikesrvm.compilers.common.CompiledMethod; 022 023 /** 024 * Defines an attribute for compiler advice, and maintains a map 025 * allowing attributes to be retrieved by method and bytecode offset. 026 * <p> 027 * Each attribute encodes an compiler site and the advice for that 028 * site: 029 * <ul> 030 * <li><code><class></code> <i>string</i> The name of the class</li> 031 * <li><code><method></code> <i>string</i> The name of the method</li> 032 * <li><code><signature></code> <i>string</i> The method signature</li> 033 * <li><code><advice></code> <i>in </i> The integer value for the 034 * compiler, as given in CompilerInfo</li> 035 * <li><code><optLevel></code> <i>in </i> The optimization level when 036 the Opt compiler is used 037 * </ul> 038 * 039 * 040 * @see CompilerAdvice 041 * @see CompilerAdviceInfoReader 042 */ 043 public class CompilerAdviceAttribute { 044 045 private static HashMap<CompilerAdviceAttribute, CompilerAdviceAttribute> attribMap = null; 046 private static CompilerAdviceAttribute defaultAttr = null; 047 private static CompilerAdviceAttribute tempAttr = null; 048 private static boolean hasAdvice = false; 049 050 private Atom className; // The name of the class for the compiler site 051 private Atom methodName; // The name of the method for the compiler site 052 private Atom methodSig; // The signature of the method 053 private int compiler; // The compiler to use for the method 054 private int optLevel; // The optimization level 055 056 /** 057 * Initialization of key compiler advice data structure. 058 */ 059 public static void postBoot() { 060 attribMap = new HashMap<CompilerAdviceAttribute, CompilerAdviceAttribute>(); 061 062 // With defaultAttr set up this way, methods will be BASELINE compiled 063 // *unless* they appear in the advice file. If defaultAttr is set to 064 // null, then methods will be compiled in the default way for the 065 // current build configuration *unless* they appear in the advice file. 066 defaultAttr = new CompilerAdviceAttribute(null, null, null, CompiledMethod.BASELINE); 067 tempAttr = new CompilerAdviceAttribute(null, null, null, CompiledMethod.BASELINE); 068 } 069 070 /** 071 * Getter method for class name 072 * 073 * @return the class name for this attribute 074 */ 075 public Atom getClassName() { return className; } 076 077 /** 078 * Getter method for method name 079 * 080 * @return the method name for this attribute 081 */ 082 public Atom getMethodName() { return methodName; } 083 084 /** 085 * Getter method for method signature 086 * 087 * @return the method signature for this attribute 088 */ 089 public Atom getMethodSig() { return methodSig; } 090 091 /** 092 * Getter method for compiler ID 093 * 094 * @return the compiler ID for this attribute 095 */ 096 public int getCompiler() { return compiler; } 097 098 /** 099 * Getter method for optimization level 100 * 101 * @return the optimization level for this attribute 102 */ 103 public int getOptLevel() { return optLevel; } 104 105 /** 106 * Constructor 107 * 108 * @param className The name of the class for the compiler site 109 * @param methodName The name of the method for the compiler site 110 * @param methodSig The signature of the method for the compiler site 111 * @param compiler The ID of the compiler to use for this method 112 * 113 * @see CompilerAdviceInfoReader 114 */ 115 public CompilerAdviceAttribute(Atom className, Atom methodName, Atom methodSig, int compiler) { 116 this.className = className; 117 this.methodName = methodName; 118 this.methodSig = methodSig; 119 this.compiler = compiler; 120 this.optLevel = -1; 121 } 122 123 /** 124 * Constructor 125 * 126 * @param className The name of the class for the compiler site 127 * @param methodName The name of the method for the compiler site 128 * @param methodSig The signature of the method for the compiler site 129 * @param compiler The ID of the compiler to use for this method 130 * @param optLevel The optimization level if using Opt compiler 131 * 132 * @see CompilerAdviceInfoReader 133 */ 134 public CompilerAdviceAttribute(Atom className, Atom methodName, Atom methodSig, int compiler, 135 int optLevel) { 136 this.className = className; 137 this.methodName = methodName; 138 this.methodSig = methodSig; 139 this.compiler = compiler; 140 this.optLevel = optLevel; 141 } 142 143 /** 144 * Stringify this instance 145 * 146 * @return The state of this instance expressed as a string 147 */ 148 @Override 149 public String toString() { 150 return ("Compiler advice: " + 151 className + 152 " " + 153 methodName + 154 " " + 155 methodSig + 156 " " + 157 compiler + 158 "(" + 159 optLevel + 160 ")"); 161 } 162 163 /** 164 * Use a list of compiler advice attributes to create an advice map 165 * keyed on <code>RVMMethod</code> instances. This map is used by 166 * <code>getCompilerAdviceInfo()</code>. 167 * 168 * @param compilerAdviceList A list of compiler advice attributes 169 * @see #getCompilerAdviceInfo 170 */ 171 public static void registerCompilerAdvice(List<CompilerAdviceAttribute> compilerAdviceList) { 172 // do nothing for empty list 173 if (compilerAdviceList == null) return; 174 175 hasAdvice = true; 176 177 // iterate over each element of the list 178 ListIterator<CompilerAdviceAttribute> it = compilerAdviceList.listIterator(); 179 while (it.hasNext()) { 180 // pick up an attribute 181 CompilerAdviceAttribute attr = it.next(); 182 attribMap.put(attr, attr); 183 // XXX if already there, should we warn the user? 184 } 185 } 186 187 /** 188 * Given a method and bytecode offset, return an compiler advice 189 * attribute or null if none is found for that method and offset. 190 * 191 * @param method The method containing the site in question 192 * @return Attribute advice for that site or null if none is found. 193 */ 194 public static CompilerAdviceAttribute getCompilerAdviceInfo(RVMMethod method) { 195 tempAttr.className = method.getDeclaringClass().getDescriptor(); 196 tempAttr.methodName = method.getName(); 197 tempAttr.methodSig = method.getDescriptor(); 198 CompilerAdviceAttribute value = attribMap.get(tempAttr); 199 200 if (value == null) { 201 return defaultAttr; 202 } else { 203 return value; 204 } 205 } 206 207 public static Collection<CompilerAdviceAttribute> values() { 208 return attribMap.values(); 209 } 210 211 public static boolean hasAdvice() { 212 return hasAdvice; 213 } 214 215 @Override 216 public boolean equals(Object obj) { 217 if (super.equals(obj)) { 218 return true; 219 } 220 221 if (obj instanceof CompilerAdviceAttribute) { 222 CompilerAdviceAttribute attr = (CompilerAdviceAttribute) obj; 223 if (attr.className == className && attr.methodName == methodName && attr.methodSig == methodSig) { 224 return true; 225 } 226 } 227 return false; 228 } 229 230 @Override 231 public int hashCode() { 232 return className.hashCode() ^ methodName.hashCode() ^ methodSig.hashCode(); 233 } 234 }