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 retrived 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 public String toString() {
149 return ("Compiler advice: " +
150 className +
151 " " +
152 methodName +
153 " " +
154 methodSig +
155 " " +
156 compiler +
157 "(" +
158 optLevel +
159 ")");
160 }
161
162 /**
163 * Use a list of compiler advice attributes to create an advice map
164 * keyed on <code>RVMMethod</code> instances. This map is used by
165 * <code>getCompilerAdviceInfo()</code>.
166 *
167 * @param compilerAdviceList A list of compiler advice attributes
168 * @see #getCompilerAdviceInfo
169 */
170 public static void registerCompilerAdvice(List<CompilerAdviceAttribute> compilerAdviceList) {
171 // do nothing for empty list
172 if (compilerAdviceList == null) return;
173
174 hasAdvice = true;
175
176 // iterate over each element of the list
177 ListIterator<CompilerAdviceAttribute> it = compilerAdviceList.listIterator();
178 while (it.hasNext()) {
179 // pick up an attribute
180 CompilerAdviceAttribute attr = it.next();
181 attribMap.put(attr, attr);
182 // XXX if already there, should we warn the user?
183 }
184 }
185
186 /**
187 * Given a method and bytecode offset, return an compiler advice
188 * attribute or null if none is found for that method and offset.
189 *
190 * @param method The method containing the site in question
191 * @return Attribute advice for that site or null if none is found.
192 */
193 public static CompilerAdviceAttribute getCompilerAdviceInfo(RVMMethod method) {
194 tempAttr.className = method.getDeclaringClass().getDescriptor();
195 tempAttr.methodName = method.getName();
196 tempAttr.methodSig = method.getDescriptor();
197 CompilerAdviceAttribute value = attribMap.get(tempAttr);
198
199 if (value == null) {
200 return defaultAttr;
201 } else {
202 return value;
203 }
204 }
205
206 public static Collection<CompilerAdviceAttribute> values() {
207 return attribMap.values();
208 }
209
210 public static boolean hasAdvice() {
211 return hasAdvice;
212 }
213
214 public boolean equals(Object obj) {
215 if (super.equals(obj)) {
216 return true;
217 }
218
219 if (obj instanceof CompilerAdviceAttribute) {
220 CompilerAdviceAttribute attr = (CompilerAdviceAttribute) obj;
221 if (attr.className == className && attr.methodName == methodName && attr.methodSig == methodSig) {
222 return true;
223 }
224 }
225 return false;
226 }
227
228 public int hashCode() {
229 return className.hashCode() ^ methodName.hashCode() ^ methodSig.hashCode();
230 }
231 }