Exemple #1
0
  public static TypeReference getCapsuleMockupClassReference(TypeReference capsuleInterface) {
    ClassLoaderReference loader = capsuleInterface.getClassLoader();

    TypeName interfaceName = capsuleInterface.getName();
    String pkg = interfaceName.getPackage().toString();
    String name = interfaceName.getClassName().toString() + CAPSULE_MOCKUP_SUFFIX;

    return TypeReference.findOrCreateClass(loader, pkg, name);
  }
  private static List<Pair<CGNode, SSACheckCastInstruction>> findFailingCasts(
      CallGraph cg, DemandRefinementPointsTo dmp) {
    final IClassHierarchy cha = dmp.getClassHierarchy();
    List<Pair<CGNode, SSACheckCastInstruction>> failing =
        new ArrayList<Pair<CGNode, SSACheckCastInstruction>>();

    int numSafe = 0, numMightFail = 0;
    outer:
    for (Iterator<? extends CGNode> nodeIter = cg.iterator(); nodeIter.hasNext(); ) {
      CGNode node = nodeIter.next();
      TypeReference declaringClass = node.getMethod().getReference().getDeclaringClass();
      // skip library classes
      if (declaringClass.getClassLoader().equals(ClassLoaderReference.Primordial)) {
        continue;
      }
      IR ir = node.getIR();
      if (ir == null) continue;
      SSAInstruction[] instrs = ir.getInstructions();
      for (int i = 0; i < instrs.length; i++) {
        if (numSafe + numMightFail > MAX_CASTS) break outer;
        SSAInstruction instruction = instrs[i];
        if (instruction instanceof SSACheckCastInstruction) {
          SSACheckCastInstruction castInstr = (SSACheckCastInstruction) instruction;
          final TypeReference[] declaredResultTypes = castInstr.getDeclaredResultTypes();

          boolean primOnly = true;
          for (TypeReference t : declaredResultTypes) {
            if (!t.isPrimitiveType()) {
              primOnly = false;
            }
          }
          if (primOnly) {
            continue;
          }

          System.err.println("CHECKING " + castInstr + " in " + node.getMethod());
          PointerKey castedPk = heapModel.getPointerKeyForLocal(node, castInstr.getUse(0));
          Predicate<InstanceKey> castPred =
              new Predicate<InstanceKey>() {

                @Override
                public boolean test(InstanceKey ik) {
                  TypeReference ikTypeRef = ik.getConcreteType().getReference();
                  for (TypeReference t : declaredResultTypes) {
                    if (cha.isAssignableFrom(cha.lookupClass(t), cha.lookupClass(ikTypeRef))) {
                      return true;
                    }
                  }
                  return false;
                }
              };
          long startTime = System.currentTimeMillis();
          Pair<PointsToResult, Collection<InstanceKey>> queryResult =
              dmp.getPointsTo(castedPk, castPred);
          long runningTime = System.currentTimeMillis() - startTime;
          System.err.println("running time: " + runningTime + "ms");
          final FieldRefinePolicy fieldRefinePolicy =
              dmp.getRefinementPolicy().getFieldRefinePolicy();
          switch (queryResult.fst) {
            case SUCCESS:
              System.err.println("SAFE: " + castInstr + " in " + node.getMethod());
              if (fieldRefinePolicy instanceof ManualFieldPolicy) {
                ManualFieldPolicy hackedFieldPolicy = (ManualFieldPolicy) fieldRefinePolicy;
                System.err.println(hackedFieldPolicy.getHistory());
              }
              System.err.println("TRAVERSED " + dmp.getNumNodesTraversed() + " nodes");
              numSafe++;
              break;
            case NOMOREREFINE:
              if (queryResult.snd != null) {
                System.err.println(
                    "MIGHT FAIL: no more refinement possible for "
                        + castInstr
                        + " in "
                        + node.getMethod());
              } else {
                System.err.println(
                    "MIGHT FAIL: exceeded budget for " + castInstr + " in " + node.getMethod());
              }
              failing.add(Pair.make(node, castInstr));
              numMightFail++;
              break;
            case BUDGETEXCEEDED:
              System.err.println(
                  "MIGHT FAIL: exceeded budget for " + castInstr + " in " + node.getMethod());
              failing.add(Pair.make(node, castInstr));
              numMightFail++;
              break;
            default:
              Assertions.UNREACHABLE();
          }
        }
      }
      // break outer;
    }
    System.err.println("TOTAL SAFE: " + numSafe);
    System.err.println("TOTAL MIGHT FAIL: " + numMightFail);
    return failing;
  }