예제 #1
0
 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);
   }
 }
예제 #2
0
 /**
  * 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();
 }
예제 #3
0
  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);
    }
  }