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.io.BufferedReader;
016 import java.io.FileInputStream;
017 import java.io.IOException;
018 import java.io.InputStreamReader;
019 import java.util.ArrayList;
020 import java.util.List;
021 import java.util.NoSuchElementException;
022 import java.util.StringTokenizer;
023 import org.jikesrvm.VM;
024 import org.jikesrvm.classloader.Atom;
025
026 /**
027 * Utility to read compiler advice annotations from file in ascii format.
028 * Takes a single argument: the name of the file containing the ascii
029 * annotations. Each line of the file corresponds to an annotation
030 * for one method and has the following format:
031 * <p>
032 * <pre>
033 * <class> <method> <signature> <advice> <optLevel>
034 * </pre>
035 * Where the types and meanings of the fields is as follows:
036 * <ul>
037 * <li><code><class></code> <i>string</i> The name of the class</li>
038 * <li><code><method></code> <i>string</i> The name of the method</li>
039 * <li><code><signature></code> <i>string</i> The method signature</li>
040 * <li><code><advice></code> <i>int</i> The compiler type to be used --
041 * an integer value corresponding to the compiler enumeration in
042 CompiledMethod</li>
043 * <li><code><optLevel></code> <i>int</i> (Optional) The opt level to use
044 if compiler is optimizing compiler</li>
045 * </ul>
046 *
047 *
048 * @see CompilerAdvice
049 * @see CompilerAdviceAttribute
050 */
051 class CompilerAdviceInfoReader {
052
053 /**
054 * Read annoations from a specified file. Reads all annotations at
055 * once and returns a collection of compiler advice attributes.
056 *
057 * @param file The annoation file to be read
058 * @return A list of compileration advice attributes
059 */
060 public static List<CompilerAdviceAttribute> readCompilerAdviceFile(String file) {
061 List<CompilerAdviceAttribute> compilerAdviceInfo = new ArrayList<CompilerAdviceAttribute>();
062 BufferedReader fileIn = null;
063
064 if (file == null) return null;
065
066 try {
067 fileIn = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));
068
069 try {
070 for (String s = fileIn.readLine(); s != null; s = fileIn.readLine()) {
071 StringTokenizer parser = new StringTokenizer(s, " \n,");
072 compilerAdviceInfo.add(readOneAttribute(parser));
073
074 }
075 } catch (IOException e) {
076 e.printStackTrace();
077 VM.sysFail("Error parsing input compilation advice file " + file);
078 }
079
080 fileIn.close();
081 } catch (java.io.FileNotFoundException e) {
082 System.out.println("IO: Couldn't read compiler advice attribute file: " + file + e);
083 return null;
084 } catch (java.io.UnsupportedEncodingException e) {
085 System.out.println("IO: UTF-8 is not supported: " + e);
086 return null;
087 } catch (java.io.IOException e) {
088 System.out.println("IO: Couldn't close compiler advice attribute file: " + file + e);
089 return null;
090 }
091
092 return compilerAdviceInfo;
093 }
094
095 /**
096 * Actual reading is done here. This method reads one attribute
097 * from a single line of an input stream. There are six elements
098 * per line corresponding to each call site. First three are
099 * strings, <i>class name</i>, <i>method name</i>, <i>method
100 * signature</i>, followed by one number,
101 * <i>compiler advice</i>.
102 *
103 * @param st an input stream
104 * @return an compileration advice atribute
105 */
106 private static CompilerAdviceAttribute readOneAttribute(StringTokenizer st) {
107 int compiler, optLevel = -1;
108
109 try {
110 Atom cls = Atom.findOrCreateUnicodeAtom(st.nextToken());
111 Atom mth = Atom.findOrCreateUnicodeAtom(st.nextToken());
112 Atom sig = Atom.findOrCreateUnicodeAtom(st.nextToken());
113 compiler = Integer.parseInt(st.nextToken());
114 optLevel = Integer.parseInt(st.nextToken());
115 // this is the attribute which will be returned
116 CompilerAdviceAttribute newAttrib;
117
118 if (optLevel >= 0) {
119 newAttrib = new CompilerAdviceAttribute(cls, mth, sig, compiler, optLevel);
120 } else {
121 newAttrib = new CompilerAdviceAttribute(cls, mth, sig, compiler);
122 }
123
124 return newAttrib;
125 } catch (NoSuchElementException e) {
126 return null;
127 }
128
129 }
130 }