Beispiel #1
0
void bm_clear(struct bitmap* const bm,
              const Addr a1,
              const Addr a2)
{
  Addr b, b_next;

  tl_assert(bm);
  tl_assert(a1);
  tl_assert(a1 <= a2);

  for (b = a1; b < a2; b = b_next)
  {
    struct bitmap2* const p2 = bm2_lookup_exclusive(bm, b >> ADDR0_BITS);

    b_next = (b & ~ADDR0_MASK) + ADDR0_COUNT;
    if (b_next > a2)
    {
      b_next = a2;
    }

    if (p2)
    {
      Addr c = b;
      /* If the first address in the bitmap that must be cleared does not */
      /* start on an UWord boundary, start clearing the first addresses.  */
      if (UWORD_LSB(c))
      {
        Addr c_next = UWORD_MSB(c) + BITS_PER_UWORD;
        if (c_next > b_next)
          c_next = b_next;
        bm0_clear_range(p2->bm1.bm0_r, c & ADDR0_MASK, c_next - c);
        bm0_clear_range(p2->bm1.bm0_w, c & ADDR0_MASK, c_next - c);
        c = c_next;
      }
      /* If some UWords have to be cleared entirely, do this now. */
      if (UWORD_LSB(c) == 0)
      {
        const Addr c_next = UWORD_MSB(b_next);
        tl_assert(UWORD_LSB(c) == 0);
        tl_assert(UWORD_LSB(c_next) == 0);
        tl_assert(c_next <= b_next);
        tl_assert(c <= c_next);
        if (c_next > c)
        {
          UWord idx = (c & ADDR0_MASK) >> BITS_PER_BITS_PER_UWORD;
          VG_(memset)(&p2->bm1.bm0_r[idx], 0, (c_next - c) / 8);
          VG_(memset)(&p2->bm1.bm0_w[idx], 0, (c_next - c) / 8);
          c = c_next;
        }
      }
      /* If the last address in the bitmap that must be cleared does not */
      /* fall on an UWord boundary, clear the last addresses.            */
      /* tl_assert(c <= b_next); */
      bm0_clear_range(p2->bm1.bm0_r, c & ADDR0_MASK, b_next - c);
      bm0_clear_range(p2->bm1.bm0_w, c & ADDR0_MASK, b_next - c);
    }
  }
// New and fast implementation.
void bm_clear(const struct bitmap* const bm,
              const Addr a1,
              const Addr a2)
{
   Addr b, b_next;

   tl_assert(bm);
   tl_assert(a1);
   tl_assert(a1 <= a2);

   for (b = a1; b < a2; b = b_next)
   {
      struct bitmap2* const p2 = bm_lookup(bm, b);

      b_next = (b & ~ADDR0_MASK) + ADDR0_COUNT;
      if (b_next > a2)
      {
         b_next = a2;
      }

      if (p2)
      {
         Addr c = b;
         if (UWORD_LSB(c))
         {
            Addr c_next = UWORD_MSB(c) + BITS_PER_UWORD;
            if (c_next > b_next)
               c_next = b_next;
            bm1_clear(&p2->bm1, c, c_next);
            c = c_next;
         }
         if (UWORD_LSB(c) == 0)
         {
            const Addr c_next = UWORD_MSB(b_next);
            tl_assert(UWORD_LSB(c) == 0);
            tl_assert(UWORD_LSB(c_next) == 0);
            tl_assert(c_next <= b_next);
            tl_assert(c <= c_next);
            if (c_next > c)
            {
               UWord idx = (c & ADDR0_MASK) >> BITS_PER_BITS_PER_UWORD;
               VG_(memset)(&p2->bm1.bm0_r[idx], 0, (c_next - c) / 8);
               VG_(memset)(&p2->bm1.bm0_w[idx], 0, (c_next - c) / 8);
               c = c_next;
            }
         }
         if (c != b_next)
         {
            bm1_clear(&p2->bm1, c, b_next);
         }
      }
   }
static __inline__
void bm1_clear(struct bitmap1* const bm1, const Addr a1, const Addr a2)
{
   UWord idx;
   UWord mask;

#if 0
   // Commented out the assert statements below because of performance reasons.
   tl_assert(a1);
   tl_assert(a1 <= a2);
   tl_assert(UWORD_MSB(a1) == UWORD_MSB(a2)
             || UWORD_MSB(a1) == UWORD_MSB(a2 - 1));
#endif

   idx = (a1 & ADDR0_MASK) >> BITS_PER_BITS_PER_UWORD;
   /* mask: a contiguous series of one bits. The first bit set is bit */
   /* UWORD_LSB(a2-1), and the last bit set is UWORD_LSB(a1).         */
   mask = UWORD_LSB(a2) ? bm0_mask(a2) - bm0_mask(a1) : - bm0_mask(a1);
   bm1->bm0_r[idx] &= ~mask;
   bm1->bm0_w[idx] &= ~mask;
}