@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));
    }
  }
  @Override
  public void notifyCompilationSuccess(
      OptimizedCallTarget target,
      TruffleInlining inliningDecision,
      StructuredGraph graph,
      CompilationResult result) {
    success++;
    long compilationDone = System.nanoTime();

    CompilationLocal local = compilationLocal.get();

    compilationTime.accept(compilationDone - local.compilationStarted);
    compilationTimeTruffleTier.accept(local.truffleTierFinished - local.compilationStarted);
    compilationTimeGraalTier.accept(local.graalTierFinished - local.truffleTierFinished);
    compilationTimeCodeInstallation.accept(compilationDone - local.graalTierFinished);

    compilationResultCodeSize.accept(result.getTargetCodeSize());
    compilationResultTotalFrameSize.accept(result.getTotalFrameSize());
    compilationResultExceptionHandlers.accept(result.getExceptionHandlers().size());
    compilationResultInfopoints.accept(result.getInfopoints().size());
    compilationResultInfopointStatistics.accept(
        result.getInfopoints().stream().map(e -> e.reason.toString()));
    compilationResultMarks.accept(result.getMarks().size());
    compilationResultDataPatches.accept(result.getDataPatches().size());
  }
  @Override
  public void notifyCompilationStarted(OptimizedCallTarget target) {
    compilations++;
    CompilationLocal local = new CompilationLocal();
    local.compilationStarted = System.nanoTime();
    compilationLocal.set(local);

    OptimizedCompilationProfile profile = target.getCompilationProfile();
    if (profile != null) {
      deferCompilations.accept(profile.getDeferredCount());
      timeToCompilation.accept(local.compilationStarted - profile.getTimestamp());
    }
  }
  @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));
    }
  }