Global Metrics

path: .metrics.nargs.sum
old: 8.0
new: 13.0

path: .metrics.nargs.average
old: 0.8888888888888888
new: 0.52

path: .metrics.mi.mi_sei
old: 19.00998817955523
new: -24.20339226551669

path: .metrics.mi.mi_original
old: 38.381766447533096
new: 12.126494475652976

path: .metrics.mi.mi_visual_studio
old: 22.445477454697716
new: 7.091517237223963

path: .metrics.cyclomatic.sum
old: 31.0
new: 62.0

path: .metrics.cyclomatic.average
old: 2.5833333333333335
new: 1.8235294117647056

path: .metrics.nom.total
old: 9.0
new: 25.0

path: .metrics.nom.closures
old: 1.0
new: 0.0

path: .metrics.nom.functions
old: 8.0
new: 25.0

path: .metrics.cognitive.average
old: 2.888888888888889
new: 1.36

path: .metrics.cognitive.sum
old: 26.0
new: 34.0

path: .metrics.nexits.average
old: 0.7777777777777778
new: 0.52

path: .metrics.nexits.sum
old: 7.0
new: 13.0

path: .metrics.halstead.n2
old: 85.0
new: 180.0

path: .metrics.halstead.N2
old: 168.0
new: 395.0

path: .metrics.halstead.estimated_program_length
old: 685.6796784304042
new: 1502.1136429613348

path: .metrics.halstead.difficulty
old: 28.65882352941177
new: 34.013888888888886

path: .metrics.halstead.n1
old: 29.0
new: 31.0

path: .metrics.halstead.purity_ratio
old: 1.5339590121485551
new: 1.4961291264555128

path: .metrics.halstead.volume
old: 3054.301836331639
new: 7751.983585462014

path: .metrics.halstead.length
old: 447.0
new: 1004.0

path: .metrics.halstead.time
old: 4862.927629610374
new: 14648.617130244187

path: .metrics.halstead.bugs
old: 0.6571415880758816
new: 1.3706445199274797

path: .metrics.halstead.N1
old: 279.0
new: 609.0

path: .metrics.halstead.effort
old: 87532.69733298675
new: 263675.1083443954

path: .metrics.halstead.level
old: 0.03489326765188834
new: 0.02939975500204165

path: .metrics.halstead.vocabulary
old: 114.0
new: 211.0

path: .metrics.loc.sloc
old: 176.0
new: 425.0

path: .metrics.loc.blank
old: 11.0
new: 72.0

path: .metrics.loc.ploc
old: 117.0
new: 292.0

path: .metrics.loc.cloc
old: 48.0
new: 61.0

path: .metrics.loc.lloc
old: 52.0
new: 76.0

Spaces Data

Minimal test - lines (172, 176)

path: .spaces[0].spaces[7].metrics.cyclomatic.sum
old: 3.0
new: 2.0

path: .spaces[0].spaces[7].metrics.cyclomatic.average
old: 3.0
new: 2.0

path: .spaces[0].spaces[7].metrics.loc.sloc
old: 10.0
new: 5.0

path: .spaces[0].spaces[7].metrics.loc.lloc
old: 3.0
new: 1.0

path: .spaces[0].spaces[7].metrics.loc.ploc
old: 10.0
new: 5.0

path: .spaces[0].spaces[7].metrics.nargs.average
old: 5.0
new: 0.0

path: .spaces[0].spaces[7].metrics.nargs.sum
old: 5.0
new: 0.0

path: .spaces[0].spaces[7].metrics.cognitive.average
old: 1.0
new: 0.0

path: .spaces[0].spaces[7].metrics.cognitive.sum
old: 1.0
new: 0.0

path: .spaces[0].spaces[7].metrics.halstead.n1
old: 10.0
new: 8.0

path: .spaces[0].spaces[7].metrics.halstead.estimated_program_length
old: 76.2388309575275
new: 43.65148445440323

path: .spaces[0].spaces[7].metrics.halstead.purity_ratio
old: 1.5558945093372958
new: 2.297446550231749

path: .spaces[0].spaces[7].metrics.halstead.volume
old: 218.5121493132276
new: 74.23092131656186

path: .spaces[0].spaces[7].metrics.halstead.n2
old: 12.0
new: 7.0

path: .spaces[0].spaces[7].metrics.halstead.time
old: 96.10488048498436
new: 18.85229747722206

path: .spaces[0].spaces[7].metrics.halstead.N1
old: 30.0
new: 11.0

path: .spaces[0].spaces[7].metrics.halstead.length
old: 49.0
new: 19.0

path: .spaces[0].spaces[7].metrics.halstead.difficulty
old: 7.916666666666667
new: 4.571428571428571

path: .spaces[0].spaces[7].metrics.halstead.effort
old: 1729.8878487297184
new: 339.3413545899971

path: .spaces[0].spaces[7].metrics.halstead.vocabulary
old: 22.0
new: 15.0

path: .spaces[0].spaces[7].metrics.halstead.N2
old: 19.0
new: 8.0

path: .spaces[0].spaces[7].metrics.halstead.level
old: 0.1263157894736842
new: 0.21875

path: .spaces[0].spaces[7].metrics.halstead.bugs
old: 0.04803495379905817
new: 0.016216978391790506

path: .spaces[0].spaces[7].metrics.mi.mi_sei
old: 76.08260249653999
new: 100.61223333965796

path: .spaces[0].spaces[7].metrics.mi.mi_visual_studio
old: 61.401488356125995
new: 71.38582789270771

path: .spaces[0].spaces[7].metrics.mi.mi_original
old: 104.99654508897544
new: 122.06976569653015

Code

void nsAvailableMemoryWatcher::SendMemoryPressureEvent() {
  MemoryPressureState state =
      OngoingMemoryPressure() ? MemPressure_Ongoing : MemPressure_New;
  NS_DispatchEventualMemoryPressure(state);
}

Minimal test - lines (92, 92)

path: .spaces[0].spaces[1].spaces[0].metrics.halstead.bugs
old: 0.006944786620971931
new: 0.0017471609294725976

path: .spaces[0].spaces[1].spaces[0].metrics.halstead.level
old: 0.4
new: 0.6666666666666666

path: .spaces[0].spaces[1].spaces[0].metrics.halstead.vocabulary
old: 9.0
new: 4.0

path: .spaces[0].spaces[1].spaces[0].metrics.halstead.volume
old: 38.039100017307746
new: 8.0

path: .spaces[0].spaces[1].spaces[0].metrics.halstead.time
old: 5.2832083357371875
new: 0.6666666666666666

path: .spaces[0].spaces[1].spaces[0].metrics.halstead.difficulty
old: 2.5
new: 1.5

path: .spaces[0].spaces[1].spaces[0].metrics.halstead.length
old: 12.0
new: 4.0

path: .spaces[0].spaces[1].spaces[0].metrics.halstead.estimated_program_length
old: 19.60964047443681
new: 4.754887502163468

path: .spaces[0].spaces[1].spaces[0].metrics.halstead.n2
old: 4.0
new: 1.0

path: .spaces[0].spaces[1].spaces[0].metrics.halstead.N1
old: 8.0
new: 3.0

path: .spaces[0].spaces[1].spaces[0].metrics.halstead.effort
old: 95.09775004326936
new: 12.0

path: .spaces[0].spaces[1].spaces[0].metrics.halstead.purity_ratio
old: 1.6341367062030674
new: 1.188721875540867

path: .spaces[0].spaces[1].spaces[0].metrics.halstead.N2
old: 4.0
new: 1.0

path: .spaces[0].spaces[1].spaces[0].metrics.halstead.n1
old: 5.0
new: 3.0

path: .spaces[0].spaces[1].spaces[0].metrics.loc.ploc
old: 4.0
new: 1.0

path: .spaces[0].spaces[1].spaces[0].metrics.loc.cloc
old: 2.0
new: 0.0

path: .spaces[0].spaces[1].spaces[0].metrics.loc.sloc
old: 6.0
new: 1.0

path: .spaces[0].spaces[1].spaces[0].metrics.loc.lloc
old: 2.0
new: 0.0

path: .spaces[0].spaces[1].spaces[0].metrics.mi.mi_original
old: 122.82270079006472
new: 159.95690398326485

path: .spaces[0].spaces[1].spaces[0].metrics.mi.mi_visual_studio
old: 71.82614081290335
new: 93.54204911302038

path: .spaces[0].spaces[1].spaces[0].metrics.mi.mi_sei
old: 140.5892017250539
new: 155.17000000000002

Code

  ~nsAvailableMemoryWatcher(){};

Minimal test - lines (133, 145)

path: .spaces[0].spaces[4].metrics.loc.ploc
old: 43.0
new: 11.0

path: .spaces[0].spaces[4].metrics.loc.sloc
old: 58.0
new: 13.0

path: .spaces[0].spaces[4].metrics.loc.blank
old: 0.0
new: 2.0

path: .spaces[0].spaces[4].metrics.loc.cloc
old: 15.0
new: 0.0

path: .spaces[0].spaces[4].metrics.loc.lloc
old: 26.0
new: 5.0

path: .spaces[0].spaces[4].metrics.halstead.N1
old: 101.0
new: 29.0

path: .spaces[0].spaces[4].metrics.halstead.purity_ratio
old: 1.775526754090705
new: 2.157631600949801

path: .spaces[0].spaces[4].metrics.halstead.time
old: 827.3113510662622
new: 120.33522986244468

path: .spaces[0].spaces[4].metrics.halstead.length
old: 161.0
new: 47.0

path: .spaces[0].spaces[4].metrics.halstead.N2
old: 60.0
new: 18.0

path: .spaces[0].spaces[4].metrics.halstead.level
old: 0.06333333333333334
new: 0.10317460317460318

path: .spaces[0].spaces[4].metrics.halstead.difficulty
old: 15.789473684210526
new: 9.692307692307692

path: .spaces[0].spaces[4].metrics.halstead.n1
old: 20.0
new: 14.0

path: .spaces[0].spaces[4].metrics.halstead.vocabulary
old: 58.0
new: 27.0

path: .spaces[0].spaces[4].metrics.halstead.estimated_program_length
old: 285.8598074086035
new: 101.40868524464064

path: .spaces[0].spaces[4].metrics.halstead.volume
old: 943.134940215539
new: 223.47971260168305

path: .spaces[0].spaces[4].metrics.halstead.bugs
old: 0.2017621687013634
new: 0.05580275104439644

path: .spaces[0].spaces[4].metrics.halstead.n2
old: 38.0
new: 13.0

path: .spaces[0].spaces[4].metrics.halstead.effort
old: 14891.60431919272
new: 2166.034137524005

path: .spaces[0].spaces[4].metrics.cyclomatic.average
old: 8.0
new: 3.0

path: .spaces[0].spaces[4].metrics.cyclomatic.sum
old: 8.0
new: 3.0

path: .spaces[0].spaces[4].metrics.cognitive.average
old: 5.0
new: 1.0

path: .spaces[0].spaces[4].metrics.cognitive.sum
old: 10.0
new: 1.0

path: .spaces[0].spaces[4].metrics.nexits.average
old: 2.5
new: 0.0

path: .spaces[0].spaces[4].metrics.nexits.sum
old: 5.0
new: 0.0

path: .spaces[0].spaces[4].metrics.mi.mi_sei
old: 58.31935790013438
new: 69.78207625488035

path: .spaces[0].spaces[4].metrics.mi.mi_visual_studio
old: 39.62861667233742
new: 58.847574905570255

path: .spaces[0].spaces[4].metrics.mi.mi_original
old: 67.76493450969699
new: 100.62935308852514

path: .spaces[0].spaces[4].metrics.nom.total
old: 2.0
new: 1.0

path: .spaces[0].spaces[4].metrics.nom.closures
old: 1.0
new: 0.0

Code

void nsAvailableMemoryWatcher::Shutdown() {
  nsCOMPtr observerService = services::GetObserverService();
  MOZ_ASSERT(observerService);

  for (auto topic : kObserverTopics) {
    Unused << observerService->RemoveObserver(this, topic);
  }

  if (mTimer) {
    mTimer->Cancel();
    mTimer = nullptr;
  }
}

Minimal test - lines (159, 170)

path: .spaces[0].spaces[6].metrics.loc.blank
old: 0.0
new: 1.0

path: .spaces[0].spaces[6].metrics.loc.ploc
old: 10.0
new: 11.0

path: .spaces[0].spaces[6].metrics.loc.lloc
old: 4.0
new: 5.0

path: .spaces[0].spaces[6].metrics.loc.sloc
old: 10.0
new: 12.0

path: .spaces[0].spaces[6].metrics.cyclomatic.sum
old: 2.0
new: 3.0

path: .spaces[0].spaces[6].metrics.cyclomatic.average
old: 2.0
new: 3.0

path: .spaces[0].spaces[6].metrics.cognitive.average
old: 1.0
new: 2.0

path: .spaces[0].spaces[6].metrics.cognitive.sum
old: 1.0
new: 2.0

path: .spaces[0].spaces[6].metrics.mi.mi_visual_studio
old: 61.80996864927052
new: 60.019763600423126

path: .spaces[0].spaces[6].metrics.mi.mi_sei
old: 76.98850700054253
new: 72.67387575203644

path: .spaces[0].spaces[6].metrics.mi.mi_original
old: 105.6950463902526
new: 102.63379575672354

path: .spaces[0].spaces[6].metrics.halstead.n2
old: 13.0
new: 11.0

path: .spaces[0].spaces[6].metrics.halstead.volume
old: 199.68581616031315
new: 195.0419599705384

path: .spaces[0].spaces[6].metrics.halstead.difficulty
old: 7.384615384615385
new: 8.909090909090908

path: .spaces[0].spaces[6].metrics.halstead.bugs
old: 0.043184591013155665
new: 0.048178474062131174

path: .spaces[0].spaces[6].metrics.halstead.level
old: 0.13541666666666666
new: 0.11224489795918367

path: .spaces[0].spaces[6].metrics.halstead.estimated_program_length
old: 91.12526634448808
new: 91.35671671381672

path: .spaces[0].spaces[6].metrics.halstead.effort
old: 1474.602950106928
new: 1737.6465524647963

path: .spaces[0].spaces[6].metrics.halstead.purity_ratio
old: 2.11919224056949
new: 2.1751599217575412

path: .spaces[0].spaces[6].metrics.halstead.N1
old: 27.0
new: 28.0

path: .spaces[0].spaces[6].metrics.halstead.time
old: 81.92238611705154
new: 96.53591958137758

path: .spaces[0].spaces[6].metrics.halstead.length
old: 43.0
new: 42.0

path: .spaces[0].spaces[6].metrics.halstead.n1
old: 12.0
new: 14.0

path: .spaces[0].spaces[6].metrics.halstead.N2
old: 16.0
new: 14.0

Code

bool nsAvailableMemoryWatcher::IsCommitSpaceLow(const MEMORYSTATUSEX& aStat) {
  if ((kLowCommitSpaceThreshold != 0) &&
      (aStat.ullAvailPageFile < kLowCommitSpaceThreshold)) {
    sNumLowCommitSpaceEvents++;
    CrashReporter::AnnotateCrashReport(
        CrashReporter::Annotation::LowCommitSpaceEvents,
        uint32_t(sNumLowCommitSpaceEvents));
    return true;
  }

  return false;
}

Minimal test - lines (148, 156)

path: .spaces[0].spaces[5].metrics.cyclomatic.average
old: 1.0
new: 3.0

path: .spaces[0].spaces[5].metrics.cyclomatic.sum
old: 1.0
new: 3.0

path: .spaces[0].spaces[5].metrics.nexits.average
old: 0.0
new: 2.0

path: .spaces[0].spaces[5].metrics.nexits.sum
old: 0.0
new: 2.0

path: .spaces[0].spaces[5].metrics.loc.ploc
old: 1.0
new: 8.0

path: .spaces[0].spaces[5].metrics.loc.sloc
old: 1.0
new: 9.0

path: .spaces[0].spaces[5].metrics.loc.lloc
old: 1.0
new: 4.0

path: .spaces[0].spaces[5].metrics.loc.blank
old: 0.0
new: 1.0

path: .spaces[0].spaces[5].metrics.nargs.average
old: 0.0
new: 1.0

path: .spaces[0].spaces[5].metrics.nargs.sum
old: 0.0
new: 1.0

path: .spaces[0].spaces[5].metrics.cognitive.average
old: 0.0
new: 2.0

path: .spaces[0].spaces[5].metrics.cognitive.sum
old: 0.0
new: 2.0

path: .spaces[0].spaces[5].metrics.mi.mi_visual_studio
old: 89.35513233151332
new: 63.7918815961899

path: .spaces[0].spaces[5].metrics.mi.mi_sei
old: 144.8408406278255
new: 81.97972298573713

path: .spaces[0].spaces[5].metrics.mi.mi_original
old: 152.79727628688778
new: 109.08411752948474

path: .spaces[0].spaces[5].metrics.halstead.estimated_program_length
old: 20.264662506490403
new: 76.63504134881501

path: .spaces[0].spaces[5].metrics.halstead.difficulty
old: 3.0
new: 7.944444444444445

path: .spaces[0].spaces[5].metrics.halstead.n2
old: 3.0
new: 9.0

path: .spaces[0].spaces[5].metrics.halstead.n1
old: 6.0
new: 13.0

path: .spaces[0].spaces[5].metrics.halstead.N1
old: 7.0
new: 20.0

path: .spaces[0].spaces[5].metrics.halstead.effort
old: 95.09775004326936
new: 1098.2589091899522

path: .spaces[0].spaces[5].metrics.halstead.volume
old: 31.69925001442312
new: 138.24238017775622

path: .spaces[0].spaces[5].metrics.halstead.N2
old: 3.0
new: 11.0

path: .spaces[0].spaces[5].metrics.halstead.bugs
old: 0.006944786620971931
new: 0.035482583648985856

path: .spaces[0].spaces[5].metrics.halstead.level
old: 0.3333333333333333
new: 0.12587412587412586

path: .spaces[0].spaces[5].metrics.halstead.vocabulary
old: 9.0
new: 22.0

path: .spaces[0].spaces[5].metrics.halstead.length
old: 10.0
new: 31.0

path: .spaces[0].spaces[5].metrics.halstead.time
old: 5.2832083357371875
new: 61.01438384388624

path: .spaces[0].spaces[5].metrics.halstead.purity_ratio
old: 2.0264662506490403
new: 2.4720981080262905

Code

bool nsAvailableMemoryWatcher::IsVirtualMemoryLow(const MEMORYSTATUSEX& aStat) {
  if ((kLowVirtualMemoryThreshold != 0) &&
      (aStat.ullAvailVirtual < kLowVirtualMemoryThreshold)) {
    sNumLowVirtualMemEvents++;
    return true;
  }

  return false;
}

Minimal test - lines (113, 114)

path: .spaces[0].spaces[2].metrics.mi.mi_visual_studio
old: 65.63997397571175
new: 81.0934572754703

path: .spaces[0].spaces[2].metrics.mi.mi_original
old: 112.2443554984671
new: 138.6698119410542

path: .spaces[0].spaces[2].metrics.mi.mi_sei
old: 86.53898263161697
new: 124.45921787575575

path: .spaces[0].spaces[2].metrics.cyclomatic.sum
old: 3.0
new: 1.0

path: .spaces[0].spaces[2].metrics.cyclomatic.average
old: 1.5
new: 1.0

path: .spaces[0].spaces[2].metrics.loc.sloc
old: 9.0
new: 2.0

path: .spaces[0].spaces[2].metrics.loc.lloc
old: 4.0
new: 0.0

path: .spaces[0].spaces[2].metrics.loc.ploc
old: 9.0
new: 2.0

path: .spaces[0].spaces[2].metrics.halstead.n1
old: 7.0
new: 5.0

path: .spaces[0].spaces[2].metrics.halstead.N1
old: 13.0
new: 9.0

path: .spaces[0].spaces[2].metrics.halstead.level
old: 0.17857142857142858
new: 0.34285714285714286

path: .spaces[0].spaces[2].metrics.halstead.N2
old: 8.0
new: 7.0

path: .spaces[0].spaces[2].metrics.halstead.difficulty
old: 5.6
new: 2.9166666666666665

path: .spaces[0].spaces[2].metrics.halstead.estimated_program_length
old: 31.26112492884004
new: 27.11941547876375

path: .spaces[0].spaces[2].metrics.halstead.time
old: 23.421755004711553
new: 8.96889678905966

path: .spaces[0].spaces[2].metrics.halstead.effort
old: 421.59159008480793
new: 161.44014220307386

path: .spaces[0].spaces[2].metrics.halstead.bugs
old: 0.018741601728696464
new: 0.009882946238954084

path: .spaces[0].spaces[2].metrics.halstead.n2
old: 5.0
new: 6.0

path: .spaces[0].spaces[2].metrics.halstead.purity_ratio
old: 1.4886249966114304
new: 1.6949634674227343

path: .spaces[0].spaces[2].metrics.halstead.volume
old: 75.28421251514428
new: 55.35090589819676

path: .spaces[0].spaces[2].metrics.halstead.vocabulary
old: 12.0
new: 11.0

path: .spaces[0].spaces[2].metrics.halstead.length
old: 21.0
new: 16.0

path: .spaces[0].spaces[2].metrics.cognitive.average
old: 1.0
new: 0.0

path: .spaces[0].spaces[2].metrics.cognitive.sum
old: 1.0
new: 0.0

Code

nsAvailableMemoryWatcher::nsAvailableMemoryWatcher()
    : mTimer(nullptr), mUnderMemoryPressure(false), mSavedReport(false) {}

Minimal test - lines (57, 103)

path: .spaces[0].spaces[1].metrics.cyclomatic.sum
old: 2.0
new: 3.0

path: .spaces[0].spaces[1].metrics.nom.functions
old: 1.0
new: 2.0

path: .spaces[0].spaces[1].metrics.nom.total
old: 1.0
new: 2.0

path: .spaces[0].spaces[1].metrics.loc.ploc
old: 6.0
new: 31.0

path: .spaces[0].spaces[1].metrics.loc.lloc
old: 2.0
new: 1.0

path: .spaces[0].spaces[1].metrics.loc.blank
old: 0.0
new: 9.0

path: .spaces[0].spaces[1].metrics.loc.cloc
old: 2.0
new: 7.0

path: .spaces[0].spaces[1].metrics.loc.sloc
old: 8.0
new: 47.0

path: .spaces[0].spaces[1].metrics.halstead.bugs
old: 0.008930931841887613
new: 0.11022749495637564

path: .spaces[0].spaces[1].metrics.halstead.effort
old: 138.68421881310115
new: 6013.354243047388

path: .spaces[0].spaces[1].metrics.halstead.time
old: 7.704678822950064
new: 334.0752357248549

path: .spaces[0].spaces[1].metrics.halstead.length
old: 14.0
new: 119.0

path: .spaces[0].spaces[1].metrics.halstead.n1
old: 5.0
new: 14.0

path: .spaces[0].spaces[1].metrics.halstead.N1
old: 9.0
new: 74.0

path: .spaces[0].spaces[1].metrics.halstead.level
old: 0.32
new: 0.1111111111111111

path: .spaces[0].spaces[1].metrics.halstead.vocabulary
old: 9.0
new: 49.0

path: .spaces[0].spaces[1].metrics.halstead.N2
old: 5.0
new: 45.0

path: .spaces[0].spaces[1].metrics.halstead.volume
old: 44.37895002019237
new: 668.1504714497098

path: .spaces[0].spaces[1].metrics.halstead.n2
old: 4.0
new: 35.0

path: .spaces[0].spaces[1].metrics.halstead.purity_ratio
old: 1.400688605316915
new: 1.9565367605200024

path: .spaces[0].spaces[1].metrics.halstead.estimated_program_length
old: 19.60964047443681
new: 232.82787450188027

path: .spaces[0].spaces[1].metrics.halstead.difficulty
old: 3.125
new: 9.0

path: .spaces[0].spaces[1].metrics.nexits.sum
old: 0.0
new: 1.0

path: .spaces[0].spaces[1].metrics.nexits.average
old: 0.0
new: 0.5

path: .spaces[0].spaces[1].metrics.mi.mi_sei
old: 128.4580146497127
new: 59.67281030747717

path: .spaces[0].spaces[1].metrics.mi.mi_original
old: 117.13066768124412
new: 74.1141391471737

path: .spaces[0].spaces[1].metrics.mi.mi_visual_studio
old: 68.49746648025972
new: 43.341601840452455

Code

class nsAvailableMemoryWatcher final : public nsIObserver,
                                       public nsITimerCallback {
 public:
  NS_DECL_ISUPPORTS
  NS_DECL_NSIOBSERVER
  NS_DECL_NSITIMERCALLBACK

  nsAvailableMemoryWatcher();
  nsresult Init();

 private:
  // Fire a low-memory notification if we have less than this many bytes of
  // virtual address space available.
#  if defined(HAVE_64BIT_BUILD)
  static const size_t kLowVirtualMemoryThreshold = 0;
#  else
  static const size_t kLowVirtualMemoryThreshold = 384 * 1024 * 1024;
#  endif

  // Fire a low-memory notification if we have less than this many bytes of
  // commit space (physical memory plus page file) left.
  static const size_t kLowCommitSpaceThreshold = 384 * 1024 * 1024;

  // Don't fire a low-memory notification more often than this interval.
  static const uint32_t kLowMemoryNotificationIntervalMS = 10000;

  // Poll the amount of free memory at this rate.
  static const uint32_t kPollingIntervalMS = 1000;

  // Observer topics we subscribe to, see below.
  static const char* const kObserverTopics[];

  static bool IsVirtualMemoryLow(const MEMORYSTATUSEX& aStat);
  static bool IsCommitSpaceLow(const MEMORYSTATUSEX& aStat);

  ~nsAvailableMemoryWatcher(){};
  bool OngoingMemoryPressure() { return mUnderMemoryPressure; }
  void AdjustPollingInterval(const bool aLowMemory);
  void SendMemoryPressureEvent();
  void MaybeSendMemoryPressureStopEvent();
  void MaybeSaveMemoryReport();
  void Shutdown();

  nsCOMPtr mTimer;
  bool mUnderMemoryPressure;
  bool mSavedReport;
};

Minimal test - lines (35, 397)

path: .spaces[0].metrics.halstead.N2
old: 162.0
new: 349.0

path: .spaces[0].metrics.halstead.n1
old: 29.0
new: 31.0

path: .spaces[0].metrics.halstead.bugs
old: 0.6623494331190752
new: 1.308090879472304

path: .spaces[0].metrics.halstead.length
old: 441.0
new: 914.0

path: .spaces[0].metrics.halstead.time
old: 4920.850040420995
new: 13657.34415269519

path: .spaces[0].metrics.halstead.level
old: 0.033631332481907195
new: 0.02791385525464461

path: .spaces[0].metrics.halstead.n2
old: 79.0
new: 151.0

path: .spaces[0].metrics.halstead.estimated_program_length
old: 638.8801279646907
new: 1246.57920126008

path: .spaces[0].metrics.halstead.purity_ratio
old: 1.448707773162564
new: 1.363872211444289

path: .spaces[0].metrics.halstead.difficulty
old: 29.73417721518987
new: 35.824503311258276

path: .spaces[0].metrics.halstead.N1
old: 279.0
new: 565.0

path: .spaces[0].metrics.halstead.vocabulary
old: 108.0
new: 182.0

path: .spaces[0].metrics.halstead.volume
old: 2978.9053884540895
new: 6862.124301141608

path: .spaces[0].metrics.halstead.effort
old: 88575.30072757792
new: 245832.19474851343

path: .spaces[0].metrics.cyclomatic.sum
old: 30.0
new: 56.0

path: .spaces[0].metrics.cyclomatic.average
old: 2.727272727272727
new: 1.8666666666666667

path: .spaces[0].metrics.nom.closures
old: 1.0
new: 0.0

path: .spaces[0].metrics.nom.functions
old: 8.0
new: 24.0

path: .spaces[0].metrics.nom.total
old: 9.0
new: 24.0

path: .spaces[0].metrics.nargs.sum
old: 8.0
new: 13.0

path: .spaces[0].metrics.nargs.average
old: 0.8888888888888888
new: 0.5416666666666666

path: .spaces[0].metrics.cognitive.sum
old: 26.0
new: 31.0

path: .spaces[0].metrics.cognitive.average
old: 2.888888888888889
new: 1.2916666666666667

path: .spaces[0].metrics.loc.cloc
old: 42.0
new: 50.0

path: .spaces[0].metrics.loc.blank
old: 9.0
new: 64.0

path: .spaces[0].metrics.loc.lloc
old: 52.0
new: 69.0

path: .spaces[0].metrics.loc.sloc
old: 162.0
new: 363.0

path: .spaces[0].metrics.loc.ploc
old: 111.0
new: 249.0

path: .spaces[0].metrics.nexits.average
old: 0.7777777777777778
new: 0.5416666666666666

path: .spaces[0].metrics.nexits.sum
old: 7.0
new: 13.0

path: .spaces[0].metrics.mi.mi_sei
old: 20.659265851248648
new: -18.72301930709246

path: .spaces[0].metrics.mi.mi_original
old: 40.08452116714089
new: 16.695057929009295

path: .spaces[0].metrics.mi.mi_visual_studio
old: 23.441240448620405
new: 9.763191771350463

Code

namespace {

#if defined(XP_WIN)

#  if (NTDDI_VERSION < NTDDI_WINBLUE) || \
      (NTDDI_VERSION == NTDDI_WINBLUE && !defined(WINBLUE_KBSPRING14))
// Definitions for heap optimization that require the Windows SDK to target the
// Windows 8.1 Update
static const HEAP_INFORMATION_CLASS HeapOptimizeResources =
    static_cast(3);

static const DWORD HEAP_OPTIMIZE_RESOURCES_CURRENT_VERSION = 1;

typedef struct _HEAP_OPTIMIZE_RESOURCES_INFORMATION {
  DWORD Version;
  DWORD Flags;
} HEAP_OPTIMIZE_RESOURCES_INFORMATION, *PHEAP_OPTIMIZE_RESOURCES_INFORMATION;
#  endif

Atomic sNumLowVirtualMemEvents;
Atomic sNumLowCommitSpaceEvents;

class nsAvailableMemoryWatcher final : public nsIObserver,
                                       public nsITimerCallback {
 public:
  NS_DECL_ISUPPORTS
  NS_DECL_NSIOBSERVER
  NS_DECL_NSITIMERCALLBACK

  nsAvailableMemoryWatcher();
  nsresult Init();

 private:
  // Fire a low-memory notification if we have less than this many bytes of
  // virtual address space available.
#  if defined(HAVE_64BIT_BUILD)
  static const size_t kLowVirtualMemoryThreshold = 0;
#  else
  static const size_t kLowVirtualMemoryThreshold = 384 * 1024 * 1024;
#  endif

  // Fire a low-memory notification if we have less than this many bytes of
  // commit space (physical memory plus page file) left.
  static const size_t kLowCommitSpaceThreshold = 384 * 1024 * 1024;

  // Don't fire a low-memory notification more often than this interval.
  static const uint32_t kLowMemoryNotificationIntervalMS = 10000;

  // Poll the amount of free memory at this rate.
  static const uint32_t kPollingIntervalMS = 1000;

  // Observer topics we subscribe to, see below.
  static const char* const kObserverTopics[];

  static bool IsVirtualMemoryLow(const MEMORYSTATUSEX& aStat);
  static bool IsCommitSpaceLow(const MEMORYSTATUSEX& aStat);

  ~nsAvailableMemoryWatcher(){};
  bool OngoingMemoryPressure() { return mUnderMemoryPressure; }
  void AdjustPollingInterval(const bool aLowMemory);
  void SendMemoryPressureEvent();
  void MaybeSendMemoryPressureStopEvent();
  void MaybeSaveMemoryReport();
  void Shutdown();

  nsCOMPtr mTimer;
  bool mUnderMemoryPressure;
  bool mSavedReport;
};

const char* const nsAvailableMemoryWatcher::kObserverTopics[] = {
    "quit-application",
    "user-interaction-active",
    "user-interaction-inactive",
};

NS_IMPL_ISUPPORTS(nsAvailableMemoryWatcher, nsIObserver, nsITimerCallback)

nsAvailableMemoryWatcher::nsAvailableMemoryWatcher()
    : mTimer(nullptr), mUnderMemoryPressure(false), mSavedReport(false) {}

nsresult nsAvailableMemoryWatcher::Init() {
  mTimer = NS_NewTimer();

  nsCOMPtr observerService = services::GetObserverService();
  MOZ_ASSERT(observerService);

  for (auto topic : kObserverTopics) {
    nsresult rv = observerService->AddObserver(this, topic,
                                               /* ownsWeak */ false);
    NS_ENSURE_SUCCESS(rv, rv);
  }

  MOZ_TRY(mTimer->InitWithCallback(this, kPollingIntervalMS,
                                   nsITimer::TYPE_REPEATING_SLACK));
  return NS_OK;
}

void nsAvailableMemoryWatcher::Shutdown() {
  nsCOMPtr observerService = services::GetObserverService();
  MOZ_ASSERT(observerService);

  for (auto topic : kObserverTopics) {
    Unused << observerService->RemoveObserver(this, topic);
  }

  if (mTimer) {
    mTimer->Cancel();
    mTimer = nullptr;
  }
}

/* static */
bool nsAvailableMemoryWatcher::IsVirtualMemoryLow(const MEMORYSTATUSEX& aStat) {
  if ((kLowVirtualMemoryThreshold != 0) &&
      (aStat.ullAvailVirtual < kLowVirtualMemoryThreshold)) {
    sNumLowVirtualMemEvents++;
    return true;
  }

  return false;
}

/* static */
bool nsAvailableMemoryWatcher::IsCommitSpaceLow(const MEMORYSTATUSEX& aStat) {
  if ((kLowCommitSpaceThreshold != 0) &&
      (aStat.ullAvailPageFile < kLowCommitSpaceThreshold)) {
    sNumLowCommitSpaceEvents++;
    CrashReporter::AnnotateCrashReport(
        CrashReporter::Annotation::LowCommitSpaceEvents,
        uint32_t(sNumLowCommitSpaceEvents));
    return true;
  }

  return false;
}

void nsAvailableMemoryWatcher::SendMemoryPressureEvent() {
  MemoryPressureState state =
      OngoingMemoryPressure() ? MemPressure_Ongoing : MemPressure_New;
  NS_DispatchEventualMemoryPressure(state);
}

void nsAvailableMemoryWatcher::MaybeSendMemoryPressureStopEvent() {
  if (OngoingMemoryPressure()) {
    NS_DispatchEventualMemoryPressure(MemPressure_Stopping);
  }
}

void nsAvailableMemoryWatcher::MaybeSaveMemoryReport() {
  if (!mSavedReport && OngoingMemoryPressure()) {
    nsCOMPtr cr =
        do_GetService("@mozilla.org/toolkit/crash-reporter;1");
    if (cr) {
      if (NS_SUCCEEDED(cr->SaveMemoryReport())) {
        mSavedReport = true;
      }
    }
  }
}

void nsAvailableMemoryWatcher::AdjustPollingInterval(const bool aLowMemory) {
  if (aLowMemory) {
    // We entered a low-memory state, wait for a longer interval before polling
    // again as there's no point in rapidly sending further notifications.
    mTimer->SetDelay(kLowMemoryNotificationIntervalMS);
  } else if (OngoingMemoryPressure()) {
    // We were under memory pressure but we're not anymore, resume polling at
    // a faster pace.
    mTimer->SetDelay(kPollingIntervalMS);
  }
}

// Timer callback, polls memory stats to detect low-memory conditions. This
// will send memory-pressure events if memory is running low and adjust the
// polling interval accordingly.
NS_IMETHODIMP
nsAvailableMemoryWatcher::Notify(nsITimer* aTimer) {
  MEMORYSTATUSEX stat;
  stat.dwLength = sizeof(stat);
  bool success = GlobalMemoryStatusEx(&stat);

  if (success) {
    bool lowMemory = IsVirtualMemoryLow(stat) || IsCommitSpaceLow(stat);

    if (lowMemory) {
      SendMemoryPressureEvent();
    } else {
      MaybeSendMemoryPressureStopEvent();
    }

    if (lowMemory) {
      MaybeSaveMemoryReport();
    } else {
      mSavedReport = false;  // Save a new report if memory gets low again
    }

    AdjustPollingInterval(lowMemory);
    mUnderMemoryPressure = lowMemory;
  }

  return NS_OK;
}

// Observer service callback, used to stop the polling timer when the user
// stops interacting with Firefox and resuming it when they interact again.
// Also used to shut down the service if the application is quitting.
NS_IMETHODIMP
nsAvailableMemoryWatcher::Observe(nsISupports* aSubject, const char* aTopic,
                                  const char16_t* aData) {
  if (strcmp(aTopic, "quit-application") == 0) {
    Shutdown();
  } else if (strcmp(aTopic, "user-interaction-inactive") == 0) {
    mTimer->Cancel();
  } else if (strcmp(aTopic, "user-interaction-active") == 0) {
    mTimer->InitWithCallback(this, kPollingIntervalMS,
                             nsITimer::TYPE_REPEATING_SLACK);
  } else {
    MOZ_ASSERT_UNREACHABLE("Unknown topic");
  }

  return NS_OK;
}

static int64_t LowMemoryEventsVirtualDistinguishedAmount() {
  return sNumLowVirtualMemEvents;
}

static int64_t LowMemoryEventsCommitSpaceDistinguishedAmount() {
  return sNumLowCommitSpaceEvents;
}

class LowEventsReporter final : public nsIMemoryReporter {
  ~LowEventsReporter() {}

 public:
  NS_DECL_ISUPPORTS

  NS_IMETHOD CollectReports(nsIHandleReportCallback* aHandleReport,
                            nsISupports* aData, bool aAnonymize) override {
    // clang-format off
    MOZ_COLLECT_REPORT(
      "low-memory-events/virtual", KIND_OTHER, UNITS_COUNT_CUMULATIVE,
      LowMemoryEventsVirtualDistinguishedAmount(),
"Number of low-virtual-memory events fired since startup. We fire such an "
"event if we notice there is less than predefined amount of virtual address "
"space available (if zero, this behavior is disabled, see "
"xpcom/base/AvailableMemoryTracker.cpp). The process will probably crash if "
"it runs out of virtual address space, so this event is dire.");

    MOZ_COLLECT_REPORT(
      "low-memory-events/commit-space", KIND_OTHER, UNITS_COUNT_CUMULATIVE,
      LowMemoryEventsCommitSpaceDistinguishedAmount(),
"Number of low-commit-space events fired since startup. We fire such an "
"event if we notice there is less than a predefined amount of commit space "
"available (if zero, this behavior is disabled, see "
"xpcom/base/AvailableMemoryTracker.cpp). Windows will likely kill the process "
"if it runs out of commit space, so this event is dire.");
    // clang-format on

    return NS_OK;
  }
};
NS_IMPL_ISUPPORTS(LowEventsReporter, nsIMemoryReporter)

#endif  // defined(XP_WIN)

/**
 * This runnable is executed in response to a memory-pressure event; we spin
 * the event-loop when receiving the memory-pressure event in the hope that
 * other observers will synchronously free some memory that we'll be able to
 * purge here.
 */
class nsJemallocFreeDirtyPagesRunnable final : public Runnable {
  ~nsJemallocFreeDirtyPagesRunnable() = default;

#if defined(XP_WIN)
  void OptimizeSystemHeap();
#endif

 public:
  NS_DECL_NSIRUNNABLE

  nsJemallocFreeDirtyPagesRunnable()
      : Runnable("nsJemallocFreeDirtyPagesRunnable") {}
};

NS_IMETHODIMP
nsJemallocFreeDirtyPagesRunnable::Run() {
  MOZ_ASSERT(NS_IsMainThread());

#if defined(MOZ_MEMORY)
  jemalloc_free_dirty_pages();
#endif

#if defined(XP_WIN)
  OptimizeSystemHeap();
#endif

  return NS_OK;
}

#if defined(XP_WIN)
void nsJemallocFreeDirtyPagesRunnable::OptimizeSystemHeap() {
  // HeapSetInformation exists prior to Windows 8.1, but the
  // HeapOptimizeResources information class does not.
  if (IsWin8Point1OrLater()) {
    HEAP_OPTIMIZE_RESOURCES_INFORMATION heapOptInfo = {
        HEAP_OPTIMIZE_RESOURCES_CURRENT_VERSION};

    ::HeapSetInformation(nullptr, HeapOptimizeResources, &heapOptInfo,
                         sizeof(heapOptInfo));
  }
}
#endif  // defined(XP_WIN)

/**
 * The memory pressure watcher is used for listening to memory-pressure events
 * and reacting upon them. We use one instance per process currently only for
 * cleaning up dirty unused pages held by jemalloc.
 */
class nsMemoryPressureWatcher final : public nsIObserver {
  ~nsMemoryPressureWatcher() = default;

 public:
  NS_DECL_ISUPPORTS
  NS_DECL_NSIOBSERVER

  void Init();
};

NS_IMPL_ISUPPORTS(nsMemoryPressureWatcher, nsIObserver)

/**
 * Initialize and subscribe to the memory-pressure events. We subscribe to the
 * observer service in this method and not in the constructor because we need
 * to hold a strong reference to 'this' before calling the observer service.
 */
void nsMemoryPressureWatcher::Init() {
  nsCOMPtr os = services::GetObserverService();

  if (os) {
    os->AddObserver(this, "memory-pressure", /* ownsWeak */ false);
  }
}

/**
 * Reacts to all types of memory-pressure events, launches a runnable to
 * free dirty pages held by jemalloc.
 */
NS_IMETHODIMP
nsMemoryPressureWatcher::Observe(nsISupports* aSubject, const char* aTopic,
                                 const char16_t* aData) {
  MOZ_ASSERT(!strcmp(aTopic, "memory-pressure"), "Unknown topic");

  nsCOMPtr runnable = new nsJemallocFreeDirtyPagesRunnable();

  NS_DispatchToMainThread(runnable);

  return NS_OK;
}

}  // namespace

Minimal test - lines (48, 51)

path: .spaces[0].spaces[0].metrics.nexits.average
old: 0.0
new: null

path: .spaces[0].spaces[0].metrics.mi.mi_original
old: 112.52433481121324
new: 132.56043812602817

path: .spaces[0].spaces[0].metrics.mi.mi_visual_studio
old: 65.80370456796095
new: 77.52072405030886

path: .spaces[0].spaces[0].metrics.mi.mi_sei
old: 86.94290739766731
new: 115.6452545698808

path: .spaces[0].spaces[0].metrics.cognitive.sum
old: 2.0
new: 0.0

path: .spaces[0].spaces[0].metrics.cognitive.average
old: 2.0
new: null

path: .spaces[0].spaces[0].metrics.nom.functions
old: 1.0
new: 0.0

path: .spaces[0].spaces[0].metrics.nom.total
old: 1.0
new: 0.0

path: .spaces[0].spaces[0].metrics.halstead.n1
old: 11.0
new: 3.0

path: .spaces[0].spaces[0].metrics.halstead.time
old: 56.36226073555473
new: 1.723308333814104

path: .spaces[0].spaces[0].metrics.halstead.vocabulary
old: 22.0
new: 6.0

path: .spaces[0].spaces[0].metrics.halstead.length
old: 35.0
new: 8.0

path: .spaces[0].spaces[0].metrics.halstead.n2
old: 11.0
new: 3.0

path: .spaces[0].spaces[0].metrics.halstead.difficulty
old: 6.5
new: 1.5

path: .spaces[0].spaces[0].metrics.halstead.level
old: 0.15384615384615383
new: 0.6666666666666666

path: .spaces[0].spaces[0].metrics.halstead.N1
old: 22.0
new: 5.0

path: .spaces[0].spaces[0].metrics.halstead.effort
old: 1014.5206932399852
new: 31.019550008653873

path: .spaces[0].spaces[0].metrics.halstead.bugs
old: 0.033655239474984285
new: 0.003290806962640765

path: .spaces[0].spaces[0].metrics.halstead.purity_ratio
old: 2.174499874572015
new: 1.188721875540867

path: .spaces[0].spaces[0].metrics.halstead.volume
old: 156.0801066523054
new: 20.67970000576925

path: .spaces[0].spaces[0].metrics.halstead.N2
old: 13.0
new: 3.0

path: .spaces[0].spaces[0].metrics.halstead.estimated_program_length
old: 76.10749561002054
new: 9.509775004326936

path: .spaces[0].spaces[0].metrics.nargs.average
old: 0.0
new: null

path: .spaces[0].spaces[0].metrics.cyclomatic.sum
old: 3.0
new: 1.0

path: .spaces[0].spaces[0].metrics.cyclomatic.average
old: 3.0
new: 1.0

path: .spaces[0].spaces[0].metrics.loc.lloc
old: 3.0
new: 0.0

path: .spaces[0].spaces[0].metrics.loc.ploc
old: 7.0
new: 4.0

path: .spaces[0].spaces[0].metrics.loc.sloc
old: 7.0
new: 4.0

Code

typedef struct _HEAP_OPTIMIZE_RESOURCES_INFORMATION {
  DWORD Version;
  DWORD Flags;
} HEAP_OPTIMIZE_RESOURCES_INFORMATION, *PHEAP_OPTIMIZE_RESOURCES_INFORMATION;

Minimal test - lines (116, 131)

path: .spaces[0].spaces[3].metrics.nexits.average
old: 0.0
new: 1.0

path: .spaces[0].spaces[3].metrics.nexits.sum
old: 0.0
new: 1.0

path: .spaces[0].spaces[3].metrics.cyclomatic.sum
old: 7.0
new: 2.0

path: .spaces[0].spaces[3].metrics.cyclomatic.average
old: 7.0
new: 2.0

path: .spaces[0].spaces[3].metrics.halstead.n2
old: 13.0
new: 20.0

path: .spaces[0].spaces[3].metrics.halstead.time
old: 303.6752136752136
new: 141.75

path: .spaces[0].spaces[3].metrics.halstead.N2
old: 22.0
new: 27.0

path: .spaces[0].spaces[3].metrics.halstead.effort
old: 5466.153846153846
new: 2551.5

path: .spaces[0].spaces[3].metrics.halstead.length
old: 68.0
new: 63.0

path: .spaces[0].spaces[3].metrics.halstead.purity_ratio
old: 1.894357927812681
new: 2.05489066518097

path: .spaces[0].spaces[3].metrics.halstead.estimated_program_length
old: 128.8163390912623
new: 129.45811190640111

path: .spaces[0].spaces[3].metrics.halstead.N1
old: 46.0
new: 36.0

path: .spaces[0].spaces[3].metrics.halstead.volume
old: 340.0
new: 315.0

path: .spaces[0].spaces[3].metrics.halstead.n1
old: 19.0
new: 12.0

path: .spaces[0].spaces[3].metrics.halstead.bugs
old: 0.10343479209370732
new: 0.06224088994278901

path: .spaces[0].spaces[3].metrics.halstead.difficulty
old: 16.076923076923077
new: 8.1

path: .spaces[0].spaces[3].metrics.halstead.level
old: 0.06220095693779904
new: 0.1234567901234568

path: .spaces[0].spaces[3].metrics.cognitive.average
old: 11.0
new: 0.0

path: .spaces[0].spaces[3].metrics.cognitive.sum
old: 11.0
new: 0.0

path: .spaces[0].spaces[3].metrics.mi.mi_sei
old: 88.55099294884796
new: 81.4685300984352

path: .spaces[0].spaces[3].metrics.mi.mi_original
old: 83.44889007576754
new: 95.71068497782224

path: .spaces[0].spaces[3].metrics.mi.mi_visual_studio
old: 48.80052051214476
new: 55.97116080574401

path: .spaces[0].spaces[3].metrics.loc.sloc
old: 31.0
new: 16.0

path: .spaces[0].spaces[3].metrics.loc.lloc
old: 9.0
new: 5.0

path: .spaces[0].spaces[3].metrics.loc.blank
old: 0.0
new: 2.0

path: .spaces[0].spaces[3].metrics.loc.cloc
old: 14.0
new: 1.0

path: .spaces[0].spaces[3].metrics.loc.ploc
old: 17.0
new: 13.0

path: .spaces[0].spaces[3].metrics.nargs.average
old: 2.0
new: 0.0

path: .spaces[0].spaces[3].metrics.nargs.sum
old: 2.0
new: 0.0

Code

nsresult nsAvailableMemoryWatcher::Init() {
  mTimer = NS_NewTimer();

  nsCOMPtr observerService = services::GetObserverService();
  MOZ_ASSERT(observerService);

  for (auto topic : kObserverTopics) {
    nsresult rv = observerService->AddObserver(this, topic,
                                               /* ownsWeak */ false);
    NS_ENSURE_SUCCESS(rv, rv);
  }

  MOZ_TRY(mTimer->InitWithCallback(this, kPollingIntervalMS,
                                   nsITimer::TYPE_REPEATING_SLACK));
  return NS_OK;
}