public MethodTypeFlow(OptionValues options, AnalysisMethod method) { super(method, null); this.method = method; this.localCallingContextDepth = PointstoOptions.MaxCallingContextDepth.getValue(options); this.originalMethodFlows = new MethodFlowsGraph(method); this.clonedMethodFlows = new ConcurrentHashMap<>(4, 0.75f, 1); }
/** * Add the context, if not already added, and return the method flows clone from that context. */ public MethodFlowsGraph addContext(BigBang bb, AnalysisContext calleeContext, InvokeTypeFlow reason) { // make sure that the method is parsed before attempting to clone it; // the parsing should always happen on the same thread this.ensureParsed(bb, reason); AnalysisContext newContext = bb.contextPolicy().peel(calleeContext, localCallingContextDepth); MethodFlowsGraph methodFlows = clonedMethodFlows.get(newContext); if (methodFlows == null) { MethodFlowsGraph newFlows = new MethodFlowsGraph(method, newContext); newFlows.cloneOriginalFlows(bb); MethodFlowsGraph oldFlows = clonedMethodFlows.putIfAbsent(newContext, newFlows); methodFlows = oldFlows != null ? oldFlows : newFlows; if (oldFlows == null) { // link uses after adding the clone to the map since linking uses might trigger // updates to the current method in the current context methodFlows.linkClones(bb); } } return methodFlows; }