Ejemplo n.º 1
0
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);
      }
    }
  }
Ejemplo n.º 2
0
void processRangeAccessWorkingSet(uptr PC, uptr Addr, SIZE_T Size,
                                  bool IsWrite) {
  if (Size == 0)
    return;
  SIZE_T I = 0;
  uptr LineSize = getFlags()->cache_line_size;
  // As Addr+Size could overflow at the top of a 32-bit address space,
  // we avoid the simpler formula that rounds the start and end.
  SIZE_T NumLines = Size / LineSize +
    // Add any extra at the start or end adding on an extra line:
    (LineSize - 1 + Addr % LineSize + Size % LineSize) / LineSize;
  byte *Shadow = (byte *)appToShadow(Addr);
  // Write shadow bytes until we're word-aligned.
  while (I < NumLines && (uptr)Shadow % 4 != 0) {
    if ((*Shadow & ShadowAccessedVal) != ShadowAccessedVal)
      *Shadow |= ShadowAccessedVal;
    ++Shadow;
    ++I;
  }
  // Write whole shadow words at a time.
  // Using a word-stride loop improves the runtime of a microbenchmark of
  // memset calls by 10%.
  u32 WordValue = ShadowAccessedVal | ShadowAccessedVal << 8 |
    ShadowAccessedVal << 16 | ShadowAccessedVal << 24;
  while (I + 4 <= NumLines) {
    if ((*(u32*)Shadow & WordValue) != WordValue)
      *(u32*)Shadow |= WordValue;
    Shadow += 4;
    I += 4;
  }
  // Write any trailing shadow bytes.
  while (I < NumLines) {
    if ((*Shadow & ShadowAccessedVal) != ShadowAccessedVal)
      *Shadow |= ShadowAccessedVal;
    ++Shadow;
    ++I;
  }
}