Cache misses too.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@7789 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/exp-drd/drd_bitmap.c b/exp-drd/drd_bitmap.c
index 9d21a1d..5b994fd 100644
--- a/exp-drd/drd_bitmap.c
+++ b/exp-drd/drd_bitmap.c
@@ -59,15 +59,18 @@
   unsigned i;
   struct bitmap* bm;
 
-  // If this assert fails, fix the definition of BITS_PER_BITS_PER_UWORD
-  // in drd_bitmap.h.
+  /* If this assert fails, fix the definition of BITS_PER_BITS_PER_UWORD */
+  /* in drd_bitmap.h.                                                    */
   tl_assert((1 << BITS_PER_BITS_PER_UWORD) == BITS_PER_UWORD);
 
   bm = VG_(malloc)(sizeof(*bm));
   tl_assert(bm);
+  /* Cache initialization. a1 is initialized with a value that never can */
+  /* match any valid address: the upper ADDR0_BITS bits of a1 are always */
+  /* zero for a valid cache entry.                                       */
   for (i = 0; i < N_CACHE_ELEM; i++)
   {
-    bm->cache[i].a1  = 0;
+    bm->cache[i].a1  = ~(UWord)1;
     bm->cache[i].bm2 = 0;
   }
   bm->oset = VG_(OSetGen_Create)(0, 0, VG_(malloc), VG_(free));
diff --git a/exp-drd/drd_bitmap.h b/exp-drd/drd_bitmap.h
index 7f3b77a..d111ceb 100644
--- a/exp-drd/drd_bitmap.h
+++ b/exp-drd/drd_bitmap.h
@@ -201,69 +201,74 @@
                                           struct bitmap2ref* const bm2ref);
 
 
-#if 0
-/** Bitmap invariant check.
- *
- *  @return 1 if the invariant is satisfied, 0 if not.
- */
 static __inline__
-int bm_check(const struct bitmap* const bm)
-{
-  struct bitmap2_ref* bm2ref;
-
-  tl_assert(bm);
-
-  return (bm->cache[0].a1 == 0
-          && bm->cache[1].a1 == 0
-          || ((bm2ref = VG_(OSetGen_Lookup)(bm->oset, &bm->last_lookup_a1))
-              && bm2ref->bm2
-              && bm->last_lookup_a1 == bm2ref->bm2->addr
-              && bm2ref->bm2->refcnt >= 1)
-          );
-}
-#endif
-
-static __inline__
-struct bitmap2* bm_cache_lookup(const struct bitmap* const bm, const UWord a1)
+Bool bm_cache_lookup(const struct bitmap* const bm, const UWord a1,
+                     struct bitmap2** bm2)
 {
   tl_assert(bm);
+  tl_assert(bm2);
 
 #if N_CACHE_ELEM > 8
 #error Please update the code below.
 #endif
 #if N_CACHE_ELEM >= 1
   if (a1 == bm->cache[0].a1)
-    return bm->cache[0].bm2;
+  {
+    *bm2 = bm->cache[0].bm2;
+    return True;
+  }
 #endif
 #if N_CACHE_ELEM >= 2
   if (a1 == bm->cache[1].a1)
-    return bm->cache[1].bm2;
+  {
+    *bm2 = bm->cache[1].bm2;
+    return True;
+  }
 #endif
 #if N_CACHE_ELEM >= 3
   if (a1 == bm->cache[2].a1)
-    return bm->cache[2].bm2;
+  {
+    *bm2 = bm->cache[2].bm2;
+    return True;
+  }
 #endif
 #if N_CACHE_ELEM >= 4
   if (a1 == bm->cache[3].a1)
-    return bm->cache[3].bm2;
+  {
+    *bm2 = bm->cache[3].bm2;
+    return True;
+  }
 #endif
 #if N_CACHE_ELEM >= 5
   if (a1 == bm->cache[4].a1)
-    return bm->cache[4].bm2;
+  {
+    *bm2 = bm->cache[4].bm2;
+    return True;
+  }
 #endif
 #if N_CACHE_ELEM >= 6
   if (a1 == bm->cache[5].a1)
-    return bm->cache[5].bm2;
+  {
+    *bm2 = bm->cache[5].bm2;
+    return True;
+  }
 #endif
 #if N_CACHE_ELEM >= 7
   if (a1 == bm->cache[6].a1)
-    return bm->cache[6].bm2;
+  {
+    *bm2 = bm->cache[6].bm2;
+    return True;
+  }
 #endif
 #if N_CACHE_ELEM >= 8
   if (a1 == bm->cache[7].a1)
-    return bm->cache[7].bm2;
+  {
+    *bm2 = bm->cache[7].bm2;
+    return True;
+  }
 #endif
-  return 0;
+  *bm2 = 0;
+  return False;
 }
 
 static __inline__
@@ -311,25 +316,20 @@
 static __inline__
 const struct bitmap2* bm2_lookup(const struct bitmap* const bm, const UWord a1)
 {
+  struct bitmap2*    bm2;
   struct bitmap2ref* bm2ref;
 
   tl_assert(bm);
-  if (a1 == bm->cache[0].a1)
+  if (! bm_cache_lookup(bm, a1, &bm2))
   {
-    return bm->cache[0].bm2;
-  }
-  if (a1 == bm->cache[1].a1)
-  {
-    return bm->cache[1].bm2;
-  }
-  bm2ref = VG_(OSetGen_Lookup)(bm->oset, &a1);
-  if (bm2ref)
-  {
-    struct bitmap2* const bm2 = bm2ref->bm2;
+    bm2ref = VG_(OSetGen_Lookup)(bm->oset, &a1);
+    if (bm2ref)
+    {
+      bm2 = bm2ref->bm2;
+    }
     bm_update_cache(*(struct bitmap**)&bm, a1, bm2);
-    return bm2;
   }
-  return 0;
+  return bm2;
 }
 
 /** Look up the address a1 in bitmap bm and return a pointer to a second
@@ -346,9 +346,10 @@
   struct bitmap2* bm2;
 
   bm2ref = 0;
-  bm2 = bm_cache_lookup(bm, a1);
-  if (bm2)
+  if (bm_cache_lookup(bm, a1, &bm2))
   {
+    if (bm2 == 0)
+      return 0;
     if (bm2->refcnt > 1)
     {
       bm2ref = VG_(OSetGen_Lookup)(bm->oset, &a1);
@@ -357,14 +358,9 @@
   else
   {
     bm2ref = VG_(OSetGen_Lookup)(bm->oset, &a1);
-    if (bm2ref)
-    {
-      bm2 = bm2ref->bm2;
-    }
-    else
-    {
+    if (bm2ref == 0)
       return 0;
-    }
+    bm2 = bm2ref->bm2;
   }
 
   tl_assert(bm2);
@@ -438,8 +434,7 @@
   struct bitmap2* bm2;
 
   tl_assert(bm);
-  bm2 = bm_cache_lookup(bm, a1);
-  if (bm2 == 0)
+  if (! bm_cache_lookup(bm, a1, &bm2) || bm2 == 0)
   {
     bm2ref = VG_(OSetGen_Lookup)(bm->oset, &a1);
     if (bm2ref)