diff --git a/src/libexpr/eval-gc.cc b/src/libexpr/eval-gc.cc index baf9df332..c8e2adb94 100644 --- a/src/libexpr/eval-gc.cc +++ b/src/libexpr/eval-gc.cc @@ -155,6 +155,10 @@ static inline void initGCReal() there. */ GC_set_no_dls(1); + /* Enable perf measurements. This is just a setting; not much of a + start of something. */ + GC_start_performance_measurement(); + GC_INIT(); GC_set_oom_fn(oomHandler); @@ -205,6 +209,7 @@ static inline void initGCReal() #endif static bool gcInitialised = false; +static GC_word gcCyclesAfterInit = 0; void initGC() { @@ -216,6 +221,7 @@ void initGC() #endif gcInitialised = true; + gcCyclesAfterInit = GC_get_gc_no(); } void assertGCInitialized() @@ -223,4 +229,10 @@ void assertGCInitialized() assert(gcInitialised); } +size_t getGCCycles() +{ + assertGCInitialized(); + return GC_get_gc_no() - gcCyclesAfterInit; } + +} // namespace nix diff --git a/src/libexpr/eval-gc.hh b/src/libexpr/eval-gc.hh index cd4ea914d..76f019729 100644 --- a/src/libexpr/eval-gc.hh +++ b/src/libexpr/eval-gc.hh @@ -1,6 +1,8 @@ #pragma once ///@file +#include + namespace nix { /** @@ -13,4 +15,9 @@ void initGC(); */ void assertGCInitialized(); +/** + * The number of GC cycles since initGC(). + */ +size_t getGCCycles(); + } diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 4f01d0a62..11c3282ad 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -2610,6 +2610,11 @@ void EvalState::printStatistics() #if HAVE_BOEHMGC GC_word heapSize, totalBytes; GC_get_heap_usage_safe(&heapSize, 0, 0, 0, &totalBytes); + double gcFullOnlyTime = ({ + auto ms = GC_get_full_gc_total_time(); + ms * 0.001; + }); + auto gcCycles = getGCCycles(); #endif auto outPath = getEnv("NIX_SHOW_STATS_PATH").value_or("-"); @@ -2620,6 +2625,13 @@ void EvalState::printStatistics() #ifndef _WIN32 // TODO implement topObj["cpuTime"] = cpuTime; #endif + topObj["time"] = { + {"cpu", cpuTime}, +#ifdef HAVE_BOEHMGC + {GC_is_incremental_mode() ? "gcNonIncremental" : "gc", gcFullOnlyTime}, + {GC_is_incremental_mode() ? "gcNonIncrementalFraction" : "gcFraction", gcFullOnlyTime / cpuTime}, +#endif + }; topObj["envs"] = { {"number", nrEnvs}, {"elements", nrValuesInEnvs}, @@ -2661,6 +2673,7 @@ void EvalState::printStatistics() topObj["gc"] = { {"heapSize", heapSize}, {"totalBytes", totalBytes}, + {"cycles", gcCycles}, }; #endif