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