Global Metrics
path: .metrics.halstead.N2
old: 186.0
new: 290.0
path: .metrics.halstead.estimated_program_length
old: 316.1839163704497
new: 746.3477154631084
path: .metrics.halstead.time
old: 3693.016598721668
new: 9945.521983479792
path: .metrics.halstead.bugs
old: 0.5469923532661695
new: 1.0587956210253442
path: .metrics.halstead.n1
old: 13.0
new: 26.0
path: .metrics.halstead.difficulty
old: 25.1875
new: 39.68421052631579
path: .metrics.halstead.length
old: 445.0
new: 652.0
path: .metrics.halstead.level
old: 0.03970223325062035
new: 0.02519893899204244
path: .metrics.halstead.volume
old: 2639.1781152154845
new: 4511.098830703036
path: .metrics.halstead.N1
old: 259.0
new: 362.0
path: .metrics.halstead.effort
old: 66474.29877699002
new: 179019.39570263625
path: .metrics.halstead.n2
old: 48.0
new: 95.0
path: .metrics.halstead.purity_ratio
old: 0.7105256547650555
new: 1.1447050850661171
path: .metrics.halstead.vocabulary
old: 61.0
new: 121.0
path: .metrics.loc.lloc
old: 5.0
new: 56.0
path: .metrics.loc.sloc
old: 158.0
new: 207.0
path: .metrics.loc.blank
old: 27.0
new: 37.0
path: .metrics.loc.ploc
old: 104.0
new: 134.0
path: .metrics.loc.cloc
old: 27.0
new: 36.0
path: .metrics.nargs.sum
old: 6.0
new: 18.0
path: .metrics.nargs.average
old: 0.5
new: 1.5
path: .metrics.cyclomatic.average
old: 1.0
new: 2.0625
path: .metrics.cyclomatic.sum
old: 21.0
new: 33.0
path: .metrics.mi.mi_original
old: 43.18920176104744
new: 33.26561610994288
path: .metrics.mi.mi_visual_studio
old: 25.256843135115464
new: 19.45357667248122
path: .metrics.mi.mi_sei
old: 18.622475304416284
new: 5.753531510842887
path: .metrics.cognitive.average
old: 0.0
new: 0.75
path: .metrics.cognitive.sum
old: 0.0
new: 9.0
path: .metrics.nexits.sum
old: 5.0
new: 11.0
path: .metrics.nexits.average
old: 0.4166666666666667
new: 0.9166666666666666
Spaces Data
Minimal test - lines (33, 53)
path: .spaces[0].spaces[0].metrics.mi.mi_sei
old: 18.472850423126204
new: 53.62150385269314
path: .spaces[0].spaces[0].metrics.mi.mi_original
old: 45.38810238831371
new: 89.42769789171422
path: .spaces[0].spaces[0].metrics.mi.mi_visual_studio
old: 26.54274993468638
new: 52.29689935187966
path: .spaces[0].spaces[0].metrics.loc.lloc
old: 5.0
new: 7.0
path: .spaces[0].spaces[0].metrics.loc.blank
old: 26.0
new: 3.0
path: .spaces[0].spaces[0].metrics.loc.ploc
old: 98.0
new: 18.0
path: .spaces[0].spaces[0].metrics.loc.sloc
old: 143.0
new: 21.0
path: .spaces[0].spaces[0].metrics.loc.cloc
old: 19.0
new: 0.0
path: .spaces[0].spaces[0].metrics.nexits.average
old: 0.4166666666666667
new: 3.0
path: .spaces[0].spaces[0].metrics.nexits.sum
old: 5.0
new: 3.0
path: .spaces[0].spaces[0].metrics.cyclomatic.sum
old: 19.0
new: 3.0
path: .spaces[0].spaces[0].metrics.cyclomatic.average
old: 1.0
new: 3.0
path: .spaces[0].spaces[0].metrics.cognitive.average
old: 0.0
new: 2.0
path: .spaces[0].spaces[0].metrics.cognitive.sum
old: 0.0
new: 2.0
path: .spaces[0].spaces[0].metrics.nargs.sum
old: 6.0
new: 3.0
path: .spaces[0].spaces[0].metrics.nargs.average
old: 0.5
new: 3.0
path: .spaces[0].spaces[0].metrics.halstead.N2
old: 182.0
new: 34.0
path: .spaces[0].spaces[0].metrics.halstead.purity_ratio
old: 0.67099796743334
new: 1.6389880198771285
path: .spaces[0].spaces[0].metrics.halstead.difficulty
old: 26.288888888888888
new: 13.421052631578949
path: .spaces[0].spaces[0].metrics.halstead.length
old: 440.0
new: 85.0
path: .spaces[0].spaces[0].metrics.halstead.volume
old: 2577.5116378561315
new: 432.4343415062788
path: .spaces[0].spaces[0].metrics.halstead.effort
old: 67759.91705741786
new: 5803.724057057952
path: .spaces[0].spaces[0].metrics.halstead.time
old: 3764.439836523214
new: 322.42911428099734
path: .spaces[0].spaces[0].metrics.halstead.N1
old: 258.0
new: 51.0
path: .spaces[0].spaces[0].metrics.halstead.bugs
old: 0.5540223976157168
new: 0.10765063158981984
path: .spaces[0].spaces[0].metrics.halstead.n1
old: 13.0
new: 15.0
path: .spaces[0].spaces[0].metrics.halstead.vocabulary
old: 58.0
new: 34.0
path: .spaces[0].spaces[0].metrics.halstead.level
old: 0.03803888419273035
new: 0.07450980392156863
path: .spaces[0].spaces[0].metrics.halstead.n2
old: 45.0
new: 19.0
path: .spaces[0].spaces[0].metrics.halstead.estimated_program_length
old: 295.2391056706696
new: 139.3139816895559
path: .spaces[0].spaces[0].metrics.nom.functions
old: 12.0
new: 1.0
path: .spaces[0].spaces[0].metrics.nom.total
old: 12.0
new: 1.0
Code
static int32_t GetPathFromFd(int32_t aFd, char* aBuf, size_t aBufSize) {
#ifdef XP_MACOSX
NS_ASSERTION(aBufSize >= MAXPATHLEN,
"aBufSize should be a least MAXPATHLEN long");
return fcntl(aFd, F_GETPATH, aBuf);
#else
char procPath[32];
if (PR_snprintf(procPath, sizeof(procPath), "/proc/self/fd/%i", aFd) ==
(PRUint32)-1) {
return -1;
}
int32_t ret = readlink(procPath, aBuf, aBufSize - 1);
if (ret > -1) {
aBuf[ret] = '\0';
}
return ret;
#endif
}
Minimal test - lines (23, 132)
path: .spaces[0].metrics.loc.lloc
old: 5.0
new: 24.0
path: .spaces[0].metrics.loc.ploc
old: 100.0
new: 77.0
path: .spaces[0].metrics.loc.cloc
old: 20.0
new: 11.0
path: .spaces[0].metrics.loc.sloc
old: 145.0
new: 110.0
path: .spaces[0].metrics.loc.blank
old: 25.0
new: 22.0
path: .spaces[0].metrics.nargs.sum
old: 6.0
new: 18.0
path: .spaces[0].metrics.nargs.average
old: 0.5
new: 1.8
path: .spaces[0].metrics.nexits.average
old: 0.4166666666666667
new: 0.9
path: .spaces[0].metrics.nexits.sum
old: 5.0
new: 9.0
path: .spaces[0].metrics.nom.total
old: 12.0
new: 10.0
path: .spaces[0].metrics.nom.functions
old: 12.0
new: 10.0
path: .spaces[0].metrics.mi.mi_original
old: 44.887669958624855
new: 49.795021505548235
path: .spaces[0].metrics.mi.mi_sei
old: 18.30143787298541
new: 21.395908323821786
path: .spaces[0].metrics.mi.mi_visual_studio
old: 26.25009939100869
new: 29.11989561727967
path: .spaces[0].metrics.cyclomatic.average
old: 1.0
new: 1.4166666666666667
path: .spaces[0].metrics.cyclomatic.sum
old: 20.0
new: 17.0
path: .spaces[0].metrics.cognitive.sum
old: 0.0
new: 5.0
path: .spaces[0].metrics.cognitive.average
old: 0.0
new: 0.5
path: .spaces[0].metrics.halstead.effort
old: 67235.92449977026
new: 77706.21435976328
path: .spaces[0].metrics.halstead.level
old: 0.03867171080285834
new: 0.035162746495604656
path: .spaces[0].metrics.halstead.purity_ratio
old: 0.683686801616418
new: 1.36121128996583
path: .spaces[0].metrics.halstead.time
old: 3735.329138876126
new: 4317.011908875738
path: .spaces[0].metrics.halstead.volume
old: 2600.1282278179337
new: 2732.3639166654707
path: .spaces[0].metrics.halstead.N1
old: 259.0
new: 231.0
path: .spaces[0].metrics.halstead.estimated_program_length
old: 302.1895663144568
new: 563.5414740458536
path: .spaces[0].metrics.halstead.n2
old: 46.0
new: 74.0
path: .spaces[0].metrics.halstead.vocabulary
old: 59.0
new: 97.0
path: .spaces[0].metrics.halstead.length
old: 442.0
new: 414.0
path: .spaces[0].metrics.halstead.bugs
old: 0.5511625056702443
new: 0.6069914585407531
path: .spaces[0].metrics.halstead.n1
old: 13.0
new: 23.0
path: .spaces[0].metrics.halstead.difficulty
old: 25.85869565217391
new: 28.43918918918919
Code
namespace {
/* Original IO methods */
PRCloseFN sCloseFn = nullptr;
PRReadFN sReadFn = nullptr;
PRWriteFN sWriteFn = nullptr;
PRFsyncFN sFSyncFn = nullptr;
PRFileInfoFN sFileInfoFn = nullptr;
PRFileInfo64FN sFileInfo64Fn = nullptr;
static int32_t GetPathFromFd(int32_t aFd, char* aBuf, size_t aBufSize) {
#ifdef XP_MACOSX
NS_ASSERTION(aBufSize >= MAXPATHLEN,
"aBufSize should be a least MAXPATHLEN long");
return fcntl(aFd, F_GETPATH, aBuf);
#else
char procPath[32];
if (PR_snprintf(procPath, sizeof(procPath), "/proc/self/fd/%i", aFd) ==
(PRUint32)-1) {
return -1;
}
int32_t ret = readlink(procPath, aBuf, aBufSize - 1);
if (ret > -1) {
aBuf[ret] = '\0';
}
return ret;
#endif
}
/**
* RAII class for timing the duration of an NSPR I/O call and reporting the
* result to the mozilla::IOInterposeObserver API.
*/
class NSPRIOAutoObservation : public mozilla::IOInterposeObserver::Observation {
public:
explicit NSPRIOAutoObservation(mozilla::IOInterposeObserver::Operation aOp,
PRFileDesc* aFd)
: mozilla::IOInterposeObserver::Observation(aOp, "NSPRIOInterposer") {
char filename[MAXPATHLEN];
if (mShouldReport && aFd &&
GetPathFromFd(PR_FileDesc2NativeHandle(aFd), filename,
sizeof(filename)) != -1) {
CopyUTF8toUTF16(mozilla::MakeStringSpan(filename), mFilename);
} else {
mFilename.Truncate();
}
}
void Filename(nsAString& aFilename) override { aFilename = mFilename; }
~NSPRIOAutoObservation() override { Report(); }
private:
nsString mFilename;
};
PRStatus PR_CALLBACK interposedClose(PRFileDesc* aFd) {
// If we don't have a valid original function pointer something is very wrong.
NS_ASSERTION(sCloseFn, "NSPR IO Interposing: sCloseFn is NULL");
NSPRIOAutoObservation timer(mozilla::IOInterposeObserver::OpClose, aFd);
return sCloseFn(aFd);
}
int32_t PR_CALLBACK interposedRead(PRFileDesc* aFd, void* aBuf, int32_t aAmt) {
// If we don't have a valid original function pointer something is very wrong.
NS_ASSERTION(sReadFn, "NSPR IO Interposing: sReadFn is NULL");
NSPRIOAutoObservation timer(mozilla::IOInterposeObserver::OpRead, aFd);
return sReadFn(aFd, aBuf, aAmt);
}
int32_t PR_CALLBACK interposedWrite(PRFileDesc* aFd, const void* aBuf,
int32_t aAmt) {
// If we don't have a valid original function pointer something is very wrong.
NS_ASSERTION(sWriteFn, "NSPR IO Interposing: sWriteFn is NULL");
NSPRIOAutoObservation timer(mozilla::IOInterposeObserver::OpWrite, aFd);
return sWriteFn(aFd, aBuf, aAmt);
}
PRStatus PR_CALLBACK interposedFSync(PRFileDesc* aFd) {
// If we don't have a valid original function pointer something is very wrong.
NS_ASSERTION(sFSyncFn, "NSPR IO Interposing: sFSyncFn is NULL");
NSPRIOAutoObservation timer(mozilla::IOInterposeObserver::OpFSync, aFd);
return sFSyncFn(aFd);
}
PRStatus PR_CALLBACK interposedFileInfo(PRFileDesc* aFd, PRFileInfo* aInfo) {
// If we don't have a valid original function pointer something is very wrong.
NS_ASSERTION(sFileInfoFn, "NSPR IO Interposing: sFileInfoFn is NULL");
NSPRIOAutoObservation timer(mozilla::IOInterposeObserver::OpStat, aFd);
return sFileInfoFn(aFd, aInfo);
}
PRStatus PR_CALLBACK interposedFileInfo64(PRFileDesc* aFd,
PRFileInfo64* aInfo) {
// If we don't have a valid original function pointer something is very wrong.
NS_ASSERTION(sFileInfo64Fn, "NSPR IO Interposing: sFileInfo64Fn is NULL");
NSPRIOAutoObservation timer(mozilla::IOInterposeObserver::OpStat, aFd);
return sFileInfo64Fn(aFd, aInfo);
}
} // namespace