private void doVisitMethod( ProcessedMethod method, Map<ProcessedMethod, Object> colours, List<CallSite> calls) { if (colours.get(method) == GREY) { visitMethod(method, Collections.unmodifiableList(calls)); colours.put(method, BLACK); } }
/** * Traverse the call graph of <code>method</code>. * * @param method the root of a call graph * @param methods the map from method symbols to their processed form * @return the set of methods traversed in this scan if this is an idempotent scanner otherwise * the set of methods traversed in this and all previous scans */ public Set<ProcessedMethod> scan( ProcessedMethod method, Map<MethodSymbol, ProcessedMethod> methods) { Map<ProcessedMethod, Object> colours = this.colours; if (colours == null) { colours = new HashMap<ProcessedMethod, Object>(methods.size()); } scan(method, methods, colours, new Stack<CallSite>()); return colours.keySet(); }
private void scan( ProcessedMethod caller, Map<MethodSymbol, ProcessedMethod> methods, Map<ProcessedMethod, Object> colours, Stack<CallSite> calls) { Object colour = colours.get(caller); if (colour == WHITE) { colours.put(caller, GREY); if (caller.error == null) { // do inline first: for (CallSite call : caller.calls) { ProcessedMethod callee = methods.get(call.callee); if (callee != null && isEarlyMethod(callee)) { calls.push(new CallSite(callee.sym, caller.sym, call.call)); scan(callee, methods, colours, calls); calls.pop(); } } // Emit callees first if (isEarlyMethod(caller)) { doVisitMethod(caller, colours, calls); } for (CallSite call : caller.calls) { ProcessedMethod callee = methods.get(call.callee); if (callee != null && !isEarlyMethod(callee)) { calls.push(new CallSite(callee.sym, caller.sym, call.call)); scan(callee, methods, colours, calls); calls.pop(); } } } doVisitMethod(caller, colours, calls); } }