Initial rehash of Memcheck's shadow-space management to support both
32- and 64-bit targets, little- and big-endian.  It does more or less
work on x86 as-is, although is unusably slow since I have knocked out
all the fast-path cases and am concentrating on getting the baseline
functionality correct.  The fast cases will go back in in due course.

The fundamental idea is to retain the old 2-level indexing for speed,
even on a 64-bit target.  Since that's clearly unviable on a 64-bit
target, the primary map handles only first N gigabytes of address
space (probably to be set to 16, 32 or 64G).  Addresses above that are
handled slowly using an auxiliary primary map which explicitly lists
(base, &-of-secondary-map) pairs.  The goal is to have the
address-space-manager try and put everything below the 16/32/64G
boundary, so we hit the fast cases almost all the time.

Performance of the 32-bit case should be unaffected since the fast map
will always cover at least the lowest 4G of address space.

There are many word-size and endianness cleanups.

Jeremy's distinguished-map space-compression scheme is retained, in
modified form, as it is simple and seems effective at reducing
Memcheck's space use.

Note this is all subject to rapid change.




git-svn-id: svn://svn.valgrind.org/valgrind/trunk@3535 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/memcheck/mac_shared.h b/memcheck/mac_shared.h
index f3a82be..44d9d05 100644
--- a/memcheck/mac_shared.h
+++ b/memcheck/mac_shared.h
@@ -189,22 +189,23 @@
 
 #endif   /* MAC_PROFILE_MEMORY */
 
-/*------------------------------------------------------------*/
-/*--- V and A bits                                         ---*/
-/*------------------------------------------------------------*/
 
-/* expand 1 bit -> 8 */
-#define BIT_EXPAND(b)	((~(((UChar)(b) & 1) - 1)) & 0xFF)
-
-#define SECONDARY_SHIFT	16
-#define SECONDARY_SIZE	(1 << SECONDARY_SHIFT)
-#define SECONDARY_MASK	(SECONDARY_SIZE - 1)
-
-#define PRIMARY_SIZE	(1 << (32 - SECONDARY_SHIFT))
-
-#define SM_OFF(addr)	((addr) & SECONDARY_MASK)
-#define PM_IDX(addr)	((addr) >> SECONDARY_SHIFT)
-
+//zz /*------------------------------------------------------------*/
+//zz /*--- V and A bits (Victoria & Albert ?)                   ---*/
+//zz /*------------------------------------------------------------*/
+//zz 
+//zz /* expand 1 bit -> 8 */
+//zz #define BIT_EXPAND(b)	((~(((UChar)(b) & 1) - 1)) & 0xFF)
+//zz 
+//zz #define SECONDARY_SHIFT	16
+//zz #define SECONDARY_SIZE	(1 << SECONDARY_SHIFT)
+//zz #define SECONDARY_MASK	(SECONDARY_SIZE - 1)
+//zz 
+//zz #define PRIMARY_SIZE	(1 << (32 - SECONDARY_SHIFT))
+//zz 
+//zz #define SM_OFF(addr)	((addr) & SECONDARY_MASK)
+//zz #define PM_IDX(addr)	((addr) >> SECONDARY_SHIFT)
+/*
 #define IS_DISTINGUISHED_SM(smap)		   \
    ((smap) >= &distinguished_secondary_maps[0] &&  \
     (smap) < &distinguished_secondary_maps[N_SECONDARY_MAPS])
@@ -215,43 +216,62 @@
    do {                                                           \
       if (IS_DISTINGUISHED(addr)) {				  \
 	 primary_map[PM_IDX(addr)] = alloc_secondary_map(caller, primary_map[PM_IDX(addr)]); \
-         /* VG_(printf)("new 2map because of %p\n", addr); */     \
+         if (0) VG_(printf)("new 2map because of %p\n", addr);     \
       }                                                           \
-   } while(0)
+  } while(0)
+*/
 
 #define BITARR_SET(aaa_p,iii_p)                         \
    do {                                                 \
-      UInt   iii = (UInt)iii_p;                         \
-      UChar* aaa = (UChar*)aaa_p;                       \
+      UWord   iii = (UWord)iii_p;                       \
+      UChar*  aaa = (UChar*)aaa_p;                      \
       aaa[iii >> 3] |= (1 << (iii & 7));                \
    } while (0)
 
 #define BITARR_CLEAR(aaa_p,iii_p)                       \
    do {                                                 \
-      UInt   iii = (UInt)iii_p;                         \
-      UChar* aaa = (UChar*)aaa_p;                       \
+      UWord   iii = (UWord)iii_p;                       \
+      UChar*  aaa = (UChar*)aaa_p;                      \
       aaa[iii >> 3] &= ~(1 << (iii & 7));               \
    } while (0)
 
 #define BITARR_TEST(aaa_p,iii_p)                        \
-      (0 != (((UChar*)aaa_p)[ ((UInt)iii_p) >> 3 ]      \
-               & (1 << (((UInt)iii_p) & 7))))           \
+      (0 != (((UChar*)aaa_p)[ ((UWord)iii_p) >> 3 ]     \
+               & (1 << (((UWord)iii_p) & 7))))          \
+
+static inline 
+void write_bit_array ( UChar* arr, UWord idx, UWord bit ) 
+{
+   UWord shift = idx & 7;
+   idx >>= 3;
+   bit &= 1;
+   arr[idx] = (arr[idx] & ~(1<<shift)) | (bit << shift);
+}
+
+static inline
+UWord read_bit_array ( UChar* arr, UWord idx )
+{
+   UWord shift = idx & 7;
+   idx >>= 3;
+   return 1 & (arr[idx] >> shift);
+}
 
 
-#define VGM_BIT_VALID      0
-#define VGM_BIT_INVALID    1
+#define VGM_BIT_VALID       0
+#define VGM_BIT_INVALID     1
 
-#define VGM_NIBBLE_VALID   0
-#define VGM_NIBBLE_INVALID 0xF
+#define VGM_NIBBLE_VALID    0
+#define VGM_NIBBLE_INVALID  0xF
 
-#define VGM_BYTE_VALID     0
-#define VGM_BYTE_INVALID   0xFF
+#define VGM_BYTE_VALID      0
+#define VGM_BYTE_INVALID    0xFF
 
-#define VGM_WORD_VALID     0
-#define VGM_WORD_INVALID   0xFFFFFFFF
+#define VGM_WORD32_VALID    0
+#define VGM_WORD32_INVALID  0xFFFFFFFF
 
-#define VGM_WORD64_VALID     0x0ULL
-#define VGM_WORD64_INVALID   0xFFFFFFFFFFFFFFFFULL
+#define VGM_WORD64_VALID    0ULL
+#define VGM_WORD64_INVALID  0xFFFFFFFFFFFFFFFFULL
+
 
 /*------------------------------------------------------------*/
 /*--- Command line options + defaults                      ---*/
@@ -408,166 +428,166 @@
 
    Note that this code is executed very frequently and must be highly
    optimised, which is why I resort to the preprocessor to achieve the
-   factoring, rather than eg. using function pointers.
+   factoring, rather than eg. using function pointers.  
 */
 
-#define ESP_UPDATE_HANDLERS(ALIGNED4_NEW,  ALIGNED4_DIE,                      \
-                            ALIGNED8_NEW,  ALIGNED8_DIE,                      \
-                            UNALIGNED_NEW, UNALIGNED_DIE)                     \
-                                                                              \
-void VGA_REGPARM(1) MAC_(new_mem_stack_4)(Addr new_ESP)                       \
-{                                                                             \
-   PROF_EVENT(110);                                                           \
-   if (VG_IS_4_ALIGNED(new_ESP)) {                                            \
-      ALIGNED4_NEW  ( new_ESP );                                              \
-   } else {                                                                   \
-      UNALIGNED_NEW ( new_ESP, 4 );                                           \
-   }                                                                          \
-}                                                                             \
-                                                                              \
-void VGA_REGPARM(1) MAC_(die_mem_stack_4)(Addr new_ESP)                       \
-{                                                                             \
-   PROF_EVENT(120);                                                           \
-   if (VG_IS_4_ALIGNED(new_ESP)) {                                            \
-      ALIGNED4_DIE  ( new_ESP-4 );                                            \
-   } else {                                                                   \
-      UNALIGNED_DIE ( new_ESP-4, 4 );                                         \
-   }                                                                          \
-}                                                                             \
-                                                                              \
-void VGA_REGPARM(1) MAC_(new_mem_stack_8)(Addr new_ESP)                       \
-{                                                                             \
-   PROF_EVENT(111);                                                           \
-   if (VG_IS_8_ALIGNED(new_ESP)) {                                            \
-      ALIGNED8_NEW  ( new_ESP );                                              \
-   } else if (VG_IS_4_ALIGNED(new_ESP)) {                                     \
-      ALIGNED4_NEW  ( new_ESP   );                                            \
-      ALIGNED4_NEW  ( new_ESP+4 );                                            \
-   } else {                                                                   \
-      UNALIGNED_NEW ( new_ESP, 8 );                                           \
-   }                                                                          \
-}                                                                             \
-                                                                              \
-void VGA_REGPARM(1) MAC_(die_mem_stack_8)(Addr new_ESP)                       \
-{                                                                             \
-   PROF_EVENT(121);                                                           \
-   if (VG_IS_8_ALIGNED(new_ESP)) {                                            \
-      ALIGNED8_DIE  ( new_ESP-8 );                                            \
-   } else if (VG_IS_4_ALIGNED(new_ESP)) {                                     \
-      ALIGNED4_DIE  ( new_ESP-8 );                                            \
-      ALIGNED4_DIE  ( new_ESP-4 );                                            \
-   } else {                                                                   \
-      UNALIGNED_DIE ( new_ESP-8, 8 );                                         \
-   }                                                                          \
-}                                                                             \
-                                                                              \
-void VGA_REGPARM(1) MAC_(new_mem_stack_12)(Addr new_ESP)                      \
-{                                                                             \
-   PROF_EVENT(112);                                                           \
-   if (VG_IS_8_ALIGNED(new_ESP)) {                                            \
-      ALIGNED8_NEW  ( new_ESP   );                                            \
-      ALIGNED4_NEW  ( new_ESP+8 );                                            \
-   } else if (VG_IS_4_ALIGNED(new_ESP)) {                                     \
-      ALIGNED4_NEW  ( new_ESP   );                                            \
-      ALIGNED8_NEW  ( new_ESP+4 );                                            \
-   } else {                                                                   \
-      UNALIGNED_NEW ( new_ESP, 12 );                                          \
-   }                                                                          \
-}                                                                             \
-                                                                              \
-void VGA_REGPARM(1) MAC_(die_mem_stack_12)(Addr new_ESP)                      \
-{                                                                             \
-   PROF_EVENT(122);                                                           \
-   /* Note the -12 in the test */                                             \
-   if (VG_IS_8_ALIGNED(new_ESP-12)) {                                         \
-      ALIGNED8_DIE  ( new_ESP-12 );                                           \
-      ALIGNED4_DIE  ( new_ESP-4  );                                           \
-   } else if (VG_IS_4_ALIGNED(new_ESP)) {                                     \
-      ALIGNED4_DIE  ( new_ESP-12 );                                           \
-      ALIGNED8_DIE  ( new_ESP-8  );                                           \
-   } else {                                                                   \
-      UNALIGNED_DIE ( new_ESP-12, 12 );                                       \
-   }                                                                          \
-}                                                                             \
-                                                                              \
-void VGA_REGPARM(1) MAC_(new_mem_stack_16)(Addr new_ESP)                      \
-{                                                                             \
-   PROF_EVENT(113);                                                           \
-   if (VG_IS_8_ALIGNED(new_ESP)) {                                            \
-      ALIGNED8_NEW  ( new_ESP   );                                            \
-      ALIGNED8_NEW  ( new_ESP+8 );                                            \
-   } else if (VG_IS_4_ALIGNED(new_ESP)) {                                     \
-      ALIGNED4_NEW  ( new_ESP    );                                           \
-      ALIGNED8_NEW  ( new_ESP+4  );                                           \
-      ALIGNED4_NEW  ( new_ESP+12 );                                           \
-   } else {                                                                   \
-      UNALIGNED_NEW ( new_ESP, 16 );                                          \
-   }                                                                          \
-}                                                                             \
-                                                                              \
-void VGA_REGPARM(1) MAC_(die_mem_stack_16)(Addr new_ESP)                      \
-{                                                                             \
-   PROF_EVENT(123);                                                           \
-   if (VG_IS_8_ALIGNED(new_ESP)) {                                            \
-      ALIGNED8_DIE  ( new_ESP-16 );                                           \
-      ALIGNED8_DIE  ( new_ESP-8  );                                           \
-   } else if (VG_IS_4_ALIGNED(new_ESP)) {                                     \
-      ALIGNED4_DIE  ( new_ESP-16 );                                           \
-      ALIGNED8_DIE  ( new_ESP-12 );                                           \
-      ALIGNED4_DIE  ( new_ESP-4  );                                           \
-   } else {                                                                   \
-      UNALIGNED_DIE ( new_ESP-16, 16 );                                       \
-   }                                                                          \
-}                                                                             \
-                                                                              \
-void VGA_REGPARM(1) MAC_(new_mem_stack_32)(Addr new_ESP)                      \
-{                                                                             \
-   PROF_EVENT(114);                                                           \
-   if (VG_IS_8_ALIGNED(new_ESP)) {                                            \
-      ALIGNED8_NEW  ( new_ESP    );                                           \
-      ALIGNED8_NEW  ( new_ESP+8  );                                           \
-      ALIGNED8_NEW  ( new_ESP+16 );                                           \
-      ALIGNED8_NEW  ( new_ESP+24 );                                           \
-   } else if (VG_IS_4_ALIGNED(new_ESP)) {                                     \
-      ALIGNED4_NEW  ( new_ESP    );                                           \
-      ALIGNED8_NEW  ( new_ESP+4  );                                           \
-      ALIGNED8_NEW  ( new_ESP+12 );                                           \
-      ALIGNED8_NEW  ( new_ESP+20 );                                           \
-      ALIGNED4_NEW  ( new_ESP+28 );                                           \
-   } else {                                                                   \
-      UNALIGNED_NEW ( new_ESP, 32 );                                          \
-   }                                                                          \
-}                                                                             \
-                                                                              \
-void VGA_REGPARM(1) MAC_(die_mem_stack_32)(Addr new_ESP)                      \
-{                                                                             \
-   PROF_EVENT(124);                                                           \
-   if (VG_IS_8_ALIGNED(new_ESP)) {                                            \
-      ALIGNED8_DIE  ( new_ESP-32 );                                           \
-      ALIGNED8_DIE  ( new_ESP-24 );                                           \
-      ALIGNED8_DIE  ( new_ESP-16 );                                           \
-      ALIGNED8_DIE  ( new_ESP- 8 );                                           \
-   } else if (VG_IS_4_ALIGNED(new_ESP)) {                                     \
-      ALIGNED4_DIE  ( new_ESP-32 );                                           \
-      ALIGNED8_DIE  ( new_ESP-28 );                                           \
-      ALIGNED8_DIE  ( new_ESP-20 );                                           \
-      ALIGNED8_DIE  ( new_ESP-12 );                                           \
-      ALIGNED4_DIE  ( new_ESP-4  );                                           \
-   } else {                                                                   \
-      UNALIGNED_DIE ( new_ESP-32, 32 );                                       \
-   }                                                                          \
-}                                                                             \
-                                                                              \
-void MAC_(new_mem_stack) ( Addr a, SizeT len )                                \
-{                                                                             \
-   PROF_EVENT(115);                                                           \
-   UNALIGNED_NEW ( a, len );                                                  \
-}                                                                             \
-                                                                              \
-void MAC_(die_mem_stack) ( Addr a, SizeT len )                                \
-{                                                                             \
-   PROF_EVENT(125);                                                           \
-   UNALIGNED_DIE ( a, len );                                                  \
+#define SP_UPDATE_HANDLERS(ALIGNED4_NEW,  ALIGNED4_DIE,       \
+                           ALIGNED8_NEW,  ALIGNED8_DIE,       \
+                           UNALIGNED_NEW, UNALIGNED_DIE)      \
+                                                              \
+void VGA_REGPARM(1) MAC_(new_mem_stack_4)(Addr new_SP)        \
+{                                                             \
+   PROF_EVENT(110);                                           \
+   if (VG_IS_4_ALIGNED(new_SP)) {                             \
+      ALIGNED4_NEW  ( new_SP );                               \
+   } else {                                                   \
+      UNALIGNED_NEW ( new_SP, 4 );                            \
+   }                                                          \
+}                                                             \
+                                                              \
+void VGA_REGPARM(1) MAC_(die_mem_stack_4)(Addr new_SP)        \
+{                                                             \
+   PROF_EVENT(120);                                           \
+   if (VG_IS_4_ALIGNED(new_SP)) {                             \
+      ALIGNED4_DIE  ( new_SP-4 );                             \
+   } else {                                                   \
+      UNALIGNED_DIE ( new_SP-4, 4 );                          \
+   }                                                          \
+}                                                             \
+                                                              \
+void VGA_REGPARM(1) MAC_(new_mem_stack_8)(Addr new_SP)        \
+{                                                             \
+   PROF_EVENT(111);                                           \
+   if (VG_IS_8_ALIGNED(new_SP)) {                             \
+      ALIGNED8_NEW  ( new_SP );                               \
+   } else if (VG_IS_4_ALIGNED(new_SP)) {                      \
+      ALIGNED4_NEW  ( new_SP   );                             \
+      ALIGNED4_NEW  ( new_SP+4 );                             \
+   } else {                                                   \
+      UNALIGNED_NEW ( new_SP, 8 );                            \
+   }                                                          \
+}                                                             \
+                                                              \
+void VGA_REGPARM(1) MAC_(die_mem_stack_8)(Addr new_SP)        \
+{                                                             \
+   PROF_EVENT(121);                                           \
+   if (VG_IS_8_ALIGNED(new_SP)) {                             \
+      ALIGNED8_DIE  ( new_SP-8 );                             \
+   } else if (VG_IS_4_ALIGNED(new_SP)) {                      \
+      ALIGNED4_DIE  ( new_SP-8 );                             \
+      ALIGNED4_DIE  ( new_SP-4 );                             \
+   } else {                                                   \
+      UNALIGNED_DIE ( new_SP-8, 8 );                          \
+   }                                                          \
+}                                                             \
+                                                              \
+void VGA_REGPARM(1) MAC_(new_mem_stack_12)(Addr new_SP)       \
+{                                                             \
+   PROF_EVENT(112);                                           \
+   if (VG_IS_8_ALIGNED(new_SP)) {                             \
+      ALIGNED8_NEW  ( new_SP   );                             \
+      ALIGNED4_NEW  ( new_SP+8 );                             \
+   } else if (VG_IS_4_ALIGNED(new_SP)) {                      \
+      ALIGNED4_NEW  ( new_SP   );                             \
+      ALIGNED8_NEW  ( new_SP+4 );                             \
+   } else {                                                   \
+      UNALIGNED_NEW ( new_SP, 12 );                           \
+   }                                                          \
+}                                                             \
+                                                              \
+void VGA_REGPARM(1) MAC_(die_mem_stack_12)(Addr new_SP)       \
+{                                                             \
+   PROF_EVENT(122);                                           \
+   /* Note the -12 in the test */                             \
+   if (VG_IS_8_ALIGNED(new_SP-12)) {                          \
+      ALIGNED8_DIE  ( new_SP-12 );                            \
+      ALIGNED4_DIE  ( new_SP-4  );                            \
+   } else if (VG_IS_4_ALIGNED(new_SP)) {                      \
+      ALIGNED4_DIE  ( new_SP-12 );                            \
+      ALIGNED8_DIE  ( new_SP-8  );                            \
+   } else {                                                   \
+      UNALIGNED_DIE ( new_SP-12, 12 );                        \
+   }                                                          \
+}                                                             \
+                                                              \
+void VGA_REGPARM(1) MAC_(new_mem_stack_16)(Addr new_SP)       \
+{                                                             \
+   PROF_EVENT(113);                                           \
+   if (VG_IS_8_ALIGNED(new_SP)) {                             \
+      ALIGNED8_NEW  ( new_SP   );                             \
+      ALIGNED8_NEW  ( new_SP+8 );                             \
+   } else if (VG_IS_4_ALIGNED(new_SP)) {                      \
+      ALIGNED4_NEW  ( new_SP    );                            \
+      ALIGNED8_NEW  ( new_SP+4  );                            \
+      ALIGNED4_NEW  ( new_SP+12 );                            \
+   } else {                                                   \
+      UNALIGNED_NEW ( new_SP, 16 );                           \
+   }                                                          \
+}                                                             \
+                                                              \
+void VGA_REGPARM(1) MAC_(die_mem_stack_16)(Addr new_SP)       \
+{                                                             \
+   PROF_EVENT(123);                                           \
+   if (VG_IS_8_ALIGNED(new_SP)) {                             \
+      ALIGNED8_DIE  ( new_SP-16 );                            \
+      ALIGNED8_DIE  ( new_SP-8  );                            \
+   } else if (VG_IS_4_ALIGNED(new_SP)) {                      \
+      ALIGNED4_DIE  ( new_SP-16 );                            \
+      ALIGNED8_DIE  ( new_SP-12 );                            \
+      ALIGNED4_DIE  ( new_SP-4  );                            \
+   } else {                                                   \
+      UNALIGNED_DIE ( new_SP-16, 16 );                        \
+   }                                                          \
+}                                                             \
+                                                              \
+void VGA_REGPARM(1) MAC_(new_mem_stack_32)(Addr new_SP)       \
+{                                                             \
+   PROF_EVENT(114);                                           \
+   if (VG_IS_8_ALIGNED(new_SP)) {                             \
+      ALIGNED8_NEW  ( new_SP    );                            \
+      ALIGNED8_NEW  ( new_SP+8  );                            \
+      ALIGNED8_NEW  ( new_SP+16 );                            \
+      ALIGNED8_NEW  ( new_SP+24 );                            \
+   } else if (VG_IS_4_ALIGNED(new_SP)) {                      \
+      ALIGNED4_NEW  ( new_SP    );                            \
+      ALIGNED8_NEW  ( new_SP+4  );                            \
+      ALIGNED8_NEW  ( new_SP+12 );                            \
+      ALIGNED8_NEW  ( new_SP+20 );                            \
+      ALIGNED4_NEW  ( new_SP+28 );                            \
+   } else {                                                   \
+      UNALIGNED_NEW ( new_SP, 32 );                           \
+   }                                                          \
+}                                                             \
+                                                              \
+void VGA_REGPARM(1) MAC_(die_mem_stack_32)(Addr new_SP)       \
+{                                                             \
+   PROF_EVENT(124);                                           \
+   if (VG_IS_8_ALIGNED(new_SP)) {                             \
+      ALIGNED8_DIE  ( new_SP-32 );                            \
+      ALIGNED8_DIE  ( new_SP-24 );                            \
+      ALIGNED8_DIE  ( new_SP-16 );                            \
+      ALIGNED8_DIE  ( new_SP- 8 );                            \
+   } else if (VG_IS_4_ALIGNED(new_SP)) {                      \
+      ALIGNED4_DIE  ( new_SP-32 );                            \
+      ALIGNED8_DIE  ( new_SP-28 );                            \
+      ALIGNED8_DIE  ( new_SP-20 );                            \
+      ALIGNED8_DIE  ( new_SP-12 );                            \
+      ALIGNED4_DIE  ( new_SP-4  );                            \
+   } else {                                                   \
+      UNALIGNED_DIE ( new_SP-32, 32 );                        \
+   }                                                          \
+}                                                             \
+                                                              \
+void MAC_(new_mem_stack) ( Addr a, SizeT len )                \
+{                                                             \
+   PROF_EVENT(115);                                           \
+   UNALIGNED_NEW ( a, len );                                  \
+}                                                             \
+                                                              \
+void MAC_(die_mem_stack) ( Addr a, SizeT len )                \
+{                                                             \
+   PROF_EVENT(125);                                           \
+   UNALIGNED_DIE ( a, len );                                  \
 }
 
 #endif   /* __MAC_SHARED_H */