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 */