001    package EVolve;
002    
003    import java.io.IOException;
004    import java.io.RandomAccessFile;
005    import java.util.ArrayList;
006    import java.util.Stack;
007    import it.unimi.dsi.fastUtil.*;
008    
009    public class DemoData {
010            private RandomAccessFile dataInFile, dataOutFile, insInFile, insOutFile;
011    
012            private ArrayList classList, threadList, locationList;
013            private ArrayList methodUsed;
014    
015            private Object2ObjectHashMap methodDefined;
016            private Object2ObjectHashMap classIdToClass;
017            private Int2ObjectHashMap methodIdToClassId;
018    
019            private Object2ObjectHashMap stackList;
020            private Stack methodsStack;
021    
022            private int allocationEvents = 0;
023            private int invocationEvents = 0;
024    
025            private DemoData(String dataInFileName, String dataOutFileName, String insInFileName, String insOutFileName) {
026                    try {
027                            dataInFile = new RandomAccessFile(dataInFileName, "r");
028                            dataOutFile = new RandomAccessFile(dataOutFileName, "rw");
029                            //insInFile = new RandomAccessFile(insInFileName,"r");
030                            //insOutFile = new RandomAccessFile(insOutFileName,"rw");
031                    } catch (IOException e) {
032                            System.out.println("I/O error.");
033                    }
034    
035                    classList = new ArrayList();
036                    threadList = new ArrayList();
037                    locationList = new ArrayList();    
038                    methodDefined = new Object2ObjectHashMap();
039                    classIdToClass = new Object2ObjectHashMap();
040                    methodUsed = new ArrayList();
041                    methodIdToClassId = new Int2ObjectHashMap();
042                    methodsStack = new Stack();
043                    stackList = new Object2ObjectHashMap();
044                    //locationList.add("Unknown_location");
045                    //classList.add("Unknown_type");
046            }
047    
048            private void process() {
049                    try {
050                            step1();
051                            step2();
052    
053                            dataInFile.close();
054                            dataOutFile.close();
055                    } catch (IOException e) {
056                            System.out.println("I/O error.");
057                    }
058            }
059    
060            private String getSub(String line, int part) {
061                    int start = line.indexOf(' ') + 1;
062                    int i = 1;
063                    while (i < part) {
064                            start = line.indexOf(' ', start) + 1;
065                            i++;
066                    }
067                    int end = line.indexOf(' ', start);
068                    if (end == -1) {
069                            return line.substring(start);
070                    } else {
071                            return line.substring(start, end);
072                    }
073            }
074    
075            private void methodPush(String thread, String methodIndex) {
076                    methodsStack = (Stack)stackList.get(thread);
077                    if (threadList.indexOf(thread) == -1) {
078                            threadList.add(thread);
079                            methodsStack = new Stack();
080                            stackList.put(thread,methodsStack);
081                    }
082                    methodsStack.push(methodIndex);
083            }
084    
085            private int methodPop(String thread, String methodIndex) {
086                    int stackSize = 0;
087                    methodsStack = (Stack)stackList.get(thread);
088                    if (threadList.indexOf(thread) == -1) {
089                            threadList.add(thread);
090                            methodsStack = new Stack();
091                            stackList.put(thread,methodsStack);
092                    }
093                    stackSize = methodsStack.size();
094    
095                    if ((methodsStack.size()>0) && (methodIndex.equals(methodsStack.get(methodsStack.size()-1)))) {
096                            methodsStack.pop();
097                    }
098    
099                    return stackSize;
100            }
101    
102            private String getStackTop(String thread) {
103                    String top = null;
104                    methodsStack = (Stack)stackList.get(thread);
105    
106                    if ((methodsStack!=null)&&(methodsStack.size()>0)) {
107                            //top = (String)methodsStack.get(methodsStack.size()-1);
108                            top = (String)methodsStack.peek();
109                    }
110    
111                    return top;
112            }
113    
114            private void clearStack() {
115                    for (int i=0; i<threadList.size(); i++) {
116                            methodsStack =(Stack) stackList.get(threadList.get(i));
117                            methodsStack.clear();
118                    }
119                    methodsStack = null;
120            }
121    
122            private String getClassName(String method) {
123                    String strClassId = (String) methodIdToClassId.get(Integer.parseInt(method));
124                    return (String) classIdToClass.get(strClassId);
125            }
126    
127            private String getClassNamebyClassId(String classId) {
128                    String className = (String)classIdToClass.get(classId);
129    
130                    if (className == null)
131                            return "";
132    
133                    return className;
134            }
135    
136            private void step1() throws IOException {
137                    int unknownCounter = 0;
138                    System.out.println("Step 1...");
139    
140                    classIdToClass.put("boolean","boolean[]");
141                    classIdToClass.put("byte","byte[]");
142                    classIdToClass.put("char","char[]");
143                    classIdToClass.put("short","short[]");
144                    classIdToClass.put("int","int[]");
145                    classIdToClass.put("long","long[]");
146                    classIdToClass.put("float","float[]");
147                    classIdToClass.put("double","double[]");
148    
149    
150                    String line = dataInFile.readLine();
151                    while (line != null) {
152                            if (line.lastIndexOf(": ") == 1) {
153                                    line = line.trim();
154                                    char ch = line.charAt(0);
155                                    if (ch == 'C') {
156                                            classIdToClass.put(getSub(line,2),getSub(line,1));
157                                            classList.add(getSub(line,1));
158                                    } else if (ch == 'M') {
159                                            String classId = getSub(line,3);
160                                            methodIdToClassId.put(Integer.parseInt(getSub(line,2)),classId);
161                                            methodDefined.put(getSub(line, 2),getSub(line,1));
162                                    } else if (ch == '+') {
163                                            String methodId = getSub(line, 4);
164                                            String thread = getSub(line,2);
165                                            methodPush(thread,methodId);
166                                            if (!methodDefined.containsKey(methodId)) {
167                                                    methodDefined.put(methodId,"Unknown_method_"+unknownCounter);
168                                                    unknownCounter++;
169                                            }
170                                            if (methodUsed.indexOf(methodId)==-1) {
171                                                    methodUsed.add(methodId);
172                                            }
173                                            invocationEvents++;
174                                    } else if (ch == '-') {
175                                            String methodId = getSub(line, 4);
176                                            String thread = getSub(line,2);
177                                            methodPop(thread,methodId);
178                                            if (methodUsed.indexOf(methodId)==-1) {
179                                                    methodUsed.add(methodId);
180                                            }
181                                    } else if (ch == 'O') {
182                                            allocationEvents++;
183                                    }
184                            }
185                            line = dataInFile.readLine();
186                    }
187            }
188    
189            private void step2() throws IOException {
190                    ArrayList unknowMethodList = new ArrayList();
191                    Object2ObjectHashMap dupMethods = new Object2ObjectHashMap();
192                    int unknownCounter = 0;
193                    int unknownReturn = 0, unknownEnter = 0;
194                    int Enter = 0, Return = 0;
195                    System.out.println("Step 2...");
196    
197                    dataOutFile.setLength(0);
198    
199                    clearStack();
200    
201                    //write("H: invocation " + invocationEvents);
202                    //write("H: allocation " + allocationEvents);
203    
204                    for (int i = 0; i < threadList.size(); i++) {
205                            write("T: Thread" + i + " " + i);
206                    }
207    
208                    //write("C: Unknown_type 0");
209                    //write("L: Unknown_location 0");
210    
211                    int firstBytecode = -1;
212    
213                    dataInFile.seek(0);
214                    String line = dataInFile.readLine();
215                    int lastClass = 0;
216                    String lastClassName = "";
217    
218                    while (line != null) {
219                            if (line.lastIndexOf(": ") == 1) {
220                                    line = line.trim();
221                                    char ch = line.charAt(0);
222                                    if (ch == 'C') {
223                                            int index = classList.indexOf(getSub(line, 1));
224                                            if (index != -1) {
225                                                    write("C: " + getSub(line, 1) + " " + index);
226                                                    lastClass = index;
227                                                    lastClassName = getSub(line, 1);
228                                            } else {
229                                                    write("C: " + getSub(line,1) + " " + classList.size());
230                                                    classList.add(getSub(line,1));
231                                            }
232                                    } else if (ch == 'M') {
233                                            String methodId = getSub(line,2);
234                                            int index = methodUsed.indexOf(methodId);
235                                            if (index != -1) {
236                                                    String fullName = lastClassName+"."+restoreMethod((String)methodDefined.get(methodId));
237                                                    //if (!dupMethods.containsKey(fullName)) {
238                                                    write("M: " + fullName + " " + index + " " + lastClass);
239                                                    dupMethods.put(fullName,methodId);
240                                                    /*} else {
241                                                            int ii = 0;
242                                                            ii++;
243                                                    }*/
244                                            }
245    
246                                    } else if (ch == '+') {
247                                            String thread = getSub(line,2);
248                                            int threadIndex = threadList.indexOf(thread);
249                                            if (threadIndex != -1) {
250                                                    Enter ++;
251    
252                                                    String method = getSub(line, 4);
253                                                    String caller = getStackTop(thread);
254                                                    methodPush(thread,method); // in this method we set methodsStack to the current using method stack
255                                                    int methodIndex = methodUsed.indexOf(method);
256                                                    String className = "";
257    
258                                                    className = getClassName(method);
259    
260                                                    if (((String)methodDefined.get(method)).indexOf("Unknown_method_")==-1) {
261                                                            String fullName = className+"."+restoreMethod((String)methodDefined.get(method));
262                                                            methodIndex = methodUsed.indexOf(dupMethods.get(fullName));
263                                                            int index = unknowMethodList.indexOf(method);
264                                                            if (index != -1) {
265                                                                    unknowMethodList.remove(index);
266                                                            }
267                                                    }
268                                                    else {
269                                                            unknownEnter++;
270                                                            if (unknowMethodList.indexOf(method) ==-1) unknowMethodList.add(method);
271                                                    }
272    
273                                                    if (methodsStack.size() > 0) {
274                                                            if (firstBytecode == -1) {
275                                                                    firstBytecode = Integer.parseInt(getSub(line, 1)) + 1;
276                                                            }
277                                                            String location = "Unknown_location";
278                                                            if ((caller != null) && methodDefined.containsKey(caller)) {
279                                                                    String callerName = (String) methodDefined.get(caller);
280                                                                    className = getClassName(caller);
281                                                                    if (className.length() > 0)
282                                                                            location = className + "." + restoreMethod(callerName) + "_#" + getSub(line, 3);
283                                                                    else
284                                                                            location = callerName + "_#" + getSub(line,3);
285                                                            }
286                                                            int locationIndex = locationList.indexOf(location);
287                                                            if (locationIndex == -1) {
288                                                                    locationList.add(location);
289                                                                    locationIndex = locationList.indexOf(location);
290                                                                    write("L: " + location + " " + locationIndex);
291                                                            }
292                                                            if (methodIndex != -1)
293                                                                    write("+: " + (Integer.parseInt(getSub(line, 1)) -  firstBytecode + 1) + " " + threadIndex + " " + methodIndex + " " + locationIndex);
294    
295                                                    }
296                                            }
297                                    } else if (ch == '-') {
298                                            String thread = getSub(line,2);
299                                            int threadIndex = threadList.indexOf(thread);
300                                            if (threadIndex != -1) {
301                                                    Return++;
302    
303                                                    String method = getSub(line, 4);
304                                                    int stackSize = methodPop(thread,method); // in this method we set methodsStack to the current using method stack
305                                                    String caller = getStackTop(thread);
306    
307                                                    int methodIndex = methodUsed.indexOf(method);
308                                                    String className = "";
309                                                    if (!methodDefined.containsKey(method)) {
310                                                            methodDefined.put(method,"Unknown_method_"+unknownCounter);
311                                                            unknownCounter++;
312                                                    }
313    
314                                                    className = getClassName(method);
315                                                    if (((String)methodDefined.get(method)).indexOf("Unknown_method_")==-1) {
316                                                            String fullName = className+"."+restoreMethod((String)methodDefined.get(method));
317                                                            methodIndex = methodUsed.indexOf(dupMethods.get(fullName));
318                                                            int index = unknowMethodList.indexOf(method);
319                                                            if (index != -1)
320                                                                    unknowMethodList.remove(index);
321                                                    }
322                                                    else {
323                                                            unknownReturn++;
324                                                            if (unknowMethodList.indexOf(method) ==-1) unknowMethodList.add(method);
325                                                    }
326    
327                                                    if (stackSize - methodsStack.size() == 1) {
328                                                            if (firstBytecode == -1) {
329                                                                    firstBytecode = Integer.parseInt(getSub(line, 1));
330                                                            }
331                                                            String location = "Unknown_location";
332                                                            if ((caller != null) && methodDefined.containsKey(caller)) {
333                                                                    String callerName = (String) methodDefined.get(caller);
334                                                                    className = getClassName(caller);
335                                                                    if (className.length() > 0)
336                                                                            location = className + "." + restoreMethod(callerName) + "_#" + getSub(line, 3);
337                                                                    else
338                                                                            location = callerName + "_#" + getSub(line,3);
339                                                            }
340                                                            int locationIndex = locationList.indexOf(location);
341                                                            if (locationIndex == -1) {
342                                                                    locationList.add(location);
343                                                                    locationIndex = locationList.indexOf(location);
344                                                                    write("L: " + location + " " + locationIndex);
345                                                            }
346                                                            if (methodIndex != -1) {
347                                                                    write("-: " + (Integer.parseInt(getSub(line, 1)) -  firstBytecode) + " " + threadIndex + " " + methodIndex + " " + locationIndex);
348                                                            }
349                                                    }
350                                            }
351                                    } else if (ch == 'O') {
352                                            String thread = getSub(line,2);
353                                            String typeId = getSub(line,4);
354                                            int threadIndex = threadList.indexOf(thread);
355                                            String method = getStackTop(thread);
356    
357                                            if ((threadIndex != -1)&&(methodsStack.size()>0)) {
358    
359                                                    int classIndex = classList.indexOf(getClassNamebyClassId(typeId));
360                                                    int methodIndex = methodUsed.indexOf(method);
361    
362                                                    if ((methodIndex == -1)&&(methodDefined.containsKey(method))) {
363                                                            methodIndex = methodUsed.size();
364                                                            methodUsed.add(method);
365                                                    }
366    
367                                                    if ((classIndex == -1)&&(classIdToClass.containsKey(typeId))) {
368                                                            classIndex = classList.size();
369                                                            String className = getClassNamebyClassId(typeId);
370                                                            write("C: " + className + " " + classIndex);
371                                                            classList.add(className);
372                                                    }
373    
374                                                    if ((classIndex != -1)) {
375    
376                                                            if (firstBytecode == -1) {
377                                                                    firstBytecode = Integer.parseInt(getSub(line, 1));
378                                                            }
379    
380                                                            if (methodIndex != -1) {
381                                                                    String callerName = (String) methodDefined.get(method);
382                                                                    String className = (String)classIdToClass.get(methodIdToClassId.get(Integer.parseInt(method)));//"";
383                                                                    String location;
384                                                                    if (className != null)
385                                                                            location = className+"."+restoreMethod(callerName) + "_#" + getSub(line, 3);
386                                                                    else
387                                                                            location = callerName + "_#" + getSub(line, 3);
388                                                                    int locationIndex = locationList.indexOf(location);
389                                                                    if (locationIndex == -1) {
390                                                                            locationList.add(location);
391                                                                            locationIndex = locationList.indexOf(location);
392                                                                            write("L: " + location + " " + locationIndex);
393                                                                    }
394    
395                                                                    write("O: " + (Integer.parseInt(getSub(line, 1)) - firstBytecode + 1)+ " " + threadIndex + " " +
396                                                                              methodIndex + " " + locationIndex + " " + classIndex + " " + getSub(line, 5));
397                                                            } else {
398                                                                    System.out.println("ooops..., method unknown");
399                                                                    write("O: " + (Integer.parseInt(getSub(line, 1)) - firstBytecode )+ " " + threadIndex + " " +
400                                                                              0 + " " + 0 + " " + classIndex + " " + getSub(line, 5));
401                                                            }
402                                                    } else {
403                                                            System.out.println("ooops..., object unknown!");
404                                                    }
405    
406                                            }
407                                    }
408                            }
409                            line = dataInFile.readLine();
410                    }
411    
412                    for (int i = 0; i< unknowMethodList.size(); i++) {
413                            String method = (String)unknowMethodList.get(i);
414                            write("M: " + (String)methodDefined.get(method) + " " + methodUsed.indexOf(method) + " 0");
415                    }
416    
417    
418                    System.out.println("Method Defined: "+ methodDefined.size()+", Method Used: "+methodUsed.size());
419                    System.out.println("Method NOT Resolved: "+ unknowMethodList.size());
420                    System.out.println("Resolve Percert: "+(1-(float)unknowMethodList.size()/(float)methodUsed.size())*100+"%");
421    
422                    System.out.println("Method enter events: "+ Enter + ", which contains " + unknownEnter + " unknown enter events.");
423                    System.out.println("Method exit events: "+ Return + ", which contains " + unknownReturn + " unknown exit events.");
424                    System.out.println("Unknown Percert: "+((float)(unknownEnter+unknownReturn)/(float)(Enter+Return))*100+"%");
425    
426                    // process instruction file
427                    /*System.out.println("processing instruction file...");
428                    insInFile.seek(0);
429                    insOutFile.setLength(0);
430                    int index = 0,start =0;
431                    String num,origId,offset,header,threadId;
432    
433                    do {
434                            line = insInFile.readLine();
435                    } while (line.indexOf('+')==-1);
436    
437                    while (line != null) {
438    
439                            header = "";
440                            index = line.lastIndexOf(':');
441                            if (index != -1) {
442                                    header = line.substring(0,index+1);
443                                    line = line.substring(index+1);
444                            }
445    
446                            index = line.indexOf(' ');
447                            num = line.substring(0,index);
448    
449                            start = index+1;
450                            index = line.indexOf(' ',start);
451                            origId = line.substring(start,index);
452                            start = index+1;
453                            index = line.indexOf(' ',start);
454                            offset = line.substring(start, index);
455                            start = index +1;
456                            threadId = line.substring(start);
457    
458                            int threadIndex =threadList.indexOf(threadId);
459                            if (threadIndex == -1) continue;
460                            int methodIndex = methodUsed.indexOf(origId);
461                            if ((methodIndex != -1)&&(((String)methodDefined.get(origId)).indexOf("Unknown_method_")==-1)) {
462                                    writeInstruction(header + (Integer.parseInt(num)-firstBytecode) + " " + methodIndex + " " + offset + " " + threadIndex);
463                            } else {
464                                    //writeInstruction(header+(Integer.parseInt(num)-firstBytecode) + " " + 0 + " " + offset + " " + threadIndex);
465                            }
466                            line = insInFile.readLine();
467                    }*/
468                    System.out.println("done!");
469            }
470    
471            private void writeInstruction(String string) throws IOException {
472                    insOutFile.writeBytes(string + "\n");
473            }
474    
475            private void write(String string) throws IOException {
476                    dataOutFile.writeBytes(string + "\n");
477            }
478    
479            private String restoreMethod(String method) {
480                    String returnVal = method.substring(0, method.indexOf('(') + 1);
481                    String str = method.substring(method.indexOf('(') + 1,method.indexOf(')'));
482                    int arrayNum = 0;
483                    while (str.length() > 0) {
484                            String type;
485                            while (str.charAt(0) == '[') {
486                                    arrayNum++;
487                                    str = str.substring(1);
488                            }
489                            if (str.charAt(0) == 'L') {
490                                    type = str.substring(1, str.indexOf(';'));
491                                    str = str.substring(str.indexOf(';') + 1);
492                            } else {
493                                    type = str.substring(0, 1);
494                                    str = str.substring(1);
495                            }
496                            returnVal = returnVal + restoreType(type);
497                            for (int i = 0; i < arrayNum; i++) {
498                                    returnVal = returnVal + "[]";
499                            }
500                            arrayNum = 0;
501                            returnVal = returnVal + ",";
502                    }
503                    if (returnVal.charAt(returnVal.length() - 1) == ',') {
504                            returnVal = returnVal.substring(0, returnVal.length() - 1);
505                    }
506                    returnVal = returnVal + ")";
507                    returnVal = returnVal.replace('<', '[');
508                    returnVal = returnVal.replace('>', ']');
509                    return returnVal;
510            }
511    
512            private String restoreType(String type) {
513                    if (type.equals("Z")) {
514                            return "boolean";
515                    }
516                    if (type.equals("B")) {
517                            return "byte";
518                    }
519                    if (type.equals("C")) {
520                            return "char";
521                    }
522                    if (type.equals("S")) {
523                            return "short";
524                    }
525                    if (type.equals("I")) {
526                            return "int";
527                    }
528                    if (type.equals("J")) {
529                            return "long";
530                    }
531                    if (type.equals("F")) {
532                            return "float";
533                    }
534                    if (type.equals("D")) {
535                            return "double";
536                    }
537                    return type.replace('/', '.');
538            }
539    
540            public static void main(String[] args) {
541                    //DemoData data = new DemoData(args[0], args[1], args[2], args[3]);
542                    DemoData data = new DemoData(args[0], args[1], "","");
543                    data.process();
544            }
545    }