001: //
002: // Copyright (C) 2005 United States Government as represented by the
003: // Administrator of the National Aeronautics and Space Administration
004: // (NASA). All Rights Reserved.
005: //
006: // This software is distributed under the NASA Open Source Agreement
007: // (NOSA), version 1.3. The NOSA has been approved by the Open Source
008: // Initiative. See the file NOSA-1.3-JPF at the top of the distribution
009: // directory tree for the complete NOSA document.
010: //
011: // THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY
012: // KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT
013: // LIMITED TO, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL CONFORM TO
014: // SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR
015: // A PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT
016: // THE SUBJECT SOFTWARE WILL BE ERROR FREE, OR ANY WARRANTY THAT
017: // DOCUMENTATION, IF PROVIDED, WILL CONFORM TO THE SUBJECT SOFTWARE.
018: //
019: package gov.nasa.jpf.util;
020:
021: import gov.nasa.jpf.Config;
022: import gov.nasa.jpf.jvm.bytecode.Instruction;
023:
024: import java.util.Enumeration;
025: import java.util.Hashtable;
026:
027: /**
028: * static class to store coverage metrics relatedinformation
029: *
030: * <2do>make it an instance, so that it can be configured. Should be a listener.
031: * this also need to be extensible, since it's currently a great structural
032: * bottleneck
033: */
034: public class CoverageManager {
035: public static int IFcounter = 0;
036:
037: public static int Methodcounter = 0;
038:
039: private static String[] StatementIFMap = new String[1];
040:
041: private static int[][] IndexIFMap = new int[1][1];
042:
043: private static String[] StatementMethodMap = new String[1];
044:
045: private static int[][] IndexMethodMap = new int[1][1];
046:
047: private static int lastInstruction = 0;
048:
049: private static int lastInstructionGlobal = 0;
050:
051: private static Hashtable InstructionMap = new Hashtable();
052:
053: private static Hashtable PathInstructionMap = new Hashtable();
054:
055: private static int lastIncremented = 0;
056:
057: private static int lastIncrementedGlobal = 0;
058:
059: private static int[][] PathIndexIFMap = new int[1][1];
060:
061: private static boolean isBranchHeuristic;
062:
063: private static boolean isPathHeuristic;
064:
065: static boolean pathCoverage = false;
066:
067: static boolean branchCoverage = false;
068:
069: static boolean calcBranchCoverage = false;
070:
071: static boolean insnCoverage = false;
072:
073: public static boolean init(Config config) {
074: String hc = config.getProperty("search.heuristic.class");
075: if (hc != null) {
076: if (hc.indexOf("Branch") != -1)
077: isBranchHeuristic = true;
078: if (hc.indexOf("Path") != -1)
079: isPathHeuristic = true;
080: }
081:
082: branchCoverage = config.getBoolean("search.branch_coverage");
083:
084: return true;
085: }
086:
087: public static void setPathCoverage(boolean b) {
088: pathCoverage = b;
089: }
090:
091: public static void setInstructionCoverage(boolean b) {
092: insnCoverage = b;
093: }
094:
095: public static void setCalcBranchCoverage(boolean b) {
096: calcBranchCoverage = b;
097: }
098:
099: public static int getBranchCount(int th, int index) {
100: return IndexIFMap[th][index];
101: }
102:
103: public static int getGlobalCoverage() {
104: int[] sum = new int[IndexIFMap.length];
105: int total_sum = 0;
106: int length = IndexIFMap[0].length; // all the threads' branches are
107: // equal
108: int[] results = new int[length]; // total branch coverage
109:
110: for (int k = 0; k < length; k++) {
111: results[k] = 0;
112: }
113:
114: for (int j = 0; j < IndexIFMap.length; j++) {
115: sum[j] = 0;
116:
117: for (int i = 1; i < IndexIFMap[j].length; i++) { // first entry is
118: // Dummy
119: results[i] += IndexIFMap[j][i];
120:
121: if (IndexIFMap[j][i] != 0) {
122: sum[j]++;
123: }
124: }
125: }
126:
127: for (int l = 0; l < length; l++) {
128: if (results[l] != 0) {
129: total_sum++;
130: }
131: }
132:
133: if ((length - 1) == 0) {
134: return 0;
135: } else {
136: return (int) ((100 * total_sum) / (length - 1));
137: }
138: }
139:
140: public static void setIndexIFMap(int[][] newIndexMap) {
141: PathIndexIFMap = (int[][]) newIndexMap.clone();
142:
143: int pl1 = PathIndexIFMap.length;
144: int pl2 = PathIndexIFMap[0].length;
145: int l1 = IndexIFMap.length;
146: int l2 = IndexIFMap[0].length;
147:
148: if ((l1 > pl1) || (l2 > pl2)) {
149: int[][] temp1 = new int[l1][l2];
150:
151: for (int i = 0; i < l1; i++) {
152: int[] temp2 = new int[l2];
153:
154: if (i < pl1) {
155: System.arraycopy(PathIndexIFMap[i], 0, temp2, 0,
156: pl2);
157: }
158:
159: temp1[i] = temp2;
160: }
161:
162: PathIndexIFMap = temp1;
163: }
164: }
165:
166: public static int[][] getIndexIFMap() {
167: return (int[][]) PathIndexIFMap.clone();
168: }
169:
170: public static void setInstructionMap(Hashtable iMap) {
171: Hashtable h = new Hashtable();
172:
173: for (Enumeration e = iMap.keys(); e.hasMoreElements();) {
174: Object o = e.nextElement();
175: h.put(o, ((int[]) iMap.get(o)).clone());
176: }
177:
178: PathInstructionMap = h;
179: }
180:
181: public static Hashtable getInstructionMap() {
182: Hashtable h = new Hashtable();
183:
184: for (Enumeration e = PathInstructionMap.keys(); e
185: .hasMoreElements();) {
186: Object o = e.nextElement();
187: h.put(o, ((int[]) PathInstructionMap.get(o)).clone());
188: }
189:
190: return h;
191: }
192:
193: public static int getLastIncremented() {
194: return lastIncremented;
195: }
196:
197: public static int getLastIncrementedGlobal() {
198: return lastIncrementedGlobal;
199: }
200:
201: public static void setLastIncrements(int i) {
202: lastIncremented = i;
203: lastIncrementedGlobal = i;
204: }
205:
206: public static int getLastInstruction() {
207: return lastInstruction;
208: }
209:
210: public static int getLastInstructionGlobal() {
211: return lastInstructionGlobal;
212: }
213:
214: public static int getMethodCount(int th, int index) {
215: return IndexMethodMap[th][index];
216: }
217:
218: public static int getPathBranchCount(int th, int index) {
219: return PathIndexIFMap[th][index];
220: }
221:
222: public static int getPathCoverage() {
223: int[] sum = new int[PathIndexIFMap.length];
224: int total_sum = 0;
225: int length = PathIndexIFMap[0].length; // all the threads' branches are
226: // equal
227: int[] results = new int[length]; // total branch coverage
228:
229: for (int k = 0; k < length; k++) {
230: results[k] = 0;
231: }
232:
233: for (int j = 0; j < PathIndexIFMap.length; j++) {
234: sum[j] = 0;
235:
236: for (int i = 1; i < PathIndexIFMap[j].length; i++) { // first entry
237: // is Dummy
238: results[i] += PathIndexIFMap[j][i];
239:
240: if (PathIndexIFMap[j][i] != 0) {
241: sum[j]++;
242: }
243: }
244: }
245:
246: for (int l = 0; l < length; l++) {
247: if (results[l] != 0) {
248: total_sum++;
249: }
250: }
251:
252: if ((length - 1) == 0) {
253: return 0;
254: } else {
255: return (int) ((100 * total_sum) / (length - 1));
256: }
257: }
258:
259: public static int addIF(String name) {
260: // System.out.println ("addIF: " + name);
261: if (calcBranchCoverage || branchCoverage || isBranchHeuristic) {
262: if (StatementIFMap.length <= IFcounter) {
263: String[] temp = new String[IFcounter + 1];
264: System.arraycopy(StatementIFMap, 0, temp, 0,
265: StatementIFMap.length);
266: StatementIFMap = temp;
267:
268: for (int i = 0; i < IndexIFMap.length; i++) {
269: int[] temp1 = new int[IFcounter + 1];
270: System.arraycopy(IndexIFMap[i], 0, temp1, 0,
271: IndexIFMap[i].length);
272: IndexIFMap[i] = temp1;
273: }
274:
275: for (int i = 0; i < PathIndexIFMap.length; i++) {
276: int[] temp1 = new int[IFcounter + 1];
277: System.arraycopy(PathIndexIFMap[i], 0, temp1, 0,
278: PathIndexIFMap[i].length);
279: PathIndexIFMap[i] = temp1;
280: }
281: }
282:
283: StatementIFMap[IFcounter] = name;
284:
285: for (int i = 0; i < IndexIFMap.length; i++) {
286: IndexIFMap[i][IFcounter] = 0;
287: }
288:
289: for (int i = 0; i < PathIndexIFMap.length; i++) {
290: PathIndexIFMap[i][IFcounter] = 0;
291: }
292:
293: IFcounter++;
294: }
295:
296: // System.out.println ("IFcounter now: " + IFcounter);
297: return IFcounter - 1;
298: }
299:
300: public static int addMethod(String name) {
301: if (StatementMethodMap.length <= Methodcounter) {
302: String[] temp = new String[Methodcounter + 1];
303: System.arraycopy(StatementMethodMap, 0, temp, 0,
304: StatementMethodMap.length);
305: StatementMethodMap = temp;
306:
307: for (int i = 0; i < IndexIFMap.length; i++) {
308: int[] temp1 = new int[Methodcounter + 1];
309: System.arraycopy(IndexMethodMap[i], 0, temp1, 0,
310: IndexMethodMap[i].length);
311: IndexMethodMap[i] = temp1;
312: }
313: }
314:
315: StatementMethodMap[Methodcounter] = name;
316:
317: for (int i = 0; i < IndexIFMap.length; i++) {
318: IndexMethodMap[i][Methodcounter] = 0;
319: }
320:
321: Methodcounter++;
322:
323: return Methodcounter - 1;
324: }
325:
326: public static void addThread(int thread) {
327: if (calcBranchCoverage || branchCoverage || isBranchHeuristic) {
328: if (IndexIFMap.length <= thread) {
329: int[][] temp = new int[thread + 1][];
330: System.arraycopy(IndexIFMap, 0, temp, 0,
331: IndexIFMap.length);
332: IndexIFMap = temp;
333: }
334:
335: if (IndexIFMap[thread] == null) {
336: IndexIFMap[thread] = new int[IFcounter];
337: }
338:
339: if (IndexMethodMap.length <= thread) {
340: int[][] temp = new int[thread + 1][];
341: System.arraycopy(IndexMethodMap, 0, temp, 0,
342: IndexMethodMap.length);
343: IndexMethodMap = temp;
344: }
345:
346: if (IndexMethodMap[thread] == null) {
347: IndexMethodMap[thread] = new int[Methodcounter];
348: }
349:
350: if (pathCoverage || isPathHeuristic) {
351: if (PathIndexIFMap.length <= thread) {
352: int[][] temp = new int[thread + 1][];
353: System.arraycopy(PathIndexIFMap, 0, temp, 0,
354: PathIndexIFMap.length);
355: PathIndexIFMap = temp;
356: }
357:
358: if (PathIndexIFMap[thread] == null) {
359: PathIndexIFMap[thread] = new int[IFcounter];
360: }
361: }
362: }
363: }
364:
365: public static void decIFBranch(int th, int index) {
366: IndexIFMap[th][index]--;
367: }
368:
369: public static void decMethod(int th, int index) {
370: IndexMethodMap[th][index]--;
371: }
372:
373: public static void incIFBranch(int th, int index) {
374: if (calcBranchCoverage || branchCoverage) {
375: if (pathCoverage) {
376: /*
377: * int pathIndexIFMapSize = PathIndexIFMap.length; if
378: * (pathIndexIFMapSize <= th) System.out.println ("Too few thread
379: * slots!\n"); int pathIndexMapSize = PathIndexIFMap[th].length; if
380: * (pathIndexMapSize <= index) { System.out.println ("Needed " + index + "
381: * branch slots but only " + pathIndexMapSize + " are available!");
382: * System.out.println ("IFCounter = " + IFcounter); }
383: */
384: lastIncremented = PathIndexIFMap[th][index];
385: PathIndexIFMap[th][index]++;
386: }
387:
388: lastIncrementedGlobal = IndexIFMap[th][index];
389:
390: IndexIFMap[th][index]++;
391: }
392: }
393:
394: public static void incInstruction(Instruction pc, int index) {
395: if (insnCoverage) {
396:
397: Object old = InstructionMap.get(pc);
398: Object oldPath = PathInstructionMap.get(pc);
399:
400: if (old == null) {
401: lastInstructionGlobal = 0;
402:
403: int[] threadMap = new int[index + 1];
404: threadMap[index] = 1;
405: InstructionMap.put(pc, threadMap);
406: } else {
407: int[] threadMap = (int[]) old;
408:
409: if (threadMap.length <= index) {
410: int[] temp = new int[index + 1];
411: System.arraycopy(threadMap, 0, temp, 0,
412: threadMap.length);
413: threadMap = temp;
414: }
415:
416: lastInstructionGlobal = threadMap[index];
417: threadMap[index]++;
418: InstructionMap.put(pc, threadMap);
419: }
420:
421: if (pathCoverage) {
422: if (oldPath == null) {
423: lastInstruction = 0;
424:
425: int[] threadMap = new int[index + 1];
426: threadMap[index] = 1;
427: PathInstructionMap.put(pc, threadMap);
428: } else {
429: int[] threadMap = (int[]) oldPath;
430:
431: if (threadMap.length <= index) {
432: int[] temp = new int[index + 1];
433: System.arraycopy(threadMap, 0, temp, 0,
434: threadMap.length);
435: threadMap = temp;
436: }
437:
438: lastInstruction = threadMap[index];
439: threadMap[index]++;
440: PathInstructionMap.put(pc, threadMap);
441: }
442: }
443: }
444: }
445:
446: public static void incMethod(int th, int index) {
447: IndexMethodMap[th][index]++;
448: }
449:
450: public static void printResults() {
451: if (branchCoverage) {
452: CoverageManager.printIF();
453: CoverageManager.printCoverageIF();
454: }
455: }
456:
457: public static void printCoverageIF() {
458: int[] sum = new int[IndexIFMap.length];
459: int total_sum = 0;
460: int length = IndexIFMap[0].length; // all the threads' branches are
461: // equal
462: int[] results = new int[length]; // total branch coverage
463:
464: for (int k = 0; k < length; k++) {
465: results[k] = 0;
466: }
467:
468: for (int j = 0; j < IndexIFMap.length; j++) {
469: sum[j] = 0;
470:
471: for (int i = 1; i < IndexIFMap[j].length; i++) { // first entry is
472: // Dummy
473: results[i] += IndexIFMap[j][i];
474:
475: if (IndexIFMap[j][i] != 0) {
476: sum[j]++;
477: }
478: }
479:
480: if ((IndexIFMap[j].length - 1) == 0) {
481: System.out.println("Thread " + j
482: + " Branch Coverage 0%");
483: } else {
484: System.out.println("Thread " + j + " Branch Coverage "
485: + ((100 * sum[j]) / (IndexIFMap[j].length - 1))
486: + "% (" + sum[j] + "/"
487: + (IndexIFMap[j].length - 1) + ")");
488: }
489: }
490:
491: for (int l = 0; l < length; l++) {
492: if (results[l] != 0) {
493: total_sum++;
494: }
495: }
496:
497: if ((length - 1) == 0) {
498: System.out.println("Total Branch Coverage 0%");
499: } else {
500: System.out.println("Total Branch Coverage "
501: + ((100 * total_sum) / (length - 1)) + "% ("
502: + total_sum + "/" + (length - 1) + ")");
503: }
504: }
505:
506: public static void printIF() {
507: for (int j = 0; j < IndexIFMap.length; j++) {
508: for (int i = 1; i < IndexIFMap[j].length; i++) { // first entry
509: // dummy
510: System.out.println("Thread " + j + ":"
511: + StatementIFMap[i] + ": " + IndexIFMap[j][i]);
512: }
513: }
514: }
515:
516: public static void printPathCoverageIF() {
517: int[] sum = new int[PathIndexIFMap.length];
518: int total_sum = 0;
519: int length = PathIndexIFMap[0].length; // all the threads' branches are
520: // equal
521: int[] results = new int[length]; // total branch coverage
522:
523: for (int k = 0; k < length; k++) {
524: results[k] = 0;
525: }
526:
527: for (int j = 0; j < PathIndexIFMap.length; j++) {
528: sum[j] = 0;
529:
530: for (int i = 1; i < PathIndexIFMap[j].length; i++) { // first entry
531: // is Dummy
532: results[i] += PathIndexIFMap[j][i];
533:
534: if (PathIndexIFMap[j][i] != 0) {
535: sum[j]++;
536: }
537: }
538:
539: if ((PathIndexIFMap[j].length - 1) == 0) {
540: System.out.println("Thread " + j
541: + " Branch Coverage 0%");
542: } else {
543: System.out
544: .println("Thread "
545: + j
546: + " Branch Coverage "
547: + ((100 * sum[j]) / (PathIndexIFMap[j].length - 1))
548: + "% (" + sum[j] + "/"
549: + (PathIndexIFMap[j].length - 1) + ")");
550: }
551: }
552:
553: for (int l = 0; l < length; l++) {
554: if (results[l] != 0) {
555: total_sum++;
556: }
557: }
558:
559: if ((length - 1) == 0) {
560: System.out.println("Total Branch Coverage 0%");
561: } else {
562: System.out.println("Total Branch Coverage "
563: + ((100 * total_sum) / (length - 1)) + "% ("
564: + total_sum + "/" + (length - 1) + ")");
565: }
566: }
567: }
|