static bool verifyShadowScheme() { // Sanity checks for our shadow mapping scheme. uptr AppStart, AppEnd; if (Verbosity() >= 3) { for (int i = 0; getAppRegion(i, &AppStart, &AppEnd); ++i) { VPrintf(3, "App #%d: [%zx-%zx) (%zuGB)\n", i, AppStart, AppEnd, (AppEnd - AppStart) >> 30); } } for (int Scale = 0; Scale < 8; ++Scale) { Mapping.initialize(Scale); if (Verbosity() >= 3) { VPrintf(3, "\nChecking scale %d\n", Scale); uptr ShadowStart, ShadowEnd; for (int i = 0; getShadowRegion(i, &ShadowStart, &ShadowEnd); ++i) { VPrintf(3, "Shadow #%d: [%zx-%zx) (%zuGB)\n", i, ShadowStart, ShadowEnd, (ShadowEnd - ShadowStart) >> 30); } for (int i = 0; getShadowRegion(i, &ShadowStart, &ShadowEnd); ++i) { VPrintf(3, "Shadow(Shadow) #%d: [%zx-%zx)\n", i, appToShadow(ShadowStart), appToShadow(ShadowEnd - 1)+1); } } for (int i = 0; getAppRegion(i, &AppStart, &AppEnd); ++i) { DCHECK(isAppMem(AppStart)); DCHECK(!isAppMem(AppStart - 1)); DCHECK(isAppMem(AppEnd - 1)); DCHECK(!isAppMem(AppEnd)); DCHECK(!isShadowMem(AppStart)); DCHECK(!isShadowMem(AppEnd - 1)); DCHECK(isShadowMem(appToShadow(AppStart))); DCHECK(isShadowMem(appToShadow(AppEnd - 1))); // Double-shadow checks. DCHECK(!isShadowMem(appToShadow(appToShadow(AppStart)))); DCHECK(!isShadowMem(appToShadow(appToShadow(AppEnd - 1)))); } // Ensure no shadow regions overlap each other. uptr ShadowAStart, ShadowBStart, ShadowAEnd, ShadowBEnd; for (int i = 0; getShadowRegion(i, &ShadowAStart, &ShadowAEnd); ++i) { for (int j = 0; getShadowRegion(j, &ShadowBStart, &ShadowBEnd); ++j) { DCHECK(i == j || ShadowAStart >= ShadowBEnd || ShadowAEnd <= ShadowBStart); } } }
// 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). static u32 computeWorkingSizeAndReset(u32 BitIdx) { u32 WorkingSetSize = 0; MemoryMappingLayout MemIter(true/*cache*/); uptr Start, End, Prot; while (MemIter.Next(&Start, &End, nullptr/*offs*/, nullptr/*file*/, 0/*file size*/, &Prot)) { VPrintf(4, "%s: considering %p-%p app=%d shadow=%d prot=%u\n", __FUNCTION__, Start, End, Prot, isAppMem(Start), isShadowMem(Start)); if (isShadowMem(Start) && (Prot & MemoryMappingLayout::kProtectionWrite)) { VPrintf(3, "%s: walking %p-%p\n", __FUNCTION__, Start, End); WorkingSetSize += countAndClearShadowValues(BitIdx, Start, End); } } return WorkingSetSize; }