+ private void constructGlobalFlowGraph() {
+
+ System.out.println("");
+ LinkedList<MethodDescriptor> methodDescList =
+ (LinkedList<MethodDescriptor>) toanalyze_methodDescList.clone();
+
+ System.out.println("@@@methodDescList=" + methodDescList);
+ // System.exit(0);
+
+ while (!methodDescList.isEmpty()) {
+ MethodDescriptor md = methodDescList.removeLast();
+ if (state.SSJAVADEBUG) {
+ System.out.println();
+ System.out.println("SSJAVA: Constructing a global flow graph: " + md);
+
+ FlowGraph flowGraph = getFlowGraph(md);
+ FlowGraph subGlobalFlowGraph = flowGraph.clone();
+ mapMethodDescriptorToSubGlobalFlowGraph.put(md, subGlobalFlowGraph);
+
+ addValueFlowsFromCalleeSubGlobalFlowGraph(md, subGlobalFlowGraph);
+
+ try {
+ subGlobalFlowGraph.writeGraph("_SUBGLOBAL");
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ // FlowGraph fg = new FlowGraph(md, mapParamDescToIdx);
+ // mapMethodDescriptorToFlowGraph.put(md, fg);
+ // analyzeMethodBody(md.getClassDesc(), md);
+
+ }
+ }
+ // _debug_printGraph();
+
+ }
+
+ private void addValueFlowsFromCalleeSubGlobalFlowGraph(MethodDescriptor mdCaller,
+ FlowGraph subGlobalFlowGraph) {
+
+ // the transformation for a call site propagates flows through parameters
+ // if the method is virtual, it also grab all relations from any possible
+ // callees
+
+ Set<MethodInvokeNode> setMethodInvokeNode = getMethodInvokeNodeSet(mdCaller);
+
+ for (Iterator iterator = setMethodInvokeNode.iterator(); iterator.hasNext();) {
+ MethodInvokeNode min = (MethodInvokeNode) iterator.next();
+ MethodDescriptor mdCallee = min.getMethod();
+ Set<MethodDescriptor> setPossibleCallees = new HashSet<MethodDescriptor>();
+ if (mdCallee.isStatic()) {
+ setPossibleCallees.add(mdCallee);
+ } else {
+ Set<MethodDescriptor> calleeSet = ssjava.getCallGraph().getMethods(mdCallee);
+ // removes method descriptors that are not invoked by the caller
+ calleeSet.retainAll(mapMethodToCalleeSet.get(mdCaller));
+ setPossibleCallees.addAll(calleeSet);
+ }
+
+ for (Iterator iterator2 = setPossibleCallees.iterator(); iterator2.hasNext();) {
+ MethodDescriptor possibleMdCallee = (MethodDescriptor) iterator2.next();
+ propagateValueFlowsToCallerFromSubGlobalFlowGraph(min, mdCaller, possibleMdCallee);
+ // propagateFlowsToCallerWithNoCompositeLocation(min, mdCaller, possibleMdCallee);
+ }
+
+ }
+
+ }
+
+ private void propagateValueFlowsToCallerFromSubGlobalFlowGraph(MethodInvokeNode min,
+ MethodDescriptor mdCaller, MethodDescriptor possibleMdCallee) {
+
+ NTuple<Descriptor> baseTuple = mapMethodInvokeNodeToBaseTuple.get(min);
+
+ FlowGraph callerSubGlobalGraph = getSubGlobalFlowGraph(mdCaller);
+ FlowGraph calleeSubGlobalGraph = getSubGlobalFlowGraph(possibleMdCallee);
+
+ int numParam = calleeSubGlobalGraph.getNumParameters();
+ for (int idx = 0; idx < numParam; idx++) {
+ FlowNode paramNode = calleeSubGlobalGraph.getParamFlowNode(idx);
+ NodeTupleSet argTupleSet = mapMethodInvokeNodeToArgIdxMap.get(min).get(idx);
+ System.out.println("argTupleSet=" + argTupleSet + " param=" + paramNode);
+ for (Iterator<NTuple<Descriptor>> iter = argTupleSet.iterator(); iter.hasNext();) {
+ NTuple<Descriptor> argTuple = iter.next();
+ addValueFlowsFromCalleeParam(calleeSubGlobalGraph, paramNode, callerSubGlobalGraph,
+ argTuple, baseTuple);
+ }
+ }
+
+ }
+
+ private void addValueFlowsFromCalleeParam(FlowGraph calleeSubGlobalGraph, FlowNode paramNode,
+ FlowGraph callerSubGlobalGraph, NTuple<Descriptor> argTuple, NTuple<Descriptor> baseTuple) {
+
+ Set<FlowNode> visited = new HashSet<FlowNode>();
+
+ visited.add(paramNode);
+ recurAddValueFlowsFromCalleeParam(calleeSubGlobalGraph, paramNode, callerSubGlobalGraph,
+ argTuple, visited, baseTuple);
+ }
+
+ private void recurAddValueFlowsFromCalleeParam(FlowGraph calleeSubGlobalGraph,
+ FlowNode calleeSrcNode, FlowGraph callerSubGlobalGraph, NTuple<Descriptor> callerSrcTuple,
+ Set<FlowNode> visited, NTuple<Descriptor> baseTuple) {
+
+ MethodDescriptor mdCallee = calleeSubGlobalGraph.getMethodDescriptor();
+
+ Set<FlowEdge> edgeSet = calleeSubGlobalGraph.getOutEdgeSet(calleeSrcNode);
+ for (Iterator iterator = edgeSet.iterator(); iterator.hasNext();) {
+ FlowEdge flowEdge = (FlowEdge) iterator.next();
+ FlowNode dstNode = flowEdge.getDst();
+
+ NTuple<Descriptor> dstDescTuple = dstNode.getCurrentDescTuple();
+ if (dstDescTuple.get(0).equals(mdCallee.getThis())) {
+ // destination node is started with 'this' variable
+ // need to translate it in terms of the caller's base node
+ dstDescTuple = translateToCaller(dstDescTuple, baseTuple);
+ }
+
+ callerSubGlobalGraph.addValueFlowEdge(callerSrcTuple, dstDescTuple);
+
+ if (!visited.contains(dstNode)) {
+ visited.add(dstNode);
+ recurAddValueFlowsFromCalleeParam(calleeSubGlobalGraph, dstNode, callerSubGlobalGraph,
+ dstDescTuple, visited, baseTuple);
+ }
+
+ }
+
+ }
+
+ private NTuple<Descriptor> translateToCaller(NTuple<Descriptor> dstDescTuple,
+ NTuple<Descriptor> baseTuple) {
+ NTuple<Descriptor> callerDescTuple = new NTuple<Descriptor>();
+
+ callerDescTuple.addAll(baseTuple);
+ for (int i = 1; i < dstDescTuple.size(); i++) {
+ callerDescTuple.add(dstDescTuple.get(i));
+ }
+
+ return callerDescTuple;
+ }
+
+ public LocationSummary getLocationSummary(Descriptor d) {
+ if (!mapDescToLocationSummary.containsKey(d)) {
+ if (d instanceof MethodDescriptor) {
+ mapDescToLocationSummary.put(d, new MethodSummary((MethodDescriptor) d));
+ } else if (d instanceof ClassDescriptor) {
+ mapDescToLocationSummary.put(d, new FieldSummary());
+ }
+ }
+ return mapDescToLocationSummary.get(d);
+ }
+
+ private void generateMethodSummary() {
+
+ Set<MethodDescriptor> keySet = md2lattice.keySet();
+ for (Iterator iterator = keySet.iterator(); iterator.hasNext();) {
+ MethodDescriptor md = (MethodDescriptor) iterator.next();
+
+ System.out.println("\nSSJAVA: generate method summary: " + md);
+
+ FlowGraph flowGraph = getFlowGraph(md);
+ MethodSummary methodSummary = getMethodSummary(md);
+
+ // construct a parameter mapping that maps a parameter descriptor to an inferred composite
+ // location
+
+ for (int paramIdx = 0; paramIdx < flowGraph.getNumParameters(); paramIdx++) {
+ FlowNode flowNode = flowGraph.getParamFlowNode(paramIdx);
+ NTuple<Descriptor> descTuple = flowNode.getDescTuple();
+
+ CompositeLocation assignedCompLoc = flowNode.getCompositeLocation();
+ CompositeLocation inferredCompLoc;
+ if (assignedCompLoc != null) {
+ inferredCompLoc = translateCompositeLocation(assignedCompLoc);
+ } else {
+ Descriptor locDesc = descTuple.get(0);
+ Location loc = new Location(md, locDesc.getSymbol());
+ loc.setLocDescriptor(locDesc);
+ inferredCompLoc = new CompositeLocation(loc);
+ }
+ System.out.println("-paramIdx=" + paramIdx + " infer=" + inferredCompLoc);
+ methodSummary.addMapParamIdxToInferLoc(paramIdx, inferredCompLoc);
+ }
+
+ }
+
+ }
+
+ private CompositeLocation translateCompositeLocation(CompositeLocation compLoc) {
+ CompositeLocation newCompLoc = new CompositeLocation();
+
+ // System.out.println("compLoc=" + compLoc);
+ for (int i = 0; i < compLoc.getSize(); i++) {
+ Location loc = compLoc.get(i);
+ Descriptor enclosingDescriptor = loc.getDescriptor();
+ Descriptor locDescriptor = loc.getLocDescriptor();
+
+ HNode hnode = getHierarchyGraph(enclosingDescriptor).getHNode(locDescriptor);
+ // System.out.println("-hnode=" + hnode + " from=" + locDescriptor +
+ // " enclosingDescriptor="
+ // + enclosingDescriptor);
+ // System.out.println("-getLocationSummary(enclosingDescriptor)="
+ // + getLocationSummary(enclosingDescriptor));
+ String locName = getLocationSummary(enclosingDescriptor).getLocationName(hnode.getName());
+ // System.out.println("-locName=" + locName);
+ Location newLoc = new Location(enclosingDescriptor, locName);
+ newLoc.setLocDescriptor(locDescriptor);
+ newCompLoc.addLocation(newLoc);
+ }
+
+ return newCompLoc;
+ }
+