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.StringTokenizer;
020 import org.jikesrvm.VM;
021 import org.jikesrvm.adaptive.controller.Controller;
022 import org.jikesrvm.adaptive.database.callgraph.PartialCallGraph;
023 import org.jikesrvm.classloader.RVMClassLoader;
024 import org.jikesrvm.classloader.MemberReference;
025 import org.jikesrvm.classloader.RVMMethod;
026 import org.jikesrvm.classloader.MethodReference;
027
028 /**
029 * Utility to read dynamic call graph annotations from file in ascii format.
030 * Takes a single argument: the name of the file containing the ascii
031 * annotations. Each line of the file corresponds to an annotation
032 * for one method and has the following format:
033 * <p>
034 * <pre>
035 * CallSite < classloader, classname, method, signature> method_size byte_code_index <callee_classloader, classname, method, signature> method_size weight: weight
036 * </pre>
037 * Where the types and meanings of the fields is as follows:
038 * <ul>
039 * <li><code><signature></code> <i>string</i> The method signature</li>
040 * </ul>
041 *
042 *
043 * @see CompilerAdvice
044 */
045 public class DynamicCallFileInfoReader {
046
047 /**
048 * Read annoations from a specified file. Reads all annotations at
049 * once and returns a collection of compiler advice attributes.
050 *
051 * @param file The annoation file to be read
052 */
053 public static void readDynamicCallFile(String file, boolean boot) {
054 BufferedReader fileIn = null;
055
056 if (file == null) return;// null;
057
058 if ((!VM.runningVM) && (Controller.dcg == null)) {
059 Controller.dcg = new PartialCallGraph(300);
060 } else if (Controller.dcg == null) {
061 System.out.println("dcg is null ");
062 return;
063 }
064 try {
065 fileIn = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));
066 try {
067 for (String s = fileIn.readLine(); s != null; s = fileIn.readLine()) {
068 StringTokenizer parser = new StringTokenizer(s, " \n,");
069 readOneCallSiteAttribute(parser, boot);
070 }
071 } catch (IOException e) {
072 e.printStackTrace();
073 VM.sysFail("Error parsing input dynamic call graph file" + file);
074 }
075 fileIn.close();
076 } catch (java.io.FileNotFoundException e) {
077 System.out.println("IO: Couldn't read compiler advice attribute file: " + file + e);
078 } catch (java.io.UnsupportedEncodingException e) {
079 System.out.println("IO: UTF-16 is not supported: " + e);
080 } catch (IOException e) {
081 VM.sysFail("Error closing input dynamic call graph file" + file);
082 }
083
084 }
085
086 private static void readOneCallSiteAttribute(StringTokenizer parser, boolean boot) {
087 String firstToken = parser.nextToken();
088 if (firstToken.equals("CallSite")) {
089 MemberReference callerKey = MemberReference.parse(parser, boot);
090 if (callerKey == null) return;
091 MethodReference callerRef = callerKey.asMethodReference();
092 RVMMethod caller, callee;
093 if (callerRef.getType().getClassLoader() == RVMClassLoader.getApplicationClassLoader()) {
094 caller = callerRef.resolve();
095 } else {
096 caller = callerRef.getResolvedMember();
097 }
098 //if (caller == null) continue;
099 @SuppressWarnings("unused") // serves as doco - token skipped
100 int callerSize = Integer.parseInt(parser.nextToken());
101 int bci = Integer.parseInt(parser.nextToken());
102 MemberReference calleeKey = MemberReference.parse(parser, boot);
103 if (calleeKey == null) return;
104 MethodReference calleeRef = calleeKey.asMethodReference();
105 //if (callee == null) continue;
106 if (calleeRef.getType().getClassLoader() == RVMClassLoader.getApplicationClassLoader()) {
107 callee = calleeRef.resolve();
108 } else {
109 callee = calleeRef.getResolvedMember();
110 }
111 @SuppressWarnings("unused") // serves as doco - token skipped
112 int calleeSize = Integer.parseInt(parser.nextToken());
113 parser.nextToken(); // skip "weight:"
114 float weight = Float.parseFloat(parser.nextToken());
115 if ((caller == null) || (callee == null)) {
116 Controller.dcg.incrementUnResolvedEdge(callerRef, bci, calleeRef, weight);
117 } else {
118 Controller.dcg.incrementEdge(caller, bci, callee, weight);
119 }
120 } else {
121 VM.sysFail("Format error in dynamic call graph file");
122 }
123 }
124 }
125
126
127
128
129