summaryrefslogtreecommitdiffstats
path: root/compiler-rt/lib/esan/working_set.cpp
diff options
context:
space:
mode:
authorDerek Bruening <bruening@google.com>2016-07-09 04:13:25 +0000
committerDerek Bruening <bruening@google.com>2016-07-09 04:13:25 +0000
commitdec4bd08382ec6d1006063019eba34df4eaa0ccb (patch)
tree33deb8bdb09de6038c1351a4d7592dec187b0b75 /compiler-rt/lib/esan/working_set.cpp
parent081fd139b3bd2247c658d7db6c7e3e65d0ce0424 (diff)
downloadbcm5719-llvm-dec4bd08382ec6d1006063019eba34df4eaa0ccb.tar.gz
bcm5719-llvm-dec4bd08382ec6d1006063019eba34df4eaa0ccb.zip
[esan] Add __esan_report for mid-run data
Summary: Adds a new public interface routine __esan_report() which can be used to request profiling results prior to abnormal termination (e.g., for a server process killed by its parent where the normal exit does not allow for normal result reporting). Implements this for the working-set tool. The cache frag tool is left unimplemented as it requires missing iteration capabilities. Adds a new test. Reviewers: aizatsky Subscribers: vitalybuka, zhaoqin, kcc, eugenis, llvm-commits, kubabrecka Differential Revision: http://reviews.llvm.org/D22098 llvm-svn: 274964
Diffstat (limited to 'compiler-rt/lib/esan/working_set.cpp')
-rw-r--r--compiler-rt/lib/esan/working_set.cpp26
1 files changed, 21 insertions, 5 deletions
diff --git a/compiler-rt/lib/esan/working_set.cpp b/compiler-rt/lib/esan/working_set.cpp
index 622fd29e846..3fde5a8b5fc 100644
--- a/compiler-rt/lib/esan/working_set.cpp
+++ b/compiler-rt/lib/esan/working_set.cpp
@@ -118,6 +118,8 @@ void processRangeAccessWorkingSet(uptr PC, uptr Addr, SIZE_T Size,
}
// This routine will word-align ShadowStart and ShadowEnd prior to scanning.
+// It does *not* clear for BitIdx==TotalWorkingSetBitIdx, as that top bit
+// measures the access during the entire execution and should never be cleared.
static u32 countAndClearShadowValues(u32 BitIdx, uptr ShadowStart,
uptr ShadowEnd) {
u32 WorkingSetSize = 0;
@@ -127,6 +129,8 @@ static u32 countAndClearShadowValues(u32 BitIdx, uptr ShadowStart,
// Get word aligned start.
ShadowStart = RoundDownTo(ShadowStart, sizeof(u32));
bool Accum = getFlags()->record_snapshots && BitIdx < MaxAccumBitIdx;
+ // Do not clear the bit that measures access during the entire execution.
+ bool Clear = BitIdx < TotalWorkingSetBitIdx;
for (u32 *Ptr = (u32 *)ShadowStart; Ptr < (u32 *)ShadowEnd; ++Ptr) {
if ((*Ptr & WordValue) != 0) {
byte *BytePtr = (byte *)Ptr;
@@ -139,8 +143,10 @@ static u32 countAndClearShadowValues(u32 BitIdx, uptr ShadowStart,
}
}
}
- // Clear this bit from every shadow byte.
- *Ptr &= ~WordValue;
+ if (Clear) {
+ // Clear this bit from every shadow byte.
+ *Ptr &= ~WordValue;
+ }
}
}
return WorkingSetSize;
@@ -149,6 +155,8 @@ static u32 countAndClearShadowValues(u32 BitIdx, uptr ShadowStart,
// Scan shadow memory to calculate the number of cache lines being accessed,
// i.e., the number of non-zero bits indexed by BitIdx in each shadow byte.
// We also clear the lowest bits (most recent working set snapshot).
+// We do *not* clear for BitIdx==TotalWorkingSetBitIdx, as that top bit
+// measures the access during the entire execution and should never be cleared.
static u32 computeWorkingSizeAndReset(u32 BitIdx) {
u32 WorkingSetSize = 0;
MemoryMappingLayout MemIter(true/*cache*/);
@@ -226,10 +234,9 @@ static u32 getSizeForPrinting(u32 NumOfCachelines, const char *&Unit) {
}
}
-int finalizeWorkingSet() {
+void reportWorkingSet() {
const char *Unit;
if (getFlags()->record_snapshots) {
- Thread.joinThread();
u32 Freq = 1;
Report(" Total number of samples: %u\n", SnapshotNum);
for (u32 i = 0; i < NumFreq; ++i) {
@@ -243,7 +250,6 @@ int finalizeWorkingSet() {
SizePerFreq[i][j]);
}
Freq = Freq << getFlags()->snapshot_step;
- SizePerFreq[i].free();
}
}
@@ -252,6 +258,16 @@ int finalizeWorkingSet() {
u32 Size = getSizeForPrinting(NumOfCachelines, Unit);
Report(" %s: the total working set size: %u %s (%u cache lines)\n",
SanitizerToolName, Size, Unit, NumOfCachelines);
+}
+
+int finalizeWorkingSet() {
+ if (getFlags()->record_snapshots)
+ Thread.joinThread();
+ reportWorkingSet();
+ if (getFlags()->record_snapshots) {
+ for (u32 i = 0; i < NumFreq; ++i)
+ SizePerFreq[i].free();
+ }
return 0;
}
OpenPOWER on IntegriCloud