Global Metrics

path: .metrics.cognitive.average
old: 1.1923076923076923
new: 1.6

path: .metrics.cognitive.sum
old: 31.0
new: 16.0

path: .metrics.nom.total
old: 26.0
new: 10.0

path: .metrics.nom.functions
old: 26.0
new: 10.0

path: .metrics.loc.lloc
old: 107.0
new: 74.0

path: .metrics.loc.cloc
old: 71.0
new: 32.0

path: .metrics.loc.ploc
old: 344.0
new: 167.0

path: .metrics.loc.sloc
old: 457.0
new: 215.0

path: .metrics.loc.blank
old: 42.0
new: 16.0

path: .metrics.cyclomatic.sum
old: 59.0
new: 35.0

path: .metrics.cyclomatic.average
old: 1.84375
new: 2.6923076923076925

path: .metrics.nargs.average
old: 1.0384615384615383
new: 1.3

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

path: .metrics.mi.mi_visual_studio
old: 5.709412707840934
new: 18.39400169014682

path: .metrics.mi.mi_original
old: 9.763095730407995
new: 31.453742890151062

path: .metrics.mi.mi_sei
old: -26.939207317230903
new: 1.3768931184327506

path: .metrics.halstead.estimated_program_length
old: 1581.5037569416077
new: 1054.027961158894

path: .metrics.halstead.length
old: 1427.0
new: 710.0

path: .metrics.halstead.n1
old: 39.0
new: 33.0

path: .metrics.halstead.purity_ratio
old: 1.1082717287607622
new: 1.4845464241674562

path: .metrics.halstead.effort
old: 669637.114231257
new: 201945.9834791341

path: .metrics.halstead.volume
old: 11122.6314412816
new: 5198.568947370028

path: .metrics.halstead.N1
old: 862.0
new: 411.0

path: .metrics.halstead.n2
old: 183.0
new: 127.0

path: .metrics.halstead.bugs
old: 2.551360080136571
new: 1.1473666576909172

path: .metrics.halstead.vocabulary
old: 222.0
new: 160.0

path: .metrics.halstead.level
old: 0.016609938733832538
new: 0.025742373568460524

path: .metrics.halstead.time
old: 37202.0619017365
new: 11219.221304396338

path: .metrics.halstead.N2
old: 565.0
new: 299.0

path: .metrics.halstead.difficulty
old: 60.204918032786885
new: 38.846456692913385

path: .metrics.nexits.sum
old: 11.0
new: 14.0

path: .metrics.nexits.average
old: 0.4230769230769231
new: 1.4

Spaces Data

Minimal test - lines (202, 212)

path: .spaces[0].spaces[0].spaces[9].metrics.halstead.length
old: 7.0
new: 39.0

path: .spaces[0].spaces[0].spaces[9].metrics.halstead.estimated_program_length
old: 13.60964047443681
new: 66.58307281799108

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

path: .spaces[0].spaces[0].spaces[9].metrics.halstead.vocabulary
old: 7.0
new: 20.0

path: .spaces[0].spaces[0].spaces[9].metrics.halstead.level
old: 0.4
new: 0.16296296296296295

path: .spaces[0].spaces[0].spaces[9].metrics.halstead.N2
old: 2.0
new: 15.0

path: .spaces[0].spaces[0].spaces[9].metrics.halstead.bugs
old: 0.004471319041702271
new: 0.034091614311752075

path: .spaces[0].spaces[0].spaces[9].metrics.halstead.n1
old: 5.0
new: 9.0

path: .spaces[0].spaces[0].spaces[9].metrics.halstead.purity_ratio
old: 1.944234353490973
new: 1.7072582773843867

path: .spaces[0].spaces[0].spaces[9].metrics.halstead.time
old: 2.7293728408893374
new: 57.46199853429789

path: .spaces[0].spaces[0].spaces[9].metrics.halstead.volume
old: 19.651484454403228
new: 168.55519570060713

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

path: .spaces[0].spaces[0].spaces[9].metrics.halstead.difficulty
old: 2.5
new: 6.136363636363637

path: .spaces[0].spaces[0].spaces[9].metrics.halstead.effort
old: 49.12871113600807
new: 1034.315973617362

path: .spaces[0].spaces[0].spaces[9].metrics.loc.lloc
old: 1.0
new: 6.0

path: .spaces[0].spaces[0].spaces[9].metrics.loc.ploc
old: 1.0
new: 11.0

path: .spaces[0].spaces[0].spaces[9].metrics.loc.sloc
old: 1.0
new: 11.0

path: .spaces[0].spaces[0].spaces[9].metrics.cognitive.average
old: 0.0
new: 3.0

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

path: .spaces[0].spaces[0].spaces[9].metrics.nexits.sum
old: 1.0
new: 2.0

path: .spaces[0].spaces[0].spaces[9].metrics.nexits.average
old: 1.0
new: 2.0

path: .spaces[0].spaces[0].spaces[9].metrics.mi.mi_sei
old: 148.4278547652622
new: 75.80240587661184

path: .spaces[0].spaces[0].spaces[9].metrics.mi.mi_visual_studio
old: 90.80912574437468
new: 61.2879108724385

path: .spaces[0].spaces[0].spaces[9].metrics.mi.mi_original
old: 155.2836050228807
new: 104.80232759186984

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

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

Code

nsresult ProbeManager::StopSession() {
  LOG(("Probes: Stopping measures"));
  if (mSessionHandle != 0) {
    ULONG result = UnregisterTraceGuids(mSessionHandle);
    mSessionHandle = 0;
    if (result != ERROR_SUCCESS) {
      return NS_ERROR_INVALID_ARG;
    }
  }
  return NS_OK;
}

Minimal test - lines (44, 85)

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

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

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

path: .spaces[0].spaces[0].spaces[2].metrics.loc.cloc
old: 0.0
new: 1.0

path: .spaces[0].spaces[0].spaces[2].metrics.loc.ploc
old: 10.0
new: 37.0

path: .spaces[0].spaces[0].spaces[2].metrics.loc.sloc
old: 11.0
new: 42.0

path: .spaces[0].spaces[0].spaces[2].metrics.loc.blank
old: 1.0
new: 4.0

path: .spaces[0].spaces[0].spaces[2].metrics.halstead.vocabulary
old: 25.0
new: 63.0

path: .spaces[0].spaces[0].spaces[2].metrics.halstead.purity_ratio
old: 2.0301492603070384
new: 1.9084790277548616

path: .spaces[0].spaces[0].spaces[2].metrics.halstead.difficulty
old: 7.071428571428571
new: 16.75

path: .spaces[0].spaces[0].spaces[2].metrics.halstead.estimated_program_length
old: 91.35671671381672
new: 318.7159976350619

path: .spaces[0].spaces[0].spaces[2].metrics.halstead.bugs
old: 0.04324584311615488
new: 0.21795591696503216

path: .spaces[0].spaces[0].spaces[2].metrics.halstead.N1
old: 27.0
new: 100.0

path: .spaces[0].spaces[0].spaces[2].metrics.halstead.N2
old: 18.0
new: 67.0

path: .spaces[0].spaces[0].spaces[2].metrics.halstead.time
old: 82.09674335494601
new: 928.88590366723

path: .spaces[0].spaces[0].spaces[2].metrics.halstead.effort
old: 1477.7413803890283
new: 16719.94626601014

path: .spaces[0].spaces[0].spaces[2].metrics.halstead.volume
old: 208.9735285398626
new: 998.205747224486

path: .spaces[0].spaces[0].spaces[2].metrics.halstead.n2
old: 14.0
new: 42.0

path: .spaces[0].spaces[0].spaces[2].metrics.halstead.length
old: 45.0
new: 167.0

path: .spaces[0].spaces[0].spaces[2].metrics.halstead.level
old: 0.1414141414141414
new: 0.05970149253731343

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

path: .spaces[0].spaces[0].spaces[2].metrics.mi.mi_original
old: 103.91461713222338
new: 72.23876322785262

path: .spaces[0].spaces[0].spaces[2].metrics.mi.mi_sei
old: 74.41989053933018
new: 41.37463165815646

path: .spaces[0].spaces[0].spaces[2].metrics.mi.mi_visual_studio
old: 60.768781948668654
new: 42.244890776522

path: .spaces[0].spaces[0].spaces[2].metrics.cyclomatic.sum
old: 2.0
new: 10.0

path: .spaces[0].spaces[0].spaces[2].metrics.cyclomatic.average
old: 2.0
new: 10.0

Code

nsresult Probe::Trigger() {
  if (!(mManager->mIsActive)) {
    // Do not trigger if there is no session
    return NS_OK;
  }

  _EVENT_TRACE_HEADER event;
  ZeroMemory(&event, sizeof(event));
  event.Size = sizeof(event);
  event.Flags = WNODE_FLAG_TRACED_GUID;
  event.Guid = (const GUID)mGUID;
  event.Class.Type = 1;
  event.Class.Version = 0;
  event.Class.Level = TRACE_LEVEL_INFORMATION;

  ULONG result = TraceEvent(mManager->mSessionHandle, &event);

  LOG(("Probes: Triggered %s, %s, %ld", mName.Data(),
       result == ERROR_SUCCESS ? "success" : "failure", result));

  nsresult rv;
  switch (result) {
    case ERROR_SUCCESS:
      rv = NS_OK;
      break;
    case ERROR_INVALID_FLAG_NUMBER:
    case ERROR_MORE_DATA:
    case ERROR_INVALID_PARAMETER:
      rv = NS_ERROR_INVALID_ARG;
      break;
    case ERROR_INVALID_HANDLE:
      rv = NS_ERROR_FAILURE;
      break;
    case ERROR_NOT_ENOUGH_MEMORY:
    case ERROR_OUTOFMEMORY:
      rv = NS_ERROR_OUT_OF_MEMORY;
      break;
    default:
      rv = NS_ERROR_UNEXPECTED;
  }
  return rv;
}

Minimal test - lines (16, 215)

path: .spaces[0].metrics.nom.functions
old: 26.0
new: 10.0

path: .spaces[0].metrics.nom.total
old: 26.0
new: 10.0

path: .spaces[0].metrics.halstead.purity_ratio
old: 1.0586762022660836
new: 1.4747563840618032

path: .spaces[0].metrics.halstead.n2
old: 174.0
new: 126.0

path: .spaces[0].metrics.halstead.level
old: 0.016048699501936912
new: 0.025625381330079317

path: .spaces[0].metrics.halstead.time
old: 37967.14092405133
new: 11240.665279194633

path: .spaces[0].metrics.halstead.bugs
old: 2.5862212641779414
new: 1.1488282131049885

path: .spaces[0].metrics.halstead.length
old: 1418.0
new: 709.0

path: .spaces[0].metrics.halstead.n1
old: 39.0
new: 33.0

path: .spaces[0].metrics.halstead.N1
old: 862.0
new: 411.0

path: .spaces[0].metrics.halstead.vocabulary
old: 213.0
new: 159.0

path: .spaces[0].metrics.halstead.N2
old: 556.0
new: 298.0

path: .spaces[0].metrics.halstead.difficulty
old: 62.310344827586206
new: 39.023809523809526

path: .spaces[0].metrics.halstead.effort
old: 683408.5366329239
new: 202331.97502550337

path: .spaces[0].metrics.halstead.volume
old: 10967.81824148024
new: 5184.834015296608

path: .spaces[0].metrics.halstead.estimated_program_length
old: 1501.2028548133064
new: 1045.6022762998184

path: .spaces[0].metrics.loc.ploc
old: 334.0
new: 163.0

path: .spaces[0].metrics.loc.blank
old: 40.0
new: 14.0

path: .spaces[0].metrics.loc.sloc
old: 433.0
new: 200.0

path: .spaces[0].metrics.loc.cloc
old: 59.0
new: 23.0

path: .spaces[0].metrics.loc.lloc
old: 107.0
new: 74.0

path: .spaces[0].metrics.nexits.average
old: 0.4230769230769231
new: 1.4

path: .spaces[0].metrics.nexits.sum
old: 11.0
new: 14.0

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

path: .spaces[0].metrics.nargs.average
old: 1.0384615384615383
new: 1.3

path: .spaces[0].metrics.cognitive.average
old: 1.1923076923076923
new: 1.6

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

path: .spaces[0].metrics.cyclomatic.average
old: 1.870967741935484
new: 2.8333333333333335

path: .spaces[0].metrics.cyclomatic.sum
old: 58.0
new: 34.0

path: .spaces[0].metrics.mi.mi_original
old: 10.939901429508636
new: 32.86909450202607

path: .spaces[0].metrics.mi.mi_visual_studio
old: 6.397603175151249
new: 19.22169269124332

path: .spaces[0].metrics.mi.mi_sei
old: -26.952619115918292
new: 0.25719846147574543

Code

namespace mozilla {
namespace probes {

#if defined(MOZ_LOGGING)
static LazyLogModule sProbeLog("SysProbe");
#  define LOG(x) MOZ_LOG(sProbeLog, mozilla::LogLevel::Debug, x)
#else
#  define LOG(x)
#endif

// Utility function
GUID CID_to_GUID(const nsCID& aCID) {
  GUID result;
  result.Data1 = aCID.m0;
  result.Data2 = aCID.m1;
  result.Data3 = aCID.m2;
  for (int i = 0; i < 8; ++i) {
    result.Data4[i] = aCID.m3[i];
  }
  return result;
}

// Implementation of Probe

Probe::Probe(const nsCID& aGUID, const nsACString& aName,
             ProbeManager* aManager)
    : mGUID(CID_to_GUID(aGUID)), mName(aName), mManager(aManager) {}

nsresult Probe::Trigger() {
  if (!(mManager->mIsActive)) {
    // Do not trigger if there is no session
    return NS_OK;
  }

  _EVENT_TRACE_HEADER event;
  ZeroMemory(&event, sizeof(event));
  event.Size = sizeof(event);
  event.Flags = WNODE_FLAG_TRACED_GUID;
  event.Guid = (const GUID)mGUID;
  event.Class.Type = 1;
  event.Class.Version = 0;
  event.Class.Level = TRACE_LEVEL_INFORMATION;

  ULONG result = TraceEvent(mManager->mSessionHandle, &event);

  LOG(("Probes: Triggered %s, %s, %ld", mName.Data(),
       result == ERROR_SUCCESS ? "success" : "failure", result));

  nsresult rv;
  switch (result) {
    case ERROR_SUCCESS:
      rv = NS_OK;
      break;
    case ERROR_INVALID_FLAG_NUMBER:
    case ERROR_MORE_DATA:
    case ERROR_INVALID_PARAMETER:
      rv = NS_ERROR_INVALID_ARG;
      break;
    case ERROR_INVALID_HANDLE:
      rv = NS_ERROR_FAILURE;
      break;
    case ERROR_NOT_ENOUGH_MEMORY:
    case ERROR_OUTOFMEMORY:
      rv = NS_ERROR_OUT_OF_MEMORY;
      break;
    default:
      rv = NS_ERROR_UNEXPECTED;
  }
  return rv;
}

// Implementation of ProbeManager

ProbeManager::~ProbeManager() {
  // If the manager goes out of scope, stop the session.
  if (mIsActive && mRegistrationHandle) {
    StopSession();
  }
}

ProbeManager::ProbeManager(const nsCID& aApplicationUID,
                           const nsACString& aApplicationName)
    : mIsActive(false),
      mApplicationUID(aApplicationUID),
      mApplicationName(aApplicationName),
      mSessionHandle(0),
      mRegistrationHandle(0),
      mInitialized(false) {
#if defined(MOZ_LOGGING)
  char cidStr[NSID_LENGTH];
  aApplicationUID.ToProvidedString(cidStr);
  LOG(("ProbeManager::Init for application %s, %s", aApplicationName.Data(),
       cidStr));
#endif
}

// Note: The Windows API is just a little bit scary there.
// The only way to obtain the session handle is to
//- ignore the session handle obtained from RegisterTraceGuids
//- pass a callback
//- in that callback, request the session handle through
//      GetTraceLoggerHandle and some opaque value received by the callback

ULONG WINAPI ControlCallback(WMIDPREQUESTCODE aRequestCode, PVOID aContext,
                             ULONG* aReserved, PVOID aBuffer) {
  ProbeManager* context = (ProbeManager*)aContext;
  switch (aRequestCode) {
    case WMI_ENABLE_EVENTS: {
      context->mIsActive = true;
      TRACEHANDLE sessionHandle = GetTraceLoggerHandle(aBuffer);
      // Note: We only accept one handle
      if ((HANDLE)sessionHandle == INVALID_HANDLE_VALUE) {
        ULONG result = GetLastError();
        LOG(("Probes: ControlCallback failed, %ul", result));
        return result;
      } else if (context->mIsActive && context->mSessionHandle &&
                 context->mSessionHandle != sessionHandle) {
        LOG(
            ("Probes: Can only handle one context at a time, "
             "ignoring activation"));
        return ERROR_SUCCESS;
      } else {
        context->mSessionHandle = sessionHandle;
        LOG(("Probes: ControlCallback activated"));
        return ERROR_SUCCESS;
      }
    }

    case WMI_DISABLE_EVENTS:
      context->mIsActive = false;
      context->mSessionHandle = 0;
      LOG(("Probes: ControlCallback deactivated"));
      return ERROR_SUCCESS;

    default:
      LOG(("Probes: ControlCallback does not know what to do with %d",
           aRequestCode));
      return ERROR_INVALID_PARAMETER;
  }
}

already_AddRefed ProbeManager::GetProbe(const nsCID& aEventUID,
                                               const nsACString& aEventName) {
  RefPtr result(new Probe(aEventUID, aEventName, this));
  mAllProbes.AppendElement(result);
  return result.forget();
}

nsresult ProbeManager::StartSession() { return StartSession(mAllProbes); }

nsresult ProbeManager::StartSession(nsTArray>& aProbes) {
  const size_t probesCount = aProbes.Length();
  _TRACE_GUID_REGISTRATION* probes = new _TRACE_GUID_REGISTRATION[probesCount];
  for (unsigned int i = 0; i < probesCount; ++i) {
    const Probe* probe = aProbes[i];
    const Probe* probeX = static_cast(probe);
    probes[i].Guid = (LPCGUID)&probeX->mGUID;
  }
  ULONG result =
      RegisterTraceGuids(&ControlCallback
                         /*RequestAddress: Sets mSessions appropriately.*/,
                         this
                         /*RequestContext: Passed to ControlCallback*/,
                         (LPGUID)&mApplicationUID
                         /*ControlGuid:    Tracing GUID
                          the cast comes from MSDN examples*/
                         ,
                         probesCount
                         /*GuidCount:      Number of probes*/,
                         probes
                         /*TraceGuidReg:   Probes registration*/,
                         nullptr
                         /*MofImagePath:   Must be nullptr, says MSDN*/,
                         nullptr
                         /*MofResourceName:Must be nullptr, says MSDN*/,
                         &mRegistrationHandle
                         /*RegistrationHandle: Handler.
                          used only for unregistration*/
      );
  delete[] probes;
  if (NS_WARN_IF(result != ERROR_SUCCESS)) {
    return NS_ERROR_UNEXPECTED;
  }
  return NS_OK;
}

nsresult ProbeManager::StopSession() {
  LOG(("Probes: Stopping measures"));
  if (mSessionHandle != 0) {
    ULONG result = UnregisterTraceGuids(mSessionHandle);
    mSessionHandle = 0;
    if (result != ERROR_SUCCESS) {
      return NS_ERROR_INVALID_ARG;
    }
  }
  return NS_OK;
}

}  // namespace probes
}  // namespace mozilla

Minimal test - lines (40, 42)

path: .spaces[0].spaces[0].spaces[1].metrics.halstead.N1
old: 16.0
new: 15.0

path: .spaces[0].spaces[0].spaces[1].metrics.halstead.estimated_program_length
old: 52.529325012980806
new: 57.70523225941349

path: .spaces[0].spaces[0].spaces[1].metrics.halstead.n1
old: 9.0
new: 7.0

path: .spaces[0].spaces[0].spaces[1].metrics.halstead.level
old: 0.2222222222222222
new: 0.22448979591836735

path: .spaces[0].spaces[0].spaces[1].metrics.halstead.time
old: 24.524777047502035
new: 29.926582964896593

path: .spaces[0].spaces[0].spaces[1].metrics.halstead.volume
old: 98.09910819000814
new: 120.92782504182703

path: .spaces[0].spaces[0].spaces[1].metrics.halstead.effort
old: 441.4459868550366
new: 538.6784933681387

path: .spaces[0].spaces[0].spaces[1].metrics.halstead.bugs
old: 0.01932548761156621
new: 0.02206811151083656

path: .spaces[0].spaces[0].spaces[1].metrics.halstead.difficulty
old: 4.5
new: 4.454545454545454

path: .spaces[0].spaces[0].spaces[1].metrics.halstead.vocabulary
old: 17.0
new: 18.0

path: .spaces[0].spaces[0].spaces[1].metrics.halstead.N2
old: 8.0
new: 14.0

path: .spaces[0].spaces[0].spaces[1].metrics.halstead.length
old: 24.0
new: 29.0

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

path: .spaces[0].spaces[0].spaces[1].metrics.halstead.purity_ratio
old: 2.188721875540867
new: 1.989835595152189

path: .spaces[0].spaces[0].spaces[1].metrics.nargs.sum
old: 0.0
new: 3.0

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

path: .spaces[0].spaces[0].spaces[1].metrics.mi.mi_sei
old: 127.7184436416934
new: 109.11999484550196

path: .spaces[0].spaces[0].spaces[1].metrics.mi.mi_original
old: 115.39916855164113
new: 128.0374727456536

path: .spaces[0].spaces[0].spaces[1].metrics.mi.mi_visual_studio
old: 67.48489388984859
new: 74.87571505593777

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

path: .spaces[0].spaces[0].spaces[1].metrics.loc.ploc
old: 5.0
new: 3.0

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

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

Code

Probe::Probe(const nsCID& aGUID, const nsACString& aName,
             ProbeManager* aManager)
    : mGUID(CID_to_GUID(aGUID)), mName(aName), mManager(aManager) {}

Minimal test - lines (27, 36)

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

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

path: .spaces[0].spaces[0].spaces[0].metrics.mi.mi_visual_studio
old: 51.11882105894462
new: 60.54330784158337

path: .spaces[0].spaces[0].spaces[0].metrics.mi.mi_sei
old: 73.02644849512455
new: 73.86364399612941

path: .spaces[0].spaces[0].spaces[0].metrics.mi.mi_original
old: 87.4131840107953
new: 103.52905640910755

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

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

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

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

path: .spaces[0].spaces[0].spaces[0].metrics.halstead.N2
old: 47.0
new: 30.0

path: .spaces[0].spaces[0].spaces[0].metrics.halstead.level
old: 0.10801963993453356
new: 0.08888888888888889

path: .spaces[0].spaces[0].spaces[0].metrics.halstead.effort
old: 5573.692465324863
new: 3407.212801008327

path: .spaces[0].spaces[0].spaces[0].metrics.halstead.difficulty
old: 9.257575757575758
new: 11.25

path: .spaces[0].spaces[0].spaces[0].metrics.halstead.purity_ratio
old: 1.9685387364647997
new: 1.698723016010379

path: .spaces[0].spaces[0].spaces[0].metrics.halstead.time
old: 309.6495814069369
new: 189.28960005601817

path: .spaces[0].spaces[0].spaces[0].metrics.halstead.N1
old: 62.0
new: 33.0

path: .spaces[0].spaces[0].spaces[0].metrics.halstead.volume
old: 602.0682532102144
new: 302.86336008962905

path: .spaces[0].spaces[0].spaces[0].metrics.halstead.estimated_program_length
old: 214.57072227466315
new: 107.01955000865388

path: .spaces[0].spaces[0].spaces[0].metrics.halstead.n2
old: 33.0
new: 16.0

path: .spaces[0].spaces[0].spaces[0].metrics.halstead.bugs
old: 0.10478700159723674
new: 0.07547647073309965

path: .spaces[0].spaces[0].spaces[0].metrics.halstead.vocabulary
old: 46.0
new: 28.0

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

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

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

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

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

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

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

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

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

Code

GUID CID_to_GUID(const nsCID& aCID) {
  GUID result;
  result.Data1 = aCID.m0;
  result.Data2 = aCID.m1;
  result.Data3 = aCID.m2;
  for (int i = 0; i < 8; ++i) {
    result.Data4[i] = aCID.m3[i];
  }
  return result;
}

Minimal test - lines (119, 155)

path: .spaces[0].spaces[0].spaces[5].metrics.halstead.difficulty
old: 15.75
new: 17.129032258064516

path: .spaces[0].spaces[0].spaces[5].metrics.halstead.bugs
old: 0.18070713742275837
new: 0.19577624099335264

path: .spaces[0].spaces[0].spaces[5].metrics.halstead.effort
old: 12622.48436843117
new: 14233.832813849223

path: .spaces[0].spaces[0].spaces[5].metrics.halstead.purity_ratio
old: 1.6553426058166312
new: 1.5448563219456402

path: .spaces[0].spaces[0].spaces[5].metrics.halstead.n2
old: 32.0
new: 31.0

path: .spaces[0].spaces[0].spaces[5].metrics.halstead.vocabulary
old: 50.0
new: 49.0

path: .spaces[0].spaces[0].spaces[5].metrics.halstead.volume
old: 801.4275789480108
new: 830.9770569290508

path: .spaces[0].spaces[0].spaces[5].metrics.halstead.estimated_program_length
old: 235.0586500259616
new: 228.63873564795475

path: .spaces[0].spaces[0].spaces[5].metrics.halstead.length
old: 142.0
new: 148.0

path: .spaces[0].spaces[0].spaces[5].metrics.halstead.time
old: 701.2491315795095
new: 790.7684896582903

path: .spaces[0].spaces[0].spaces[5].metrics.halstead.N2
old: 56.0
new: 59.0

path: .spaces[0].spaces[0].spaces[5].metrics.halstead.N1
old: 86.0
new: 89.0

path: .spaces[0].spaces[0].spaces[5].metrics.halstead.level
old: 0.06349206349206349
new: 0.0583804143126177

path: .spaces[0].spaces[0].spaces[5].metrics.cyclomatic.sum
old: 5.0
new: 7.0

path: .spaces[0].spaces[0].spaces[5].metrics.cyclomatic.average
old: 5.0
new: 7.0

path: .spaces[0].spaces[0].spaces[5].metrics.cognitive.average
old: 7.0
new: 6.0

path: .spaces[0].spaces[0].spaces[5].metrics.cognitive.sum
old: 7.0
new: 6.0

path: .spaces[0].spaces[0].spaces[5].metrics.loc.lloc
old: 12.0
new: 20.0

path: .spaces[0].spaces[0].spaces[5].metrics.loc.ploc
old: 29.0
new: 34.0

path: .spaces[0].spaces[0].spaces[5].metrics.loc.sloc
old: 36.0
new: 37.0

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

path: .spaces[0].spaces[0].spaces[5].metrics.loc.cloc
old: 6.0
new: 1.0

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

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

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

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

path: .spaces[0].spaces[0].spaces[5].metrics.mi.mi_sei
old: 65.49214343393857
new: 47.16086692809952

path: .spaces[0].spaces[0].spaces[5].metrics.mi.mi_visual_studio
old: 45.04546270142684
new: 44.406782719676464

path: .spaces[0].spaces[0].spaces[5].metrics.mi.mi_original
old: 77.0277412194399
new: 75.93559845064675

Code

ULONG WINAPI ControlCallback(WMIDPREQUESTCODE aRequestCode, PVOID aContext,
                             ULONG* aReserved, PVOID aBuffer) {
  ProbeManager* context = (ProbeManager*)aContext;
  switch (aRequestCode) {
    case WMI_ENABLE_EVENTS: {
      context->mIsActive = true;
      TRACEHANDLE sessionHandle = GetTraceLoggerHandle(aBuffer);
      // Note: We only accept one handle
      if ((HANDLE)sessionHandle == INVALID_HANDLE_VALUE) {
        ULONG result = GetLastError();
        LOG(("Probes: ControlCallback failed, %ul", result));
        return result;
      } else if (context->mIsActive && context->mSessionHandle &&
                 context->mSessionHandle != sessionHandle) {
        LOG(
            ("Probes: Can only handle one context at a time, "
             "ignoring activation"));
        return ERROR_SUCCESS;
      } else {
        context->mSessionHandle = sessionHandle;
        LOG(("Probes: ControlCallback activated"));
        return ERROR_SUCCESS;
      }
    }

    case WMI_DISABLE_EVENTS:
      context->mIsActive = false;
      context->mSessionHandle = 0;
      LOG(("Probes: ControlCallback deactivated"));
      return ERROR_SUCCESS;

    default:
      LOG(("Probes: ControlCallback does not know what to do with %d",
           aRequestCode));
      return ERROR_INVALID_PARAMETER;
  }
}

Minimal test - lines (166, 200)

path: .spaces[0].spaces[0].spaces[8].metrics.mi.mi_sei
old: 115.71718014704972
new: 75.08645149176682

path: .spaces[0].spaces[0].spaces[8].metrics.mi.mi_visual_studio
old: 77.54987902751634
new: 46.068011279955485

path: .spaces[0].spaces[0].spaces[8].metrics.mi.mi_original
old: 132.6102931370529
new: 78.77629928872388

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

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

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

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

path: .spaces[0].spaces[0].spaces[8].metrics.loc.sloc
old: 3.0
new: 35.0

path: .spaces[0].spaces[0].spaces[8].metrics.loc.cloc
old: 0.0
new: 10.0

path: .spaces[0].spaces[0].spaces[8].metrics.loc.ploc
old: 3.0
new: 31.0

path: .spaces[0].spaces[0].spaces[8].metrics.loc.lloc
old: 1.0
new: 6.0

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

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

path: .spaces[0].spaces[0].spaces[8].metrics.halstead.bugs
old: 0.01180646926336541
new: 0.1758373806329406

path: .spaces[0].spaces[0].spaces[8].metrics.halstead.level
old: 0.23809523809523808
new: 0.05636540330417881

path: .spaces[0].spaces[0].spaces[8].metrics.halstead.volume
old: 50.18947501009619
new: 682.9065989627417

path: .spaces[0].spaces[0].spaces[8].metrics.halstead.N2
old: 6.0
new: 49.0

path: .spaces[0].spaces[0].spaces[8].metrics.halstead.purity_ratio
old: 2.2329374949171457
new: 1.9266125184880456

path: .spaces[0].spaces[0].spaces[8].metrics.halstead.N1
old: 8.0
new: 72.0

path: .spaces[0].spaces[0].spaces[8].metrics.halstead.vocabulary
old: 12.0
new: 50.0

path: .spaces[0].spaces[0].spaces[8].metrics.halstead.n2
old: 5.0
new: 29.0

path: .spaces[0].spaces[0].spaces[8].metrics.halstead.difficulty
old: 4.2
new: 17.74137931034483

path: .spaces[0].spaces[0].spaces[8].metrics.halstead.effort
old: 210.795795042404
new: 12115.70500573554

path: .spaces[0].spaces[0].spaces[8].metrics.halstead.time
old: 11.710877502355778
new: 673.0947225408632

path: .spaces[0].spaces[0].spaces[8].metrics.halstead.n1
old: 7.0
new: 21.0

path: .spaces[0].spaces[0].spaces[8].metrics.halstead.length
old: 14.0
new: 121.0

path: .spaces[0].spaces[0].spaces[8].metrics.halstead.estimated_program_length
old: 31.26112492884004
new: 233.1201147370535

Code

nsresult ProbeManager::StartSession(nsTArray>& aProbes) {
  const size_t probesCount = aProbes.Length();
  _TRACE_GUID_REGISTRATION* probes = new _TRACE_GUID_REGISTRATION[probesCount];
  for (unsigned int i = 0; i < probesCount; ++i) {
    const Probe* probe = aProbes[i];
    const Probe* probeX = static_cast(probe);
    probes[i].Guid = (LPCGUID)&probeX->mGUID;
  }
  ULONG result =
      RegisterTraceGuids(&ControlCallback
                         /*RequestAddress: Sets mSessions appropriately.*/,
                         this
                         /*RequestContext: Passed to ControlCallback*/,
                         (LPGUID)&mApplicationUID
                         /*ControlGuid:    Tracing GUID
                          the cast comes from MSDN examples*/
                         ,
                         probesCount
                         /*GuidCount:      Number of probes*/,
                         probes
                         /*TraceGuidReg:   Probes registration*/,
                         nullptr
                         /*MofImagePath:   Must be nullptr, says MSDN*/,
                         nullptr
                         /*MofResourceName:Must be nullptr, says MSDN*/,
                         &mRegistrationHandle
                         /*RegistrationHandle: Handler.
                          used only for unregistration*/
      );
  delete[] probes;
  if (NS_WARN_IF(result != ERROR_SUCCESS)) {
    return NS_ERROR_UNEXPECTED;
  }
  return NS_OK;
}

Minimal test - lines (96, 110)

path: .spaces[0].spaces[0].spaces[4].metrics.nargs.average
old: 1.0
new: 2.0

path: .spaces[0].spaces[0].spaces[4].metrics.nargs.sum
old: 1.0
new: 2.0

path: .spaces[0].spaces[0].spaces[4].metrics.mi.mi_original
old: 117.80119628756816
new: 97.3376646199166

path: .spaces[0].spaces[0].spaces[4].metrics.mi.mi_sei
old: 94.35216956225368
new: 64.82953390625852

path: .spaces[0].spaces[0].spaces[4].metrics.mi.mi_visual_studio
old: 68.88958847226209
new: 56.922610888840126

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

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

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

path: .spaces[0].spaces[0].spaces[4].metrics.loc.ploc
old: 6.0
new: 15.0

path: .spaces[0].spaces[0].spaces[4].metrics.loc.sloc
old: 6.0
new: 15.0

path: .spaces[0].spaces[0].spaces[4].metrics.halstead.purity_ratio
old: 1.3188755731272892
new: 1.9942973807770144

path: .spaces[0].spaces[0].spaces[4].metrics.halstead.N2
old: 11.0
new: 28.0

path: .spaces[0].spaces[0].spaces[4].metrics.halstead.N1
old: 16.0
new: 32.0

path: .spaces[0].spaces[0].spaces[4].metrics.halstead.difficulty
old: 8.8
new: 7.0

path: .spaces[0].spaces[0].spaces[4].metrics.halstead.effort
old: 879.2244770303236
new: 2060.894050155578

path: .spaces[0].spaces[0].spaces[4].metrics.halstead.vocabulary
old: 13.0
new: 30.0

path: .spaces[0].spaces[0].spaces[4].metrics.halstead.volume
old: 99.91187238980947
new: 294.41343573651113

path: .spaces[0].spaces[0].spaces[4].metrics.halstead.level
old: 0.11363636363636365
new: 0.14285714285714285

path: .spaces[0].spaces[0].spaces[4].metrics.halstead.length
old: 27.0
new: 60.0

path: .spaces[0].spaces[0].spaces[4].metrics.halstead.n2
old: 5.0
new: 20.0

path: .spaces[0].spaces[0].spaces[4].metrics.halstead.time
old: 48.84580427946242
new: 114.49411389753212

path: .spaces[0].spaces[0].spaces[4].metrics.halstead.bugs
old: 0.030592285618699915
new: 0.053982027101270445

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

path: .spaces[0].spaces[0].spaces[4].metrics.halstead.estimated_program_length
old: 35.60964047443681
new: 119.65784284662088

Code

ProbeManager::ProbeManager(const nsCID& aApplicationUID,
                           const nsACString& aApplicationName)
    : mIsActive(false),
      mApplicationUID(aApplicationUID),
      mApplicationName(aApplicationName),
      mSessionHandle(0),
      mRegistrationHandle(0),
      mInitialized(false) {
#if defined(MOZ_LOGGING)
  char cidStr[NSID_LENGTH];
  aApplicationUID.ToProvidedString(cidStr);
  LOG(("ProbeManager::Init for application %s, %s", aApplicationName.Data(),
       cidStr));
#endif
}

Minimal test - lines (89, 94)

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

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

path: .spaces[0].spaces[0].spaces[3].metrics.halstead.estimated_program_length
old: 13.60964047443681
new: 27.651484454403228

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

path: .spaces[0].spaces[0].spaces[3].metrics.halstead.N2
old: 2.0
new: 4.0

path: .spaces[0].spaces[0].spaces[3].metrics.halstead.difficulty
old: 2.5
new: 3.5

path: .spaces[0].spaces[0].spaces[3].metrics.halstead.vocabulary
old: 7.0
new: 11.0

path: .spaces[0].spaces[0].spaces[3].metrics.halstead.volume
old: 19.651484454403228
new: 48.43204266092216

path: .spaces[0].spaces[0].spaces[3].metrics.halstead.n2
old: 2.0
new: 4.0

path: .spaces[0].spaces[0].spaces[3].metrics.halstead.bugs
old: 0.004471319041702271
new: 0.01020969180116028

path: .spaces[0].spaces[0].spaces[3].metrics.halstead.level
old: 0.4
new: 0.2857142857142857

path: .spaces[0].spaces[0].spaces[3].metrics.halstead.time
old: 2.7293728408893374
new: 9.417341628512643

path: .spaces[0].spaces[0].spaces[3].metrics.halstead.purity_ratio
old: 1.944234353490973
new: 1.9751060324573737

path: .spaces[0].spaces[0].spaces[3].metrics.halstead.effort
old: 49.12871113600807
new: 169.51214931322758

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

path: .spaces[0].spaces[0].spaces[3].metrics.halstead.length
old: 7.0
new: 14.0

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

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

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

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

path: .spaces[0].spaces[0].spaces[3].metrics.mi.mi_sei
old: 148.4278547652622
new: 128.88093563013814

path: .spaces[0].spaces[0].spaces[3].metrics.mi.mi_original
old: 155.2836050228807
new: 121.10665610627834

path: .spaces[0].spaces[0].spaces[3].metrics.mi.mi_visual_studio
old: 90.80912574437468
new: 70.82260591010429

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

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

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

path: .spaces[0].spaces[0].spaces[3].metrics.loc.ploc
old: 1.0
new: 5.0

Code

ProbeManager::~ProbeManager() {
  // If the manager goes out of scope, stop the session.
  if (mIsActive && mRegistrationHandle) {
    StopSession();
  }
}

Minimal test - lines (164, 164)

path: .spaces[0].spaces[0].spaces[7].metrics.mi.mi_sei
old: 143.77444718573403
new: 145.25416890283572

path: .spaces[0].spaces[0].spaces[7].metrics.mi.mi_original
old: 152.05810867913445
new: 153.0837736153568

path: .spaces[0].spaces[0].spaces[7].metrics.mi.mi_visual_studio
old: 88.92287057259325
new: 89.52267462886361

path: .spaces[0].spaces[0].spaces[7].metrics.halstead.purity_ratio
old: 2.1372522731206307
new: 1.6364527976600278

path: .spaces[0].spaces[0].spaces[7].metrics.halstead.n1
old: 6.0
new: 5.0

path: .spaces[0].spaces[0].spaces[7].metrics.halstead.N1
old: 7.0
new: 6.0

path: .spaces[0].spaces[0].spaces[7].metrics.halstead.time
old: 6.090201507293497
new: 5.555555555555555

path: .spaces[0].spaces[0].spaces[7].metrics.halstead.difficulty
old: 3.0
new: 3.3333333333333335

path: .spaces[0].spaces[0].spaces[7].metrics.halstead.level
old: 0.3333333333333333
new: 0.3

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

path: .spaces[0].spaces[0].spaces[7].metrics.halstead.length
old: 11.0
new: 10.0

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

path: .spaces[0].spaces[0].spaces[7].metrics.halstead.estimated_program_length
old: 23.509775004326936
new: 16.36452797660028

path: .spaces[0].spaces[0].spaces[7].metrics.halstead.effort
old: 109.62362713128296
new: 100.0

path: .spaces[0].spaces[0].spaces[7].metrics.halstead.volume
old: 36.541209043760986
new: 30.0

path: .spaces[0].spaces[0].spaces[7].metrics.halstead.bugs
old: 0.007635102239890672
new: 0.007181448966772944

Code

nsresult ProbeManager::StartSession() { return StartSession(mAllProbes); }

Minimal test - lines (17, 214)

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

path: .spaces[0].spaces[0].metrics.cyclomatic.sum
old: 16.0
new: 33.0

path: .spaces[0].spaces[0].metrics.nexits.sum
old: 6.0
new: 14.0

path: .spaces[0].spaces[0].metrics.nexits.average
old: 0.6
new: 1.4

path: .spaces[0].spaces[0].metrics.halstead.purity_ratio
old: 1.3080547761875445
new: 1.4670269328452474

path: .spaces[0].spaces[0].metrics.halstead.estimated_program_length
old: 667.1079358556477
new: 1037.18804152159

path: .spaces[0].spaces[0].metrics.halstead.n2
old: 81.0
new: 125.0

path: .spaces[0].spaces[0].metrics.halstead.N1
old: 308.0
new: 410.0

path: .spaces[0].spaces[0].metrics.halstead.volume
old: 3471.751010249378
new: 5163.772988961212

path: .spaces[0].spaces[0].metrics.halstead.difficulty
old: 38.65432098765432
new: 39.204

path: .spaces[0].spaces[0].metrics.halstead.time
old: 7455.454329966257
new: 11246.69756995752

path: .spaces[0].spaces[0].metrics.halstead.effort
old: 134198.17793939263
new: 202440.55625923537

path: .spaces[0].spaces[0].metrics.halstead.length
old: 510.0
new: 707.0

path: .spaces[0].spaces[0].metrics.halstead.vocabulary
old: 112.0
new: 158.0

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

path: .spaces[0].spaces[0].metrics.halstead.bugs
old: 0.8737284785796605
new: 1.1492391879573578

path: .spaces[0].spaces[0].metrics.halstead.level
old: 0.025870328968380707
new: 0.025507601265177024

path: .spaces[0].spaces[0].metrics.halstead.N2
old: 202.0
new: 297.0

path: .spaces[0].spaces[0].metrics.mi.mi_sei
old: 18.578428896423983
new: 0.36407370958596985

path: .spaces[0].spaces[0].metrics.mi.mi_original
old: 45.58244057102684
new: 33.28307559115717

path: .spaces[0].spaces[0].metrics.mi.mi_visual_studio
old: 26.656397994752535
new: 19.463786895413552

path: .spaces[0].spaces[0].metrics.loc.sloc
old: 134.0
new: 198.0

path: .spaces[0].spaces[0].metrics.loc.lloc
old: 31.0
new: 74.0

path: .spaces[0].spaces[0].metrics.loc.ploc
old: 102.0
new: 161.0

path: .spaces[0].spaces[0].metrics.loc.cloc
old: 18.0
new: 22.0

path: .spaces[0].spaces[0].metrics.loc.blank
old: 14.0
new: 15.0

path: .spaces[0].spaces[0].metrics.cognitive.average
old: 0.8
new: 1.6

path: .spaces[0].spaces[0].metrics.cognitive.sum
old: 8.0
new: 16.0

path: .spaces[0].spaces[0].metrics.nargs.average
old: 0.9
new: 1.3

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

Code

namespace probes {

#if defined(MOZ_LOGGING)
static LazyLogModule sProbeLog("SysProbe");
#  define LOG(x) MOZ_LOG(sProbeLog, mozilla::LogLevel::Debug, x)
#else
#  define LOG(x)
#endif

// Utility function
GUID CID_to_GUID(const nsCID& aCID) {
  GUID result;
  result.Data1 = aCID.m0;
  result.Data2 = aCID.m1;
  result.Data3 = aCID.m2;
  for (int i = 0; i < 8; ++i) {
    result.Data4[i] = aCID.m3[i];
  }
  return result;
}

// Implementation of Probe

Probe::Probe(const nsCID& aGUID, const nsACString& aName,
             ProbeManager* aManager)
    : mGUID(CID_to_GUID(aGUID)), mName(aName), mManager(aManager) {}

nsresult Probe::Trigger() {
  if (!(mManager->mIsActive)) {
    // Do not trigger if there is no session
    return NS_OK;
  }

  _EVENT_TRACE_HEADER event;
  ZeroMemory(&event, sizeof(event));
  event.Size = sizeof(event);
  event.Flags = WNODE_FLAG_TRACED_GUID;
  event.Guid = (const GUID)mGUID;
  event.Class.Type = 1;
  event.Class.Version = 0;
  event.Class.Level = TRACE_LEVEL_INFORMATION;

  ULONG result = TraceEvent(mManager->mSessionHandle, &event);

  LOG(("Probes: Triggered %s, %s, %ld", mName.Data(),
       result == ERROR_SUCCESS ? "success" : "failure", result));

  nsresult rv;
  switch (result) {
    case ERROR_SUCCESS:
      rv = NS_OK;
      break;
    case ERROR_INVALID_FLAG_NUMBER:
    case ERROR_MORE_DATA:
    case ERROR_INVALID_PARAMETER:
      rv = NS_ERROR_INVALID_ARG;
      break;
    case ERROR_INVALID_HANDLE:
      rv = NS_ERROR_FAILURE;
      break;
    case ERROR_NOT_ENOUGH_MEMORY:
    case ERROR_OUTOFMEMORY:
      rv = NS_ERROR_OUT_OF_MEMORY;
      break;
    default:
      rv = NS_ERROR_UNEXPECTED;
  }
  return rv;
}

// Implementation of ProbeManager

ProbeManager::~ProbeManager() {
  // If the manager goes out of scope, stop the session.
  if (mIsActive && mRegistrationHandle) {
    StopSession();
  }
}

ProbeManager::ProbeManager(const nsCID& aApplicationUID,
                           const nsACString& aApplicationName)
    : mIsActive(false),
      mApplicationUID(aApplicationUID),
      mApplicationName(aApplicationName),
      mSessionHandle(0),
      mRegistrationHandle(0),
      mInitialized(false) {
#if defined(MOZ_LOGGING)
  char cidStr[NSID_LENGTH];
  aApplicationUID.ToProvidedString(cidStr);
  LOG(("ProbeManager::Init for application %s, %s", aApplicationName.Data(),
       cidStr));
#endif
}

// Note: The Windows API is just a little bit scary there.
// The only way to obtain the session handle is to
//- ignore the session handle obtained from RegisterTraceGuids
//- pass a callback
//- in that callback, request the session handle through
//      GetTraceLoggerHandle and some opaque value received by the callback

ULONG WINAPI ControlCallback(WMIDPREQUESTCODE aRequestCode, PVOID aContext,
                             ULONG* aReserved, PVOID aBuffer) {
  ProbeManager* context = (ProbeManager*)aContext;
  switch (aRequestCode) {
    case WMI_ENABLE_EVENTS: {
      context->mIsActive = true;
      TRACEHANDLE sessionHandle = GetTraceLoggerHandle(aBuffer);
      // Note: We only accept one handle
      if ((HANDLE)sessionHandle == INVALID_HANDLE_VALUE) {
        ULONG result = GetLastError();
        LOG(("Probes: ControlCallback failed, %ul", result));
        return result;
      } else if (context->mIsActive && context->mSessionHandle &&
                 context->mSessionHandle != sessionHandle) {
        LOG(
            ("Probes: Can only handle one context at a time, "
             "ignoring activation"));
        return ERROR_SUCCESS;
      } else {
        context->mSessionHandle = sessionHandle;
        LOG(("Probes: ControlCallback activated"));
        return ERROR_SUCCESS;
      }
    }

    case WMI_DISABLE_EVENTS:
      context->mIsActive = false;
      context->mSessionHandle = 0;
      LOG(("Probes: ControlCallback deactivated"));
      return ERROR_SUCCESS;

    default:
      LOG(("Probes: ControlCallback does not know what to do with %d",
           aRequestCode));
      return ERROR_INVALID_PARAMETER;
  }
}

already_AddRefed ProbeManager::GetProbe(const nsCID& aEventUID,
                                               const nsACString& aEventName) {
  RefPtr result(new Probe(aEventUID, aEventName, this));
  mAllProbes.AppendElement(result);
  return result.forget();
}

nsresult ProbeManager::StartSession() { return StartSession(mAllProbes); }

nsresult ProbeManager::StartSession(nsTArray>& aProbes) {
  const size_t probesCount = aProbes.Length();
  _TRACE_GUID_REGISTRATION* probes = new _TRACE_GUID_REGISTRATION[probesCount];
  for (unsigned int i = 0; i < probesCount; ++i) {
    const Probe* probe = aProbes[i];
    const Probe* probeX = static_cast(probe);
    probes[i].Guid = (LPCGUID)&probeX->mGUID;
  }
  ULONG result =
      RegisterTraceGuids(&ControlCallback
                         /*RequestAddress: Sets mSessions appropriately.*/,
                         this
                         /*RequestContext: Passed to ControlCallback*/,
                         (LPGUID)&mApplicationUID
                         /*ControlGuid:    Tracing GUID
                          the cast comes from MSDN examples*/
                         ,
                         probesCount
                         /*GuidCount:      Number of probes*/,
                         probes
                         /*TraceGuidReg:   Probes registration*/,
                         nullptr
                         /*MofImagePath:   Must be nullptr, says MSDN*/,
                         nullptr
                         /*MofResourceName:Must be nullptr, says MSDN*/,
                         &mRegistrationHandle
                         /*RegistrationHandle: Handler.
                          used only for unregistration*/
      );
  delete[] probes;
  if (NS_WARN_IF(result != ERROR_SUCCESS)) {
    return NS_ERROR_UNEXPECTED;
  }
  return NS_OK;
}

nsresult ProbeManager::StopSession() {
  LOG(("Probes: Stopping measures"));
  if (mSessionHandle != 0) {
    ULONG result = UnregisterTraceGuids(mSessionHandle);
    mSessionHandle = 0;
    if (result != ERROR_SUCCESS) {
      return NS_ERROR_INVALID_ARG;
    }
  }
  return NS_OK;
}

}  // namespace probes

Minimal test - lines (157, 162)

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

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

path: .spaces[0].spaces[0].spaces[6].metrics.loc.ploc
old: 9.0
new: 6.0

path: .spaces[0].spaces[0].spaces[6].metrics.loc.sloc
old: 9.0
new: 6.0

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

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

path: .spaces[0].spaces[0].spaces[6].metrics.halstead.effort
old: 1790.286635685641
new: 1530.0948316362849

path: .spaces[0].spaces[0].spaces[6].metrics.halstead.level
old: 0.1238095238095238
new: 0.12121212121212122

path: .spaces[0].spaces[0].spaces[6].metrics.halstead.N2
old: 21.0
new: 18.0

path: .spaces[0].spaces[0].spaces[6].metrics.halstead.length
old: 49.0
new: 41.0

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

path: .spaces[0].spaces[0].spaces[6].metrics.halstead.volume
old: 221.65453584679364
new: 185.4660401983375

path: .spaces[0].spaces[0].spaces[6].metrics.halstead.difficulty
old: 8.076923076923077
new: 8.25

path: .spaces[0].spaces[0].spaces[6].metrics.halstead.bugs
old: 0.049146635463153114
new: 0.04426131480681766

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

path: .spaces[0].spaces[0].spaces[6].metrics.halstead.purity_ratio
old: 1.6596938221368942
new: 1.977397507650345

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

path: .spaces[0].spaces[0].spaces[6].metrics.halstead.time
old: 99.46036864920228
new: 85.00526842423804

path: .spaces[0].spaces[0].spaces[6].metrics.halstead.estimated_program_length
old: 81.32499728470782
new: 81.07329781366414

path: .spaces[0].spaces[0].spaces[6].metrics.mi.mi_sei
old: 78.89793578510101
new: 89.71154906216879

path: .spaces[0].spaces[0].spaces[6].metrics.mi.mi_visual_studio
old: 62.62522673521669
new: 67.00851653326646

path: .spaces[0].spaces[0].spaces[6].metrics.mi.mi_original
old: 107.08913771722054
new: 114.58456327188566

Code

already_AddRefed ProbeManager::GetProbe(const nsCID& aEventUID,
                                               const nsACString& aEventName) {
  RefPtr result(new Probe(aEventUID, aEventName, this));
  mAllProbes.AppendElement(result);
  return result.forget();
}