@Override
  public void notifyCompilationTruffleTierFinished(
      OptimizedCallTarget target, TruffleInlining inliningDecision, StructuredGraph graph) {
    compilationLocal.get().truffleTierFinished = System.nanoTime();

    nodeStatistics.accept(
        target.nodeStream(inliningDecision).filter(n -> n != null).map(node -> node.getClass()));

    CallTargetNodeStatistics callTargetStat =
        new CallTargetNodeStatistics(target, inliningDecision);
    nodeCount.accept(callTargetStat.getNodeCount());
    nodeCountTrivial.accept(callTargetStat.getNodeCountTrivial());
    nodeCountNonTrivial.accept(callTargetStat.getNodeCountNonTrivial());
    nodeCountMonomorphic.accept(callTargetStat.getNodeCountMonomorphic());
    nodeCountPolymorphic.accept(callTargetStat.getNodeCountPolymorphic());
    nodeCountMegamorphic.accept(callTargetStat.getNodeCountMegamorphic());

    callCount.accept(callTargetStat.getCallCount());
    callCountIndirect.accept(callTargetStat.getCallCountIndirect());
    callCountDirect.accept(callTargetStat.getCallCountDirect());
    callCountDirectDispatched.accept(callTargetStat.getCallCountDirectDispatched());
    callCountDirectInlined.accept(callTargetStat.getCallCountDirectInlined());
    callCountDirectCloned.accept(callTargetStat.getCallCountDirectCloned());
    callCountDirectNotCloned.accept(callTargetStat.getCallCountDirectNotCloned());
    loopCount.accept(callTargetStat.getLoopCount());

    truffleTierNodeCount.accept(graph.getNodeCount());
    if (TruffleCompilerOptions.TruffleCompilationStatisticDetails.getValue()) {
      truffleTierNodeStatistics.accept(nodeClassStream(graph));
    }
  }
  @Override
  public void notifyCompilationGraalTierFinished(
      OptimizedCallTarget target, StructuredGraph graph) {
    compilationLocal.get().graalTierFinished = System.nanoTime();
    graalTierNodeCount.accept(graph.getNodeCount());

    if (TruffleCompilerOptions.TruffleCompilationStatisticDetails.getValue()) {
      graalTierNodeStatistics.accept(nodeClassStream(graph));
    }
  }
  public void printStatistics(GraalTruffleRuntime rt) {
    long endTime = System.nanoTime();
    rt.log("Truffle compilation statistics:");
    printStatistic(rt, "Compilations", compilations);
    printStatistic(rt, "  Success", success);
    printStatistic(rt, "  Failed", failures);
    printStatistic(rt, "  Interrupted", compilations - (success + failures));
    printStatistic(rt, "Invalidated", invalidations);
    printStatistic(rt, "Queues", queues);
    printStatistic(rt, "Dequeues", dequeues);
    printStatistic(rt, "Splits", splits);
    printStatistic(rt, "Compilation Accuracy", 1.0 - invalidations / (double) compilations);
    printStatistic(rt, "Queue Accuracy", 1.0 - dequeues / (double) queues);
    printStatistic(
        rt,
        "Compilation Utilization",
        compilationTime.getSum() / (double) (endTime - firstCompilation));
    printStatistic(rt, "Remaining Compilation Queue", rt.getCompilationQueueSize());
    printStatistic(rt, "Times defered until compilation", deferCompilations);

    printStatisticTime(rt, "Time to queue", timeToQueue);
    printStatisticTime(rt, "Time to compilation", timeToCompilation);

    printStatisticTime(rt, "Compilation time", compilationTime);
    printStatisticTime(rt, "  Truffle Tier", compilationTimeTruffleTier);
    printStatisticTime(rt, "  Graal Tier", compilationTimeGraalTier);
    printStatisticTime(rt, "  Code Installation", compilationTimeCodeInstallation);

    printStatistic(rt, "Truffle node count", nodeCount);
    printStatistic(rt, "  Trivial", nodeCountTrivial);
    printStatistic(rt, "  Non Trivial", nodeCountNonTrivial);
    printStatistic(rt, "    Monomorphic", nodeCountMonomorphic);
    printStatistic(rt, "    Polymorphic", nodeCountPolymorphic);
    printStatistic(rt, "    Megamorphic", nodeCountMegamorphic);
    printStatistic(rt, "Truffle call count", callCount);
    printStatistic(rt, "  Indirect", callCountIndirect);
    printStatistic(rt, "  Direct", callCountDirect);
    printStatistic(rt, "    Dispatched", callCountDirectDispatched);
    printStatistic(rt, "    Inlined", callCountDirectInlined);
    printStatistic(rt, "    ----------");
    printStatistic(rt, "    Cloned", callCountDirectCloned);
    printStatistic(rt, "    Not Cloned", callCountDirectNotCloned);
    printStatistic(rt, "Truffle loops", loopCount);
    printStatistic(rt, "Graal node count");
    printStatistic(rt, "  After Truffle Tier", truffleTierNodeCount);
    printStatistic(rt, "  After Graal Tier", graalTierNodeCount);

    printStatistic(rt, "Graal comilation result");
    printStatistic(rt, "  Code size", compilationResultCodeSize);
    printStatistic(rt, "  Total frame size", compilationResultTotalFrameSize);
    printStatistic(rt, "  Exception handlers", compilationResultExceptionHandlers);
    printStatistic(rt, "  Infopoints", compilationResultInfopoints);
    compilationResultInfopointStatistics.printStatistics(rt, identity());
    printStatistic(rt, "  Marks", compilationResultMarks);
    printStatistic(rt, "  Data references", compilationResultDataPatches);

    if (TruffleCompilerOptions.TruffleCompilationStatisticDetails.getValue()) {
      printStatistic(rt, "Truffle nodes");
      nodeStatistics.printStatistics(rt, Class::getSimpleName);
      printStatistic(rt, "Graal nodes after Truffle tier");
      truffleTierNodeStatistics.printStatistics(rt, Class::getSimpleName);
      printStatistic(rt, "Graal nodes after Graal tier");
      graalTierNodeStatistics.printStatistics(rt, Class::getSimpleName);
    }
  }
 public static void install(GraalTruffleRuntime runtime) {
   if (TruffleCompilerOptions.TruffleCompilationStatistics.getValue()
       || TruffleCompilerOptions.TruffleCompilationStatisticDetails.getValue()) {
     runtime.addCompilationListener(new CompilationStatisticsListener());
   }
 }