void setExecuted(ThreadInfo ti, Instruction insn) {
      int idx = ti.getId();

      if (covered == null) {
        covered = new BitSet[idx + 1];
      } else if (idx >= covered.length) {
        BitSet[] a = new BitSet[idx + 1];
        System.arraycopy(covered, 0, a, 0, covered.length);
        covered = a;
      }

      if (covered[idx] == null) {
        covered[idx] = new BitSet(mi.getInstructions().length);
      }

      int off = insn.getInstructionIndex();
      covered[idx].set(off);

      if (showBranchCoverage && (insn instanceof IfInstruction)) {
        if (branchTrue == null) {
          branchTrue = new BitSet(mi.getInstructions().length);
          branchFalse = new BitSet(branchTrue.size());
        }
        if (!((IfInstruction) insn).getConditionValue()) {
          branchTrue.set(off);
        } else {
          branchFalse.set(off);
        }
      }
    }
    void printBodyCoverage(MethodCoverage mc) {
      MethodInfo mi = mc.getMethodInfo();
      Instruction[] code = mi.getInstructions();
      BitSet cov = mc.getExecutedInsn();
      int i, start = -1;

      BitSet handlers = mc.getHandlers();

      if (excludeHandlers) {
        cov.andNot(handlers);
      }

      for (i = 0; i < code.length; i++) {
        if (!cov.get(i)) { // not covered
          if (start == -1) {
            start = i;
          }
        } else { // covered
          if (start != -1) {
            printSourceRange(code, handlers, start, i - 1, "");
            start = -1;
          }
        }
      }
      if (start != -1) {
        printSourceRange(code, handlers, start, i - 1, "");
      }

      // now print the missing branches
      BitSet branches = mc.getBranches();
      lastStart = -1; // reset in case condition and branch are in same line
      for (i = 0; i < code.length; i++) {
        if (branches.get(i)) {
          String prefix = "";
          BitSet bTrue = mc.branchTrue;
          BitSet bFalse = mc.branchFalse;
          if (bTrue != null) { // means we have condition bit sets
            boolean cTrue = bTrue.get(i);
            boolean cFalse = bFalse.get(i);
            if (cTrue) {
              prefix = cFalse ? "" : "F "; // covered or false missing
            } else {
              prefix = cFalse ? "T " : "N "; // true or both missing
            }
          } else {
            prefix = "N "; // not covered at all
          }

          if (prefix != null) {
            printSourceRange(code, handlers, i, i, prefix);
          }
        }
      }
    }
    public void setConstErrorMessage() {
      MethodInfo mi = insn.getMethodInfo();
      StringBuilder sb = new StringBuilder("@Const method violation: ");
      sb.append(mi.getFullName());
      sb.append("\n\tfield:    ");
      sb.append(((FieldInfo) use).getFullName());
      sb.append("\n\tmethod:   ");
      sb.append(insn.getSourceLocation());

      msg = sb.toString();
    }
    BitSet getBasicBlocks() {
      if (basicBlocks == null) {
        Instruction[] code = mi.getInstructions();
        BitSet bb = new BitSet(code.length);

        bb.set(0); // first insn is always a bb start

        // first, look at the insn type
        for (int i = 0; i < code.length; i++) {
          Instruction insn = code[i];
          if (insn instanceof IfInstruction) {
            IfInstruction ifInsn = (IfInstruction) insn;

            Instruction tgt = ifInsn.getTarget();
            bb.set(tgt.getInstructionIndex());

            tgt = ifInsn.getNext();
            bb.set(tgt.getInstructionIndex());
          } else if (insn instanceof GOTO) {
            Instruction tgt = ((GOTO) insn).getTarget();
            bb.set(tgt.getInstructionIndex());
          } else if (insn instanceof InvokeInstruction) {
            // hmm, this might be a bit too conservative, but who says we
            // don't jump out of a caller into a handler, or even that we
            // ever return from the call?
            Instruction tgt = insn.getNext();
            bb.set(tgt.getInstructionIndex());
          }
        }

        // and now look at the handlers (every first insn is a bb start)
        ExceptionHandler[] handlers = mi.getExceptions();
        if (handlers != null) {
          for (int i = 0; i < handlers.length; i++) {
            Instruction tgt = mi.getInstructionAt(handlers[i].getHandler());
            bb.set(tgt.getInstructionIndex());
          }
        }

        basicBlocks = bb;

        /** dump
         * System.out.println();
         * System.out.println(mi.getFullName());
         * for (int i=0; i<code.length; i++) {
         * System.out.print(String.format("%1$2d %2$c ",i, bb.get(i) ? '>' : ' '));
         * System.out.println(code[i]);
         * }
         **/
      }

      return basicBlocks;
    }
    BitSet getHandlerStarts() {
      BitSet b = new BitSet(mi.getInstructions().length);
      ExceptionHandler[] handler = mi.getExceptions();

      if (handler != null) {
        for (int i = 0; i < handler.length; i++) {
          Instruction hs = mi.getInstructionAt(handler[i].getHandler());
          b.set(hs.getInstructionIndex());
        }
      }

      return b;
    }
    BitSet getHandlers() {
      // this algorithm is a bit subtle - we walk through the code until
      // we hit a forward GOTO (or RETURN). If the insn following the goto is the
      // beginning of a handler, we mark everything up to the jump address
      // as a handler block

      if (handlers == null) {
        BitSet hs = getHandlerStarts();
        Instruction[] code = mi.getInstructions();
        BitSet b = new BitSet(code.length);

        if (!hs.isEmpty()) {
          for (int i = 0; i < code.length; i++) {
            Instruction insn = code[i];
            if (insn instanceof GOTO) {
              GOTO gotoInsn = (GOTO) insn;
              if (!gotoInsn.isBackJump() && hs.get(i + 1)) { // jump around handler
                int handlerEnd = gotoInsn.getTarget().getInstructionIndex();
                for (i++; i < handlerEnd; i++) {
                  b.set(i);
                }
              }
            } else if (insn instanceof ReturnInstruction) { // everything else is handler
              for (i++; i < code.length; i++) {
                b.set(i);
              }
            }
          }
        }

        handlers = b;
      }

      return handlers;
    }
    void setLoaded(ClassInfo ci) {
      if (methods == null) {
        this.ci = ci;
        covered = true;
        log.info("used class: " + className);

        methods = new HashMap<MethodInfo, MethodCoverage>();
        for (MethodInfo mi : ci.getDeclaredMethodInfos()) {
          // <2do> what about MJI methods? we should report why we don't cover them
          if (!mi.isNative() && !mi.isAbstract()) {
            MethodCoverage mc = new MethodCoverage(mi);
            methods.put(mi, mc);
          }
        }
      }
    }
  public void instructionExecuted(JVM vm) {
    ThreadInfo ti = vm.getLastThreadInfo();
    Instruction insn = vm.getLastInstruction();

    if (insn instanceof VirtualInvocation) {

      if (vm.getNextInstruction() != insn) { // otherwise we didn't execute
        VirtualInvocation call = (VirtualInvocation) insn;
        int ref = call.getCalleeThis(ti);
        Record rec = getRecord(ref);

        if (rec != null) {
          MethodInfo mi = call.getInvokedMethod(ti, ref);

          if (logCall) {
            log(ti, "invoke %1$s.%2$s", rec.ei, mi.getUniqueName());
          }

          if (!checkShared(rec, ti, mi, insn)) {
            return;
          }
        }
      }

    } else if (insn instanceof PUTFIELD) {
      PUTFIELD storeInsn = (PUTFIELD) insn;
      int ref = storeInsn.getLastThis();
      Record rec = getRecord(ref);

      if (rec != null) {
        FieldInfo fi = storeInsn.getFieldInfo();

        if (logPut) {
          log(ti, "put %1$s.%2$s = <%3$d>", rec.ei, fi.getName(), storeInsn.getLastValue());
        }

        if (!checkShared(rec, ti, fi, insn)) {
          return;
        }

        if (!checkConst(rec, ti, fi, insn)) {
          return;
        }
      }
    }
  }
Beispiel #9
0
  public Instruction execute(SystemState ss, KernelState ks, ThreadInfo ti) {

    if (!ti.isFirstStepInsn()) {
      InvocationCG cg = new InvocationCG("INVOKECG", invokes);
      ss.setNextChoiceGenerator(cg);
      return this;

    } else {
      InvocationCG cg = ss.getCurrentChoiceGenerator("INVOKECG", InvocationCG.class);
      assert (cg != null) : "no current InvocationCG";

      Invocation call = cg.getNextChoice();
      MethodInfo callee = call.getMethodInfo();
      InstructionFactory insnFactory = MethodInfo.getInstructionFactory();

      if (callee.isStatic()) {
        realInvoke = (InvokeInstruction) insnFactory.create(null, Constants.INVOKESTATIC);
      } else {
        realInvoke = (InvokeInstruction) insnFactory.create(null, Constants.INVOKENONVIRTUAL);
      }
      realInvoke.init(mi, offset, position);
      realInvoke.setInvokedMethod(
          callee.getClassInfo().getName(), callee.getName(), callee.getSignature());

      pushArguments(ti, call.getArguments(), call.getAttrs());

      return realInvoke;
    }
  }
  public void executeInstruction(JVM vm) {
    Instruction insn = vm.getLastInstruction();
    MethodInfo mi = insn.getMethodInfo();
    ThreadInfo ti = vm.getLastThreadInfo();

    if (mi != lastMi) {
      logStack(ti);
      lastMi = mi;

    } else if (insn instanceof InvokeInstruction) {
      MethodInfo callee;

      // that's the only little gist of it - if this is a VirtualInvocation,
      // we have to dig the callee out by ourselves (it's not known
      // before execution)

      if (insn instanceof VirtualInvocation) {
        VirtualInvocation callInsn = (VirtualInvocation) insn;
        int objref = callInsn.getCalleeThis(ti);
        callee = callInsn.getInvokedMethod(ti, objref);

      } else if (insn instanceof INVOKESPECIAL) {
        INVOKESPECIAL callInsn = (INVOKESPECIAL) insn;
        callee = callInsn.getInvokedMethod(ti);

      } else {
        InvokeInstruction callInsn = (InvokeInstruction) insn;
        callee = callInsn.getInvokedMethod(ti);
      }

      if (callee != null) {
        if (callee.isMJI()) {
          logStack(ti);
        }
      } else {
        out.println("ERROR: unknown callee of: " + insn);
      }
    }
  }
  MethodCoverage getMethodCoverage(JVM vm) {
    Instruction insn = vm.getLastInstruction();

    if (!insn.isExtendedInstruction()) {
      MethodInfo mi = insn.getMethodInfo();
      if (mi != lastMi) {
        lastMc = null;
        lastMi = mi;
        ClassInfo ci = mi.getClassInfo();
        if (ci != null) {
          ClassCoverage cc = classes.get(ci.getName());
          if (cc != null) {
            lastMc = cc.getMethodCoverage(mi);
          }
        }
      }

      return lastMc;
    }

    return null;
  }
    BitSet getExecutedInsn() {
      int nTotal = mi.getInstructions().length;
      BitSet bUnion = new BitSet(nTotal);

      if (covered != null) {
        for (BitSet b : covered) {
          if (b != null) {
            bUnion.or(b);
          }
        }
      }

      return bUnion;
    }
    Coverage getCoveredInsn() {
      int nTotal = mi.getInstructions().length;

      if (excludeHandlers) {
        nTotal -= getHandlers().cardinality();
      }

      if (covered != null) {
        BitSet bExec = getExecutedInsn();
        if (excludeHandlers) {
          bExec.andNot(getHandlers());
        }
        return new Coverage(nTotal, bExec.cardinality());
      } else {
        return new Coverage(nTotal, 0);
      }
    }
    // that's kind of redundant with basic blocks, but not really - here
    // we are interested in the logic behind branches, i.e. we want to know
    // what the condition values were. We are not interested in GOTOs and exceptions
    BitSet getBranches() {
      if (branches == null) {
        Instruction[] code = mi.getInstructions();
        BitSet br = new BitSet(code.length);

        for (int i = 0; i < code.length; i++) {
          Instruction insn = code[i];
          if (insn instanceof IfInstruction) {
            br.set(i);
          }
        }

        branches = br;
      }

      return branches;
    }
    boolean getCoveredLines(BitSet executable, BitSet covered) {
      Instruction inst[] = mi.getInstructions();
      BitSet insn;
      int i, line;

      if (covered == null) {
        return false;
      }

      insn = getExecutedInsn();
      if (excludeHandlers) {
        insn.andNot(getHandlers());
      }

      if (branchTrue != null) {
        for (i = branchTrue.length() - 1; i >= 0; i--) {
          boolean cTrue = branchTrue.get(i);
          boolean cFalse = branchFalse.get(i);

          if ((!cTrue || !cFalse) && (inst[i] instanceof IfInstruction)) {
            insn.clear(i);
          }
        }
      }

      for (i = inst.length - 1; i >= 0; i--) {
        line = inst[i].getLineNumber();

        if (line > 0) {
          executable.set(line);
          covered.set(line);
        }
      }

      for (i = inst.length - 1; i >= 0; i--) {
        line = inst[i].getLineNumber();
        if ((!insn.get(i))
            && (line
                > 0)) { // TODO What do we do with instructions that don't have a line number.  Is
          // this even possible?
          covered.clear(line);
        }
      }

      return true;
    }
Beispiel #16
0
  protected MethodInfo createCallStub(String originator, int id) {
    MethodInfo mi = new MethodInfo(id);
    String cname = ci.getName();
    Instruction insn;

    mi.name =
        originator
            + name; // + cname; // could maybe also include the called method, but keep it fast
    mi.signature = "()V";
    mi.maxLocals = isStatic() ? 0 : 1;
    mi.maxStack = getNumberOfCallerStackSlots(); // <2do> cache for optimization
    mi.localVariableNames = EMPTY;
    mi.localVariableTypes = EMPTY;
    mi.lineNumbers = null;
    mi.exceptions = null;
    mi.thrownExceptionClassNames = null;
    mi.uniqueName = mi.name;

    // createAndInitialize the code
    CodeBuilder cb = mi.getCodeBuilder();

    if (isStatic()) {
      mi.modifiers |= Modifier.STATIC;

      if (isClinit()) {
        insn = insnFactory.create(null, INVOKECLINIT.OPCODE);
      } else {
        insn = insnFactory.create(null, Constants.INVOKESTATIC);
      }
    } else if (name.equals("<init>")) {
      insn = insnFactory.create(null, Constants.INVOKESPECIAL);
    } else {
      insn = insnFactory.create(null, Constants.INVOKEVIRTUAL);
    }
    ((InvokeInstruction) insn).setInvokedMethod(cname, name, signature);
    cb.append(insn);

    insn = insnFactory.create(null, Constants.RETURN);
    cb.append(insn);

    cb.setCode();

    return mi;
  }
 AnnotationInfo getRequirementsAnnotation(MethodInfo mi) {
   // <2do> should probably look for overridden method annotations
   return mi.getAnnotation("gov.nasa.jpf.Requirement");
 }
    void printMethodCoverages(ClassCoverage cc) {
      String classNameTree = "cc-" + cc.className.replace('.', '-') + '-';
      int line, lineNumbers[];
      boolean result = true;

      if (cc.methods == null) {
        return;
      }

      ArrayList<Map.Entry<MethodInfo, MethodCoverage>> mthEntries =
          Misc.createSortedEntryList(
              cc.methods,
              new Comparator<Map.Entry<MethodInfo, MethodCoverage>>() {

                public int compare(
                    Map.Entry<MethodInfo, MethodCoverage> o1,
                    Map.Entry<MethodInfo, MethodCoverage> o2) {
                  int a = o2.getValue().getCoveredInsn().percent();
                  int b = o1.getValue().getCoveredInsn().percent();

                  if (a == b) {
                    return o2.getKey().getUniqueName().compareTo(o1.getKey().getUniqueName());
                  } else {
                    return a - b;
                  }
                }
              });

      for (Map.Entry<MethodInfo, MethodCoverage> e : mthEntries) {
        MethodCoverage mc = e.getValue();
        MethodInfo mi = mc.getMethodInfo();
        Coverage insnCoverage = mc.getCoveredInsn();
        Coverage lineCoverage = mc.getCoveredLines();
        Coverage branchCoverage = mc.getCoveredBranches();

        result = result && insnCoverage.isFullyCovered();

        HTMLPublisher.writeTableTreeNodeBegin(
            pw, classNameTree + HTMLPublisher.escape(mi.getLongName()));
        pw.print("            <td class=\"firstCol\">");

        lineNumbers = mi.getLineNumbers();
        if ((lineNumbers != null) && (lineNumbers.length > 0)) {
          line = lineNumbers[0];
        } else {
          line = 0;
        }

        ((HTMLPublisher) publisher).writeSourceAnchor(pw, mi.getSourceFileName(), line);

        pw.print(HTMLPublisher.escape(mi.getLongName()));
        pw.println("</a></td>");

        pw.print("            ");

        printCoverage(insnCoverage);
        printCoverage(lineCoverage);
        printCoverage(mc.getCoveredBasicBlocks());
        printCoverage(branchCoverage);

        pw.println();
        HTMLPublisher.writeTableTreeNodeEnd(pw);
      }
    }
 MethodCoverage(MethodInfo mi) {
   this.mi = mi;
   log.info("add method: " + mi.getUniqueName());
 }
    void printMethodCoverages(ClassCoverage cc) {
      String space = "  ";
      boolean result = true;

      if (cc.methods == null) {
        return;
      }

      ArrayList<Map.Entry<MethodInfo, MethodCoverage>> mthEntries =
          Misc.createSortedEntryList(
              cc.methods,
              new Comparator<Map.Entry<MethodInfo, MethodCoverage>>() {

                public int compare(
                    Map.Entry<MethodInfo, MethodCoverage> o1,
                    Map.Entry<MethodInfo, MethodCoverage> o2) {
                  int a = o2.getValue().getCoveredInsn().percent();
                  int b = o1.getValue().getCoveredInsn().percent();

                  if (a == b) {
                    return o2.getKey().getUniqueName().compareTo(o1.getKey().getUniqueName());
                  } else {
                    return a - b;
                  }
                }
              });

      Coverage emptyCoverage = new Coverage(0, 0);

      for (Map.Entry<MethodInfo, MethodCoverage> e : mthEntries) {
        MethodCoverage mc = e.getValue();
        MethodInfo mi = mc.getMethodInfo();
        Coverage insnCoverage = mc.getCoveredInsn();
        Coverage lineCoverage = mc.getCoveredLines();
        Coverage branchCoverage = mc.getCoveredBranches();

        result = result && insnCoverage.isFullyCovered();

        pw.print(space);
        printCoverage(insnCoverage);

        pw.print(space);
        printCoverage(lineCoverage);

        pw.print(space);
        printCoverage(mc.getCoveredBasicBlocks());

        pw.print(space);
        printCoverage(branchCoverage);

        pw.print(space);
        printCoverage(emptyCoverage);

        pw.print(space);
        pw.print(mi.getLongName());
        pw.println();

        if (showMethodBodies
            && (!insnCoverage.isFullyCovered() || !branchCoverage.isFullyCovered())) {
          printBodyCoverage(mc);
        }
      }
    }
Beispiel #21
0
  /** @see gov.nasa.jpf.ListenerAdapter#instructionExecuted(gov.nasa.jpf.jvm.JVM) */
  public void instructionExecuted(JVM vm) {
    Instruction instr = vm.getLastInstruction();
    ThreadInfo ti = vm.getLastThreadInfo();

    if (instr instanceof InvokeInstruction) {
      InvokeInstruction invInstr = ((InvokeInstruction) instr);

      String method = invInstr.toString();
      // if(method.contains("Test"))
      // System.out.println(method);

      MethodInfo mi = ((InvokeInstruction) instr).getInvokedMethod();
      if (this.traceDefFilter != null && this.traceDefFilter.accept(mi)) {
        // Callee
        ElementInfo calleeElement = ti.getThisElementInfo();
        MethodInfo calleeMethod = invInstr.getInvokedMethod();
        ClassInfo calleeClass = null;
        int calleeID = -1;
        if (calleeMethod.isStatic()) {
          // static method: method declared in class
          calleeClass = calleeMethod.getClassInfo();
          // static methods do not have a instance
          calleeID = -1;
        } else {
          // non static method: method is maybe overridden. get the current class
          // instead of the class the method is declared in.
          calleeClass = calleeElement.getClassInfo();
          // get the current instance
          calleeID = calleeElement.getThisReference();
        }
        assert (calleeClass != null);

        // Caller
        ElementInfo callerElement = ti.getElementInfo(ti.getCallerStackFrame().getThis());
        if (callerElement != null) {
          MethodInfo callerMethod = invInstr.getMethodInfo();
          ClassInfo callerClass = null;
          int callerID = -1;
          if (callerMethod.isStatic()) {
            // see above
            callerClass = callerMethod.getClassInfo();
            callerID = -1;
          } else {
            // see above
            callerClass = callerElement.getClassInfo();
            callerID = callerElement.getThisReference();
          }

          // Arguments
          Object[] argumentValues = invInstr.getArgumentValues(ti);
          Object[] arguments = new Object[argumentValues.length];
          for (int i = 0; i < arguments.length; i++) {
            if (this.argumentValues) {
              if (argumentValues[i] instanceof ElementInfo)
                arguments[i] = ((ElementInfo) argumentValues[i]).getThisReference();
              else arguments[i] = argumentValues[i];
            } else arguments[i] = null;
          }

          MethodEntry methodEntry =
              new MethodEntry(
                  callerID,
                  callerMethod,
                  callerClass,
                  calleeID,
                  calleeMethod,
                  calleeClass,
                  arguments,
                  ti.getName());

          this.currentStateNode.methods.add(methodEntry);

          if (this.timeStamps) methodEntry.time = new Date().getTime();
        }
      }
    }
  }