sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.ipc/src/com/nokia/carbide/cpp/pi/internal/ipc/IpcTraceParser.java
changeset 5 844b047e260d
child 12 ae255c9aa552
equal deleted inserted replaced
4:615035072f7e 5:844b047e260d
       
     1 /*
       
     2  * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). 
       
     3  * All rights reserved.
       
     4  * This component and the accompanying materials are made available
       
     5  * under the terms of the License "Eclipse Public License v1.0"
       
     6  * which accompanies this distribution, and is available
       
     7  * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8  *
       
     9  * Initial Contributors:
       
    10  * Nokia Corporation - initial contribution.
       
    11  *
       
    12  * Contributors:
       
    13  *
       
    14  * Description: 
       
    15  *
       
    16  */
       
    17 
       
    18 package com.nokia.carbide.cpp.pi.internal.ipc;
       
    19 
       
    20 import java.io.DataInputStream;
       
    21 import java.io.File;
       
    22 import java.io.FileInputStream;
       
    23 import java.io.FileNotFoundException;
       
    24 import java.io.IOException;
       
    25 import java.util.ArrayList;
       
    26 import java.util.HashMap;
       
    27 import java.util.List;
       
    28 import java.util.Map;
       
    29 
       
    30 import com.nokia.carbide.cpp.internal.pi.model.ParsedTraceData;
       
    31 import com.nokia.carbide.cpp.internal.pi.model.Parser;
       
    32 
       
    33 
       
    34 /**
       
    35  * Parser for performance counter event traces in binary format.
       
    36  * Converts parsed content into IpcSamples.
       
    37  */
       
    38 public class IpcTraceParser extends Parser {
       
    39 	private static final String IPC_EVENT_NOT_RECOGNISED = Messages.IpcTraceParser_0;
       
    40 	private static final int MAX_IPC_EVENTS_TRACED = 14; //2 IPC events * 5 possible values + 4 optional L2 counter values
       
    41 	private static final int MAX_IPC_NO_L2_EVENTS_TRACED = 10; //2 IPC events * 5 possible values
       
    42 	
       
    43 	
       
    44 	//private static int CPU_CLOCK_TICK_DIV64 = 0xFFFF;
       
    45 	private boolean debug = false; //CH: this could be replaced with Eclipse-style logging
       
    46 	private boolean l2Enabled = false;
       
    47 	
       
    48 	long time = 0;
       
    49 	
       
    50 	private static final Map<Integer, String> eventTypeTable = new HashMap<Integer, String>();
       
    51 	static {
       
    52 		eventTypeTable.put(0x0,Messages.IpcTraceParser_1);
       
    53 		eventTypeTable.put(0x1,Messages.IpcTraceParser_2);
       
    54 		eventTypeTable.put(0x2,Messages.IpcTraceParser_3);
       
    55 		eventTypeTable.put(0x3,Messages.IpcTraceParser_4);
       
    56 		eventTypeTable.put(0x4,Messages.IpcTraceParser_5);
       
    57 	}
       
    58 	private static final Map<Integer, String> counterTypeTable = new HashMap<Integer, String>();
       
    59 	static {
       
    60 		counterTypeTable.put(0x0,Messages.IpcTraceParser_6);
       
    61 		counterTypeTable.put(0x1,Messages.IpcTraceParser_7);
       
    62 		counterTypeTable.put(0x2,Messages.IpcTraceParser_8);
       
    63 		counterTypeTable.put(0x3,Messages.IpcTraceParser_9);
       
    64 		counterTypeTable.put(0x4,Messages.IpcTraceParser_10);
       
    65 		counterTypeTable.put(0x5,Messages.IpcTraceParser_11);
       
    66 	}	
       
    67 	private static final Map<Integer, String> l2EventTypeTable = new HashMap<Integer, String>();
       
    68 	static {
       
    69 		l2EventTypeTable.put(0x3,Messages.IpcTraceParser_12);
       
    70 		l2EventTypeTable.put(0x4,Messages.IpcTraceParser_13);
       
    71 		l2EventTypeTable.put(0x5,Messages.IpcTraceParser_14);
       
    72 		l2EventTypeTable.put(0x6,Messages.IpcTraceParser_15);
       
    73 		l2EventTypeTable.put(0x7,Messages.IpcTraceParser_16);
       
    74 		l2EventTypeTable.put(0xC,Messages.IpcTraceParser_17);
       
    75 		l2EventTypeTable.put(0xD,Messages.IpcTraceParser_18);
       
    76 	}			
       
    77 
       
    78 	/* (non-Javadoc)
       
    79 	 * @see com.nokia.carbide.cpp.internal.pi.model.Parser#parse(java.io.File)
       
    80 	 */
       
    81 	@Override
       
    82 	public ParsedTraceData parse(File file) throws Exception 
       
    83 	{
       
    84 		ParsedTraceData ptd = new ParsedTraceData();
       
    85 		ptd.functionResolvers = null;
       
    86 		ptd.staticData = null;
       
    87 		ptd.traceData = new IpcTrace();
       
    88 		doParsing(file,(IpcTrace)ptd.traceData);
       
    89 		time = 0;
       
    90 		
       
    91 		return ptd;
       
    92 	}
       
    93 	
       
    94 	private void doParsing(File f, IpcTrace trace) throws FileNotFoundException
       
    95  {
       
    96 		DataInputStream dis = new DataInputStream(new FileInputStream(f));
       
    97 		try {
       
    98 			int len = dis.readByte();
       
    99 			byte[] versionString = new byte[len];
       
   100 			dis.read(versionString);
       
   101 			this.traceVersion = new String(versionString);
       
   102 			if (debug){
       
   103 				System.out.println("IPC trace version:" + this.traceVersion); //$NON-NLS-1$				
       
   104 			}
       
   105 
       
   106 			List<Integer> counterTypes = new ArrayList<Integer>();
       
   107 			List<Integer> counterL2Types = new ArrayList<Integer>();
       
   108 
       
   109 			// IPC counters
       
   110 			int firstCounter = dis.readUnsignedByte();
       
   111 			counterTypes.add(firstCounter);
       
   112 			int secondCounter = dis.readUnsignedByte();
       
   113 			counterTypes.add(secondCounter);
       
   114 
       
   115 			// this type is always the cpu clock tick div 64
       
   116 			// int thirdData = CPU_CLOCK_TICK_DIV64;
       
   117 			// valueTypeVector.add(new Integer(thirdData));
       
   118 
       
   119 			if (dis.readUnsignedByte() != 0) {
       
   120 				// L2 counters, add if available
       
   121 				int thirdCounter = dis.readUnsignedByte();
       
   122 				counterL2Types.add(thirdCounter);
       
   123 				int fourthCounter = dis.readUnsignedByte();
       
   124 				counterL2Types.add(fourthCounter);
       
   125 				int fifthCounter = dis.readUnsignedByte();
       
   126 				counterL2Types.add(fifthCounter);
       
   127 				int sixthCounter = dis.readUnsignedByte();
       
   128 				counterL2Types.add(sixthCounter);
       
   129 
       
   130 				trace.setValueTypes(this.parseValueTypes(counterTypes, counterL2Types));
       
   131 			} else {
       
   132 				trace.setValueTypes(this.parseValueTypes(counterTypes, null));
       
   133 			}
       
   134 
       
   135 			// System.out.println("IPC first "+firstCounter+" second "+secondCounter);
       
   136 
       
   137 			IpcSample s = null;
       
   138 			while (true) {
       
   139 				s = readSample(dis, s);
       
   140 				// System.out.println(this.time+" "+Long.toHexString(s.values[0])+" "+Long.toHexString(s.values[1])+" "+Long.toHexString(s.values[2]));
       
   141 				trace.addSample(s);
       
   142 			}
       
   143 		} catch (IOException ioe) {
       
   144 			// CH: is this just caught for end-of-file condition?
       
   145 		}
       
   146 	}
       
   147 
       
   148 	private IpcSample readSample(DataInputStream dis, IpcSample prevSample)
       
   149 			throws IOException {
       
   150 		// int headerByte = (dis.readInt()); // << 24) >>> 24;
       
   151 		int headerByte1 = (dis.readByte() << 24) >>> 24;
       
   152 		int headerByte2 = (dis.readByte() << 24) >>> 24;
       
   153 		int headerByte3 = (dis.readByte() << 24) >>> 24;
       
   154 		int headerByte4 = (dis.readByte() << 24) >>> 24;
       
   155 		int headerByte = ((((headerByte1) | (headerByte2) << 8) | (headerByte3) << 16) | headerByte4 << 24);
       
   156 
       
   157 		int headerByte11 = 0;
       
   158 		int headerByte12 = 0;
       
   159 		int headerByteL2 = 0;
       
   160 		// int j = ((headerByte >>> 30)&1);
       
   161 		if (((headerByte >>> 30) & 1) != 0 || l2Enabled) // flag bit in trace =>
       
   162 															// L2 trace included
       
   163 		{
       
   164 			l2Enabled = true;
       
   165 			headerByte11 = (dis.readByte() << 24) >>> 24;
       
   166 			headerByte12 = (dis.readByte() << 24) >>> 24; // overflow bits
       
   167 			headerByteL2 = ((headerByte11) | ((headerByte12) << 8));
       
   168 		}
       
   169 
       
   170 		int eventNumber = l2Enabled ? MAX_IPC_EVENTS_TRACED
       
   171 				: MAX_IPC_NO_L2_EVENTS_TRACED;
       
   172 
       
   173 		int[] neg = new int[eventNumber];
       
   174 		int[] prev = new int[eventNumber];
       
   175 
       
   176 		if (prevSample != null) {
       
   177 			prev[0] = prevSample.values[0];
       
   178 			prev[1] = prevSample.values[1];
       
   179 			prev[2] = prevSample.values[2];
       
   180 			prev[3] = prevSample.values[3];
       
   181 			prev[4] = prevSample.values[4];
       
   182 			prev[5] = prevSample.values[5];
       
   183 			prev[6] = prevSample.values[6];
       
   184 			prev[7] = prevSample.values[7];
       
   185 			prev[8] = prevSample.values[8];
       
   186 			prev[9] = prevSample.values[9];
       
   187 			if (l2Enabled) {
       
   188 				prev[10] = prevSample.values[10];
       
   189 				prev[11] = prevSample.values[11];
       
   190 				prev[12] = prevSample.values[12];
       
   191 				prev[13] = prevSample.values[13];
       
   192 			}
       
   193 		}
       
   194 		// /*if(debug) if(this.time > 7820 && this.time < 7830)*/
       
   195 		// System.out.println("header: "+Long.toHexString(headerByte)+" = "+Integer.toBinaryString(headerByte));
       
   196 
       
   197 		if (((headerByte >>> 29) & 1) != 0) {
       
   198 			neg[0] = 1;
       
   199 		}
       
   200 
       
   201 		if (((headerByte >>> 28) & 1) != 0) {
       
   202 			neg[1] = 1;
       
   203 		}
       
   204 
       
   205 		if (((headerByte >>> 27) & 1) != 0) {
       
   206 			neg[2] = 1;
       
   207 		}
       
   208 		if (((headerByte >>> 26) & 1) != 0) {
       
   209 			neg[3] = 1;
       
   210 		}
       
   211 
       
   212 		if (((headerByte >>> 25) & 1) != 0) {
       
   213 			neg[4] = 1;
       
   214 		}
       
   215 
       
   216 		if (((headerByte >>> 24) & 1) != 0) {
       
   217 			neg[5] = 1;
       
   218 		}
       
   219 		if (((headerByte >>> 23) & 1) != 0) {
       
   220 			neg[6] = 1;
       
   221 		}
       
   222 
       
   223 		if (((headerByte >>> 22) & 1) != 0) {
       
   224 			neg[7] = 1;
       
   225 		}
       
   226 
       
   227 		if (((headerByte >>> 21) & 1) != 0) {
       
   228 			neg[8] = 1;
       
   229 		}
       
   230 		if (((headerByte >>> 20) & 1) != 0) {
       
   231 			neg[9] = 1;
       
   232 		}
       
   233 
       
   234 		// check overflows of L2 counters
       
   235 		if (l2Enabled) {
       
   236 			if (((headerByteL2 >>> 11) & 1) != 0) {
       
   237 				neg[10] = 1;
       
   238 			}
       
   239 
       
   240 			if (((headerByteL2 >>> 10) & 1) != 0) {
       
   241 				neg[11] = 1;
       
   242 			}
       
   243 
       
   244 			if (((headerByteL2 >>> 9) & 1) != 0) {
       
   245 				neg[12] = 1;
       
   246 			}
       
   247 			if (((headerByteL2 >>> 8) & 1) != 0) {
       
   248 				neg[13] = 1;
       
   249 			}
       
   250 
       
   251 		}
       
   252 
       
   253 		int[] len = new int[eventNumber];
       
   254 		len[0] = (((headerByte >> 18) << 30) >>> 30) + 1;
       
   255 		len[1] = (((headerByte >> 16) << 30) >>> 30) + 1;
       
   256 		len[2] = (((headerByte >> 14) << 30) >>> 30) + 1;
       
   257 		len[3] = (((headerByte >> 12) << 30) >>> 30) + 1;
       
   258 		len[4] = (((headerByte >> 10) << 30) >>> 30) + 1;
       
   259 		len[5] = (((headerByte >> 8) << 30) >>> 30) + 1;
       
   260 		len[6] = (((headerByte >> 6) << 30) >>> 30) + 1;
       
   261 		len[7] = (((headerByte >> 4) << 30) >>> 30) + 1;
       
   262 		len[8] = (((headerByte >> 2) << 30) >>> 30) + 1;
       
   263 		len[9] = (((headerByte) << 30) >>> 30) + 1;
       
   264 
       
   265 		if (l2Enabled) {
       
   266 			len[10] = (((headerByteL2 >> 6) << 30) >>> 30) + 1;
       
   267 			len[11] = (((headerByteL2 >> 4) << 30) >>> 30) + 1;
       
   268 			len[12] = (((headerByteL2 >> 2) << 30) >>> 30) + 1;
       
   269 			len[13] = ((headerByteL2 << 30) >>> 30) + 1;
       
   270 		}
       
   271 		if (debug)
       
   272 			if (this.time > 7820 && this.time < 7830)
       
   273 				System.out.println("T:" + this.time + " len0:" + len[0] + " len1:" + len[1] + " len2:" + len[2]); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
       
   274 		if (debug)
       
   275 			if (this.time > 7900 && this.time < 7900)
       
   276 				System.out.println("H: " + Integer.toBinaryString(headerByte) + " N0:" + neg[0] + " N1:" + neg[1] + " N2:" + neg[2]); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ //$NON-NLS-4$
       
   277 
       
   278 		int[] val = new int[eventNumber];
       
   279 		val[0] = readVal(neg[0], len[0], dis);
       
   280 		val[1] = readVal(neg[1], len[1], dis);
       
   281 		val[2] = readVal(neg[2], len[2], dis);
       
   282 		val[3] = readVal(neg[3], len[3], dis);
       
   283 		val[4] = readVal(neg[4], len[4], dis);
       
   284 		val[5] = readVal(neg[5], len[5], dis);
       
   285 		val[6] = readVal(neg[6], len[6], dis);
       
   286 		val[7] = readVal(neg[7], len[7], dis);
       
   287 		val[8] = readVal(neg[8], len[8], dis);
       
   288 		val[9] = readVal(neg[9], len[9], dis);
       
   289 
       
   290 		if (l2Enabled) {
       
   291 			val[10] = readVal(neg[10], len[10], dis);
       
   292 			val[11] = readVal(neg[11], len[11], dis);
       
   293 			val[12] = readVal(neg[12], len[12], dis);
       
   294 			val[13] = readVal(neg[13], len[13], dis);
       
   295 		}
       
   296 
       
   297 		if (debug)
       
   298 			if (this.time > 7820 && this.time < 7900)
       
   299 				System.out.println("READ T:" + this.time + "   V0:" + Integer.toHexString(val[0]) + " V1:" + Long.toHexString(val[1]) + " V2:" + Long.toHexString(val[2])); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
       
   300 		for (int i = 0; i < eventNumber; i++) {
       
   301 			val[i] = prev[i] - val[i];
       
   302 		}
       
   303 
       
   304 		IpcSample ps = new IpcSample(val, this.time);
       
   305 
       
   306 		if (debug)
       
   307 			if (this.time > 7820 && this.time < 7900)
       
   308 				System.out.println("T:" + this.time + "   V0:" + Long.toHexString(val[0]) + " V1:" + Long.toHexString(val[1]) + " V2:" + Long.toHexString(val[2])); //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$ //$NON-NLS-4$
       
   309 		if (debug)
       
   310 			if (this.time > 7820 && this.time < 7900)
       
   311 				System.out.println("T:" + this.time + " " + val[0] + " " + val[1] + " " + val[2]); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ //$NON-NLS-4$
       
   312 		this.time++;
       
   313 		/*
       
   314 		 * dis.readByte(); dis.readByte(); dis.readByte(); dis.readByte();
       
   315 		 */
       
   316 		return ps;
       
   317 	}
       
   318 
       
   319 	private int readVal(int neg,int len,DataInputStream dis) throws IOException
       
   320 	{
       
   321 		byte[] array = new byte[len];
       
   322 		dis.read(array);
       
   323 		
       
   324 		//System.out.println("array: "+array);
       
   325 		
       
   326 		if(debug)
       
   327 			for(int k=0;k<array.length;k++)
       
   328 			{
       
   329 				if(this.time > 7820 && this.time < 7900) System.out.println(" "+Integer.toHexString(array[k])); //$NON-NLS-1$
       
   330 			}
       
   331 		
       
   332 		long total = 0;
       
   333 		for(int i=0;i<len;i++)
       
   334 		{
       
   335 			int value = ((array[i] << 24) >>> 24) << (i*8);			
       
   336 			total |= value;
       
   337 		}
       
   338 		
       
   339 		if(debug) if(this.time > 7820 && this.time < 7900) System.out.println("\n"+Long.toHexString(total)); //$NON-NLS-1$
       
   340 
       
   341 		if(debug) if(this.time > 7820 && this.time < 7900) System.out.println("T:"+this.time+" "+Long.toHexString(total));  //$NON-NLS-1$//$NON-NLS-2$
       
   342 		
       
   343 		if(neg != 0) total = ~total;
       
   344 		
       
   345 		return (int)total;
       
   346 	}
       
   347 		
       
   348 	private String[] parseValueTypes(List<Integer> counterTypes, List<Integer> counterL2Types){
       
   349 		String[] s = new String[counterTypes.size() * eventTypeTable.size() + (counterL2Types == null ? 0 : counterL2Types.size())];
       
   350 		int k = 0;
       
   351 		for (int i = 0; i < eventTypeTable.size(); i++) {
       
   352 			String eventType =  eventTypeTable.get(i);
       
   353 			for (Integer counterType : counterTypes) {
       
   354 				s[k] = String.format(Messages.IpcTraceParser_20, eventType, convertCounterType(counterType));
       
   355 				k++;
       
   356 			}
       
   357 		}
       
   358 		
       
   359 		if (counterL2Types != null){
       
   360 			for (Integer l2Type : counterL2Types) {
       
   361 				s[k] = convertL2EventType(l2Type);
       
   362 				k++;				
       
   363 			}
       
   364 		}
       
   365 		return s;
       
   366 	}
       
   367 	
       
   368 	private String convertL2EventType(Integer value) {
       
   369 		String s = IpcTraceParser.l2EventTypeTable.get(value);
       
   370 		if (s == null) {
       
   371 			s = String.format(IPC_EVENT_NOT_RECOGNISED, value);
       
   372 		}
       
   373 		return s;
       
   374 	}
       
   375 	
       
   376 	private String convertCounterType(Integer value) {
       
   377 		String s = IpcTraceParser.counterTypeTable.get(value);
       
   378 		if (s == null) {
       
   379 			s = String.format(IPC_EVENT_NOT_RECOGNISED, value);
       
   380 		}
       
   381 		return s;
       
   382 	}
       
   383 }