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