const uintptr_t kBits = 12;
const uintptr_t kMask = (1 << kBits) - 1;
uintptr_t Idx = (Caller & kMask) | ((Callee & kMask) << kBits);
- ValueProfileMap.AddValue(Idx);
+ ValueProfileMap.AddValueModPrime(Idx);
}
void TracePC::InitializePrintNewPCs() {
class TracePC {
public:
- static const size_t kFeatureSetSize = ValueBitMap::kNumberOfItems;
void HandleTrace(uint32_t *guard, uintptr_t PC);
void HandleInit(uint32_t *start, uint32_t *stop);
void SetUseValueProfile(bool VP) { UseValueProfile = VP; }
void SetPrintNewPCs(bool P) { DoPrintNewPCs = P; }
template <class Callback> size_t CollectFeatures(Callback CB);
- bool UpdateValueProfileMap(ValueBitMap *MaxValueProfileMap) {
- return UseValueProfile && MaxValueProfileMap->MergeFrom(ValueProfileMap);
- }
void ResetMaps() {
ValueProfileMap.Reset();
// A bit map containing kMapSizeInWords bits.
struct ValueBitMap {
- static const size_t kMapSizeInBits = 65371; // Prime.
- static const size_t kMapSizeInBitsAligned = 1 << 16; // 2^16
+ static const size_t kMapSizeInBits = 1 << 16;
+ static const size_t kMapPrimeMod = 65371; // Largest Prime < kMapSizeInBits;
static const size_t kBitsInWord = (sizeof(uintptr_t) * 8);
- static const size_t kMapSizeInWords = kMapSizeInBitsAligned / kBitsInWord;
+ static const size_t kMapSizeInWords = kMapSizeInBits / kBitsInWord;
public:
- static const size_t kNumberOfItems = kMapSizeInBits;
+
// Clears all bits.
void Reset() { memset(Map, 0, sizeof(Map)); }
// Returns true if the bit was changed from 0 to 1.
ATTRIBUTE_NO_SANITIZE_ALL
inline bool AddValue(uintptr_t Value) {
- uintptr_t Idx = Value < kMapSizeInBits ? Value : Value % kMapSizeInBits;
+ uintptr_t Idx = Value % kMapSizeInBits;
uintptr_t WordIdx = Idx / kBitsInWord;
uintptr_t BitIdx = Idx % kBitsInWord;
uintptr_t Old = Map[WordIdx];
return New != Old;
}
+ ATTRIBUTE_NO_SANITIZE_ALL
+ inline bool AddValueModPrime(uintptr_t Value) {
+ return AddValue(Value % kMapPrimeMod);
+ }
+
inline bool Get(uintptr_t Idx) {
assert(Idx < kMapSizeInBits);
uintptr_t WordIdx = Idx / kBitsInWord;