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); // } // } }
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); } }