private void addArrayMatchEdges(LocalPointerKey pk) {
   Collection<MemoryAccess> arrayWrites = fam.getArrayWrites(null);
   for (MemoryAccess a : arrayWrites) {
     addSubgraphForNode(a.getNode());
   }
   for (MemoryAccess a : arrayWrites) {
     IR ir = a.getNode().getIR();
     SSAArrayStoreInstruction s =
         (SSAArrayStoreInstruction) ir.getInstructions()[a.getInstructionIndex()];
     PointerKey r = heapModel.getPointerKeyForLocal(a.getNode(), s.getValue());
     assert containsNode(r);
     assert containsNode(pk);
     addMatchEdge(pk, r);
   }
 }
 /*
  * (non-Javadoc)
  *
  * @see com.ibm.domo.ssa.SSAInstruction.Visitor#visitArrayStore(com.ibm.domo.ssa.SSAArrayStoreInstruction)
  */
 @Override
 public void visitArrayStore(SSAArrayStoreInstruction instruction) {
   // Assertions.UNREACHABLE();
   // skip arrays of primitive type
   if (instruction.typeIsPrimitive()) {
     return;
   }
   // make node for used value
   PointerKey value = heapModel.getPointerKeyForLocal(node, instruction.getValue());
   addNode(value);
   //
   // // (requires the creation of assign constraints as
   // // the set points-to(a[]) grows.)
   // PointerKey arrayRef = getPointerKeyForLocal(node,
   // instruction.getArrayRef());
   // // if (!supportFullPointerFlowGraph &&
   // // contentsAreInvariant(instruction.getArrayRef())) {
   // if (contentsAreInvariant(symbolTable, du, instruction.getArrayRef())) {
   // system.recordImplicitPointsToSet(arrayRef);
   // InstanceKey[] ik = getInvariantContents(symbolTable, du, node,
   // instruction.getArrayRef(),
   // SSAPropagationCallGraphBuilder.this);
   //
   // for (int i = 0; i < ik.length; i++) {
   // system.findOrCreateIndexForInstanceKey(ik[i]);
   // PointerKey p = getPointerKeyForArrayContents(ik[i]);
   // IClass contents = ((ArrayClass)
   // ik[i].getConcreteType()).getElementClass();
   // if (p == null) {
   // getWarnings().add(ResolutionFailure.create(node,
   // ik[i].getConcreteType()));
   // } else {
   // if (DEBUG_TRACK_INSTANCE) {
   // if (system.findOrCreateIndexForInstanceKey(ik[i]) ==
   // DEBUG_INSTANCE_KEY) {
   // Assertions.UNREACHABLE();
   // }
   // }
   // if (contentsAreInvariant(symbolTable, du, instruction.getValue())) {
   // system.recordImplicitPointsToSet(value);
   // InstanceKey[] vk = getInvariantContents(symbolTable, du, node,
   // instruction.getValue(),
   // SSAPropagationCallGraphBuilder.this);
   // for (int j = 0; j < vk.length; j++) {
   // system.findOrCreateIndexForInstanceKey(vk[j]);
   // if (vk[j].getConcreteType() != null) {
   // if (contents.isInterface()) {
   // if (getClassHierarchy().implementsInterface(vk[j].getConcreteType(),
   // contents.getReference())) {
   // system.newConstraint(p, vk[j]);
   // }
   // } else {
   // if (getClassHierarchy().isSubclassOf(vk[j].getConcreteType(),
   // contents)) {
   // system.newConstraint(p, vk[j]);
   // }
   // }
   // }
   // }
   // } else {
   // if (isRootType(contents)) {
   // system.newConstraint(p, assignOperator, value);
   // } else {
   // system.newConstraint(p, filterOperator, value);
   // }
   // }
   // }
   // }
   // } else {
   // if (contentsAreInvariant(symbolTable, du, instruction.getValue())) {
   // system.recordImplicitPointsToSet(value);
   // InstanceKey[] ik = getInvariantContents(symbolTable, du, node,
   // instruction.getValue(),
   // SSAPropagationCallGraphBuilder.this);
   // for (int i = 0; i < ik.length; i++) {
   // system.findOrCreateIndexForInstanceKey(ik[i]);
   // if (Assertions.verifyAssertions) {
   // Assertions._assert(!system.isUnified(arrayRef));
   // }
   // system.newSideEffect(new InstanceArrayStoreOperator(ik[i]), arrayRef);
   // }
   // } else {
   // system.newSideEffect(new
   // ArrayStoreOperator(system.findOrCreatePointsToSet(value)), arrayRef);
   // }
   // }
 }
Ejemplo n.º 3
0
  private void run(IProgressMonitor progress) throws CancelException {
    final Map<PDGNode, PDGNode[]> entry2out = new HashMap<PDGNode, PDGNode[]>();

    // add out nodes for each non-primitive parameter
    for (final PDG pdg : sdg.getAllPDGs()) {
      // primitive types nodes are null
      final PDGNode[] formOuts = new PDGNode[pdg.params.length];

      for (int i = 0; i < pdg.params.length; i++) {
        final PDGNode formIn = pdg.params[i];
        final TypeReference type = pdg.getParamType(i);

        if (createOutputParamFor(type)) {
          final PDGNode formOut =
              pdg.addOutputFieldChildTo(
                  pdg.entry,
                  formIn.getLabel(),
                  formIn.getBytecodeName(),
                  formIn.getBytecodeIndex(),
                  formIn.getTypeRef());
          formOuts[i] = formOut;
        }
      }

      entry2out.put(pdg.entry, formOuts);

      for (final PDGNode call : pdg.getCalls()) {
        final PDGNode[] actIns = pdg.getParamIn(call);
        final PDGNode[] actOuts = new PDGNode[actIns.length];

        for (int i = 0; i < actIns.length; i++) {
          final PDGNode actIn = actIns[i];
          final TypeReference type = pdg.getParamType(call, i);

          if (createOutputParamFor(type)) {
            final PDGNode actOut =
                pdg.addOutputFieldChildTo(
                    call,
                    actIn.getLabel(),
                    actIn.getBytecodeName(),
                    actIn.getBytecodeIndex(),
                    actIn.getTypeRef());
            actOuts[i] = actOut;
          }
        }

        entry2out.put(call, actOuts);
      }
    }

    // connect form-outs of called procedures with act-outs
    for (final PDG pdg : sdg.getAllPDGs()) {
      for (final PDGNode call : pdg.getCalls()) {
        final PDGNode[] actOuts = entry2out.get(call);
        assert actOuts != null;

        for (final PDGEdge out : pdg.outgoingEdgesOf(call)) {
          if (out.kind == PDGEdge.Kind.CALL_STATIC || out.kind == PDGEdge.Kind.CALL_VIRTUAL) {
            final PDGNode calleeEntry = out.to;
            final PDGNode[] formOuts = entry2out.get(calleeEntry);
            final PDG callee = sdg.getPDGforId(calleeEntry.getPdgId());
            assert formOuts != null;
            assert actOuts.length == formOuts.length;

            for (int i = 0; i < actOuts.length; i++) {
              final PDGNode actOut = actOuts[i];
              if (actOut != null) {
                // primitive type (and immutable type) params have no act out
                callee.addVertex(actOut);
                final PDGNode formOut = formOuts[i];

                if (formOut != null) {
                  callee.addEdge(formOut, actOut, PDGEdge.Kind.PARAMETER_OUT);
                }
              }
            }
          }
        }
      }
    }

    // collect reachable points-to elements for reachable fields for each parameter
    for (final PDG pdg : sdg.getAllPDGs()) {
      final Map<PDGNode, OrdinalSet<InstanceKey>> node2ptsMod =
          new HashMap<PDGNode, OrdinalSet<InstanceKey>>();
      final Map<PDGNode, OrdinalSet<InstanceKey>> node2ptsRef =
          new HashMap<PDGNode, OrdinalSet<InstanceKey>>();

      final IR ir = pdg.cgNode.getIR();

      if (ir == null) {
        continue;
      }

      for (int i = 0; i < pdg.params.length; i++) {
        if (!pdg.getParamType(i).isPrimitiveType()) {
          final PDGNode formIn = pdg.params[i];
          final int ssaVar = ir.getParameter(i);

          if (ssaVar >= 0) {
            final OrdinalSet<InstanceKey> ptsSet = findReachableInstances(pdg.cgNode, ssaVar);
            node2ptsMod.put(formIn, ptsSet);
          }
        }
      }

      final PDGNode[] formOuts = entry2out.get(pdg.entry);
      for (int i = 0; i < formOuts.length; i++) {
        final PDGNode formOut = formOuts[i];

        if (formOut != null) {
          final PDGNode formIn = pdg.params[i];
          final OrdinalSet<InstanceKey> ptsSet = node2ptsMod.get(formIn);
          node2ptsRef.put(formOut, ptsSet);
        }
      }

      final TypeReference retType = pdg.getMethod().getReturnType();
      if (retType != TypeReference.Void && !retType.isPrimitiveType()) {
        for (final PDGNode retNode : pdg.getReturns()) {
          final SSAReturnInstruction ret = (SSAReturnInstruction) pdg.getInstruction(retNode);
          final int ssaVar = ret.getResult();
          final OrdinalSet<InstanceKey> ptsSet = findReachableInstances(pdg.cgNode, ssaVar);

          node2ptsRef.put(retNode, ptsSet);
        }
      }

      for (final PDGNode call : pdg.getCalls()) {
        final PDGNode[] actIns = pdg.getParamIn(call);

        final SSAAbstractInvokeInstruction invk =
            (SSAAbstractInvokeInstruction) pdg.getInstruction(call);

        for (int i = 0; i < actIns.length; i++) {

          if (!pdg.getParamType(call, i).isPrimitiveType()) {
            final PDGNode actIn = actIns[i];
            final int ssaVar = invk.getUse(i);

            if (ssaVar >= 0) {
              final OrdinalSet<InstanceKey> ptsSet = findReachableInstances(pdg.cgNode, ssaVar);
              node2ptsRef.put(actIn, ptsSet);
            }
          }
        }

        final PDGNode actOuts[] = entry2out.get(call);
        for (int i = 0; i < actIns.length; i++) {
          final PDGNode actOut = actOuts[i];

          if (actOut != null) {
            final PDGNode actIn = actIns[i];
            final OrdinalSet<InstanceKey> ptsSet = node2ptsRef.get(actIn);
            node2ptsMod.put(actOut, ptsSet);
          }
        }

        final TypeReference callRetType = invk.getDeclaredTarget().getReturnType();
        if (callRetType != TypeReference.Void && !callRetType.isPrimitiveType()) {
          final int ssaVar = invk.getReturnValue(0);
          final OrdinalSet<InstanceKey> ptsSet = findReachableInstances(pdg.cgNode, ssaVar);
          final PDGNode retNode = pdg.getReturnOut(call);
          node2ptsMod.put(retNode, ptsSet);
        }
      }

      // create mod/ref sets for get & set instructions
      for (final PDGField read : pdg.getFieldReads()) {
        if (!read.field.isStatic()) {
          if (read.field.isArray()) {
            final SSAArrayLoadInstruction ali =
                (SSAArrayLoadInstruction) pdg.getInstruction(read.node);
            final int ssaVarBase = ali.getArrayRef();

            if (ssaVarBase >= 0) {
              final OrdinalSet<InstanceKey> ptsSet = pointsToArrayField(pdg.cgNode, ssaVarBase);
              node2ptsRef.put(read.accfield, ptsSet);
            }
          } else {
            final SSAGetInstruction get = (SSAGetInstruction) pdg.getInstruction(read.node);
            final int ssaVarBase = get.getRef();

            if (ssaVarBase >= 0) {
              final IField field = sdg.getClassHierarchy().resolveField(get.getDeclaredField());
              final OrdinalSet<InstanceKey> ptsSet =
                  pointsToObjectField(pdg.cgNode, ssaVarBase, field);
              node2ptsRef.put(read.accfield, ptsSet);
            }
          }

          //					final SSAInstruction get = pdg.getInstruction(read.node);
          //					final int ssaVar = get.getDef();
          //					if (ssaVar >= 0) {
          //						final OrdinalSet<InstanceKey> ptsSet = findReachableInstances(pdg.cgNode, ssaVar);
          //						node2ptsRef.put(read.accfield, ptsSet);
          //					}
        }
      }

      for (final PDGField write : pdg.getFieldWrites()) {
        if (!write.field.isStatic()) {
          if (write.field.isArray()) {
            final SSAArrayStoreInstruction asi =
                (SSAArrayStoreInstruction) pdg.getInstruction(write.node);
            final int ssaVarBase = asi.getArrayRef();

            if (ssaVarBase >= 0) {
              final OrdinalSet<InstanceKey> ptsSet = pointsToArrayField(pdg.cgNode, ssaVarBase);
              node2ptsMod.put(write.accfield, ptsSet);
            }
          } else {
            final SSAPutInstruction put = (SSAPutInstruction) pdg.getInstruction(write.node);
            final int ssaVarBase = put.getRef();

            if (ssaVarBase >= 0) {
              final IField field = sdg.getClassHierarchy().resolveField(put.getDeclaredField());
              final OrdinalSet<InstanceKey> ptsSet =
                  pointsToObjectField(pdg.cgNode, ssaVarBase, field);
              node2ptsMod.put(write.accfield, ptsSet);
            }
          }
        }
      }

      // add data flow for each pdg
      FlatHeapParamsDataFlow.compute(
          pdg,
          node2ptsMod,
          node2ptsRef,
          (sdg.cfg.accessPath ? PDGEdge.Kind.DATA_ALIAS : PDGEdge.Kind.DATA_HEAP),
          progress);
    }
  }