diff options
| author | Qin Zhao <zhaoqin@google.com> | 2016-06-02 18:45:25 +0000 |
|---|---|---|
| committer | Qin Zhao <zhaoqin@google.com> | 2016-06-02 18:45:25 +0000 |
| commit | 4175a6d5804f62dc29e85e4160207f8cfc7a1c60 (patch) | |
| tree | c589aaf7807b559601bf23859f2ed57b4adfea23 /compiler-rt/lib/esan | |
| parent | d6c5bc2c814e8b677c474499b1715f1a4ea2c8c2 (diff) | |
| download | bcm5719-llvm-4175a6d5804f62dc29e85e4160207f8cfc7a1c60.tar.gz bcm5719-llvm-4175a6d5804f62dc29e85e4160207f8cfc7a1c60.zip | |
[esan|cfrag] Add struct info registration
Summary:
Adds StructInfo to CacheFragInfo to match the LLVM's EfficiencySanitizer
structs.
Uses StructHashMap to keep track of the struct info used by the app.
Adds registerStructInfo/unregisterStructInfo to add/remove struct infos
to/from StructHashMap.
updates test struct-simple.cpp with more C structs.
Reviewers: aizatsky, filcab
Subscribers: filcab, zhaoqin, llvm-commits, eugenis, vitalybuka, kcc, bruening, kubabrecka
Differential Revision: http://reviews.llvm.org/D20590
llvm-svn: 271564
Diffstat (limited to 'compiler-rt/lib/esan')
| -rw-r--r-- | compiler-rt/lib/esan/cache_frag.cpp | 75 |
1 files changed, 69 insertions, 6 deletions
diff --git a/compiler-rt/lib/esan/cache_frag.cpp b/compiler-rt/lib/esan/cache_frag.cpp index da168dc0c29..af36d90bb50 100644 --- a/compiler-rt/lib/esan/cache_frag.cpp +++ b/compiler-rt/lib/esan/cache_frag.cpp @@ -13,13 +13,17 @@ //===----------------------------------------------------------------------===// #include "esan.h" +#include "sanitizer_common/sanitizer_addrhashmap.h" +#include "sanitizer_common/sanitizer_placement_new.h" namespace __esan { +//===-- Struct field access counter runtime -------------------------------===// + // This should be kept consistent with LLVM's EfficiencySanitizer StructInfo. struct StructInfo { const char *StructName; - u32 NumOfFields; + u32 NumFields; u64 *FieldCounters; const char **FieldTypeNames; }; @@ -28,32 +32,91 @@ struct StructInfo { // The tool-specific information per compilation unit (module). struct CacheFragInfo { const char *UnitName; - u32 NumOfStructs; + u32 NumStructs; StructInfo *Structs; }; +struct StructCounter { + StructInfo *Struct; + u64 Count; // The total access count of the struct. + u32 Variance; // Variance score for the struct layout access. +}; + +// We use StructHashMap to keep track of an unique copy of StructCounter. +typedef AddrHashMap<StructCounter, 31051> StructHashMap; +struct Context { + StructHashMap StructMap; + u32 NumStructs; + u64 TotalCount; // The total access count of all structs. +}; +static Context *Ctx; + +static void registerStructInfo(CacheFragInfo *CacheFrag) { + for (u32 i = 0; i < CacheFrag->NumStructs; ++i) { + StructInfo *Struct = &CacheFrag->Structs[i]; + StructHashMap::Handle H(&Ctx->StructMap, (uptr)Struct->FieldCounters); + if (H.created()) { + VPrintf(2, " Register %s: %u fields\n", + Struct->StructName, Struct->NumFields); + H->Struct = Struct; + ++Ctx->NumStructs; + } else { + VPrintf(2, " Duplicated %s: %u fields\n", + Struct->StructName, Struct->NumFields); + } + } +} + +static void unregisterStructInfo(CacheFragInfo *CacheFrag) { + // FIXME: if the library is unloaded before finalizeCacheFrag, we should + // collect the result for later report. + for (u32 i = 0; i < CacheFrag->NumStructs; ++i) { + StructInfo *Struct = &CacheFrag->Structs[i]; + StructHashMap::Handle H(&Ctx->StructMap, (uptr)Struct->FieldCounters, true); + if (H.exists()) { + VPrintf(2, " Unregister %s: %u fields\n", + Struct->StructName, Struct->NumFields); + --Ctx->NumStructs; + } else { + VPrintf(2, " Duplicated %s: %u fields\n", + Struct->StructName, Struct->NumFields); + } + } +} + +static void reportStructSummary() { + // FIXME: iterate StructHashMap and generate the final report. + Report("%s is not finished: nothing yet to report\n", SanitizerToolName); +} + //===-- Init/exit functions -----------------------------------------------===// void processCacheFragCompilationUnitInit(void *Ptr) { CacheFragInfo *CacheFrag = (CacheFragInfo *)Ptr; VPrintf(2, "in esan::%s: %s with %u class(es)/struct(s)\n", - __FUNCTION__, CacheFrag->UnitName, CacheFrag->NumOfStructs); + __FUNCTION__, CacheFrag->UnitName, CacheFrag->NumStructs); + registerStructInfo(CacheFrag); } void processCacheFragCompilationUnitExit(void *Ptr) { CacheFragInfo *CacheFrag = (CacheFragInfo *)Ptr; VPrintf(2, "in esan::%s: %s with %u class(es)/struct(s)\n", - __FUNCTION__, CacheFrag->UnitName, CacheFrag->NumOfStructs); + __FUNCTION__, CacheFrag->UnitName, CacheFrag->NumStructs); + unregisterStructInfo(CacheFrag); } void initializeCacheFrag() { VPrintf(2, "in esan::%s\n", __FUNCTION__); + // We use placement new to initialize Ctx before C++ static initializaion. + // We make CtxMem 8-byte aligned for atomic operations in AddrHashMap. + static u64 CtxMem[sizeof(Context) / sizeof(u64) + 1]; + Ctx = new(CtxMem) Context(); + Ctx->NumStructs = 0; } int finalizeCacheFrag() { VPrintf(2, "in esan::%s\n", __FUNCTION__); - // FIXME: add the cache fragmentation final report. - Report("%s is not finished: nothing yet to report\n", SanitizerToolName); + reportStructSummary(); return 0; } |

