|
From: Julian S. <js...@ac...> - 2004-03-14 03:06:44
|
CVS commit by jseward:
Modify the memory manager so it "natively" supports 8-byte alignment,
basically by messing with the block layout.
* Move freelist next ptr from before payload to after it
* Ensure payload and red zones always have sizes which are
multiples of 8-bytes.
Seems to work OK. Values returned from the two basic allocator
functions VG_(arena_malloc) and VG_(arena_malloc_aligned) are
vg_asserted to have suitable alignment (== 8, >= 8 && == requested
alignment) respectively.
M +69 -37 vg_malloc2.c 1.22
--- valgrind/coregrind/vg_malloc2.c #1.21:1.22
@@ -56,5 +56,5 @@ Bool VG_(replacement_malloc_process_cmd_
VG_(clo_alignment) = (Int)VG_(atoll)(&arg[12]);
- if (VG_(clo_alignment) < 4
+ if (VG_(clo_alignment) < 8
|| VG_(clo_alignment) > 4096
|| VG_(log2)( VG_(clo_alignment) ) == -1 /* not a power of 2 */) {
@@ -62,5 +62,5 @@ Bool VG_(replacement_malloc_process_cmd_
VG_(message)(Vg_UserMsg,
"Invalid --alignment= setting. "
- "Should be a power of 2, >= 4, <= 4096.");
+ "Should be a power of 2, >= 8, <= 4096.");
VG_(bad_option)("--alignment");
}
@@ -147,8 +147,8 @@ typedef
this block total sizeW (1 word)
freelist previous ptr (1 word)
- freelist next ptr (1 word)
red zone words (depends on .rz_szW field of Arena)
(payload words)
red zone words (depends on .rz_szW field of Arena)
+ freelist next ptr (1 word)
this block total sizeW (1 word)
@@ -161,4 +161,8 @@ typedef
is not possible, because a block always has at least four words
of overhead.
+
+ 8-byte payload alignment is ensured by requiring the number
+ of words in the red zones and the number of payload words
+ to both be even (% 2 == 0).
*/
typedef
@@ -210,4 +214,6 @@ void arena_init ( Arena* a, Char* name,
{
Int i;
+ vg_assert(rz_szW >= 0);
+ vg_assert(rz_szW % 2 == 0);
vg_assert((min_sblockW % VKI_WORDS_PER_PAGE) == 0);
a->name = name;
@@ -249,4 +255,5 @@ static
void ensure_mm_init ( void )
{
+ Int client_rz_szW;
static Bool init_done = False;
@@ -260,23 +267,27 @@ void ensure_mm_init ( void )
zone words are unchanged. */
- arena_init ( &vg_arena[VG_AR_CORE], "core", 1, True, 262144, False );
+ arena_init ( &vg_arena[VG_AR_CORE], "core", 2, True, 262144, False );
- arena_init ( &vg_arena[VG_AR_TOOL], "tool", 1, True, 262144, False );
+ arena_init ( &vg_arena[VG_AR_TOOL], "tool", 2, True, 262144, False );
- arena_init ( &vg_arena[VG_AR_SYMTAB], "symtab", 1, True, 262144, False );
+ arena_init ( &vg_arena[VG_AR_SYMTAB], "symtab", 2, True, 262144, False );
- arena_init ( &vg_arena[VG_AR_JITTER], "JITter", 1, True, 8192, False );
+ arena_init ( &vg_arena[VG_AR_JITTER], "JITter", 2, True, 8192, False );
/* No particular reason for this figure, it's just smallish */
sk_assert(VG_(vg_malloc_redzone_szB) < 128);
+ sk_assert(VG_(vg_malloc_redzone_szB) >= 0);
+ client_rz_szW = VG_(vg_malloc_redzone_szB)/4;
+ if (client_rz_szW % 2 == 1) client_rz_szW++;
+
arena_init ( &vg_arena[VG_AR_CLIENT], "client",
- VG_(vg_malloc_redzone_szB)/4, False, 262144, True );
+ client_rz_szW, False, 262144, True );
arena_init ( &vg_arena[VG_AR_DEMANGLE], "demangle", 4 /*paranoid*/,
True, 16384, False );
- arena_init ( &vg_arena[VG_AR_EXECTXT], "exectxt", 1, True, 16384, False );
+ arena_init ( &vg_arena[VG_AR_EXECTXT], "exectxt", 2, True, 16384, False );
- arena_init ( &vg_arena[VG_AR_ERRORS], "errors", 1, True, 16384, False );
+ arena_init ( &vg_arena[VG_AR_ERRORS], "errors", 2, True, 16384, False );
arena_init ( &vg_arena[VG_AR_TRANSIENT], "transien", 2, True, 16384, False );
@@ -324,5 +335,6 @@ Superblock* newSuperblock ( Arena* a, In
if (a->clientmem) {
- sb = (Superblock *)VG_(client_alloc)(0, cszW * sizeof(Word),
+ sb = (Superblock *)
+ VG_(client_alloc)(0, cszW * sizeof(Word),
VKI_PROT_READ|VKI_PROT_WRITE|VKI_PROT_EXEC, 0);
} else
@@ -414,5 +426,5 @@ static __inline__
Word* first_to_payload ( Arena* a, WordF* fw )
{
- return & fw[3 + a->rz_szW];
+ return & fw[2 + a->rz_szW];
}
@@ -422,5 +434,5 @@ static __inline__
Word* payload_to_first ( Arena* a, WordF* payload )
{
- return & payload[- 3 - a->rz_szW];
+ return & payload[- (2 + a->rz_szW)];
}
@@ -444,5 +456,6 @@ void set_prev_p ( WordF* fw, Word* prev
static __inline__
void set_next_p ( WordF* fw, Word* next_p ) {
- fw[2] = (Word)next_p;
+ WordL* lw = first_to_last(fw);
+ lw[-1] = (Word)next_p;
}
static __inline__
@@ -452,5 +465,6 @@ Word* get_prev_p ( WordF* fw ) {
static __inline__
Word* get_next_p ( WordF* fw ) {
- return (Word*)(fw[2]);
+ WordL* lw = first_to_last(fw);
+ return (Word*)(lw[-1]);
}
@@ -482,5 +496,5 @@ static __inline__
void set_rz_lo_word ( Arena* a, WordF* fw, Int rz_wordno, Word w )
{
- fw[3 + rz_wordno] = w;
+ fw[2 + rz_wordno] = w;
}
static __inline__
@@ -488,10 +502,10 @@ void set_rz_hi_word ( Arena* a, WordF* f
{
WordL* lw = first_to_last(fw);
- lw[-1-rz_wordno] = w;
+ lw[-2-rz_wordno] = w;
}
static __inline__
Word get_rz_lo_word ( Arena* a, WordF* fw, Int rz_wordno )
{
- return fw[3 + rz_wordno];
+ return fw[2 + rz_wordno];
}
static __inline__
@@ -499,5 +513,5 @@ Word get_rz_hi_word ( Arena* a, WordF* f
{
WordL* lw = first_to_last(fw);
- return lw[-1-rz_wordno];
+ return lw[-2-rz_wordno];
}
@@ -508,10 +522,10 @@ static __inline__
Int overhead_szW_lo ( Arena* a )
{
- return 3 + a->rz_szW;
+ return 2 + a->rz_szW;
}
static __inline__
Int overhead_szW_hi ( Arena* a )
{
- return 1 + a->rz_szW;
+ return 2 + a->rz_szW;
}
static __inline__
@@ -949,4 +963,15 @@ Bool VG_(is_empty_arena) ( ArenaId aid )
+/* Turn a request size in bytes into a payload request size in
+ words. This means 8-aligning the request size.
+*/
+static __inline__
+Int req_pszB_to_req_pszW ( Int req_pszB )
+{
+ return ((req_pszB + 7) / 8) /* # of 64-bit units */
+ * 2; /* # of 32-bit units */
+}
+
+
/*------------------------------------------------------------*/
/*--- Core-visible functions. ---*/
@@ -959,4 +984,5 @@ void* VG_(arena_malloc) ( ArenaId aid, I
Word* b;
Arena* a;
+ void* v;
VGP_PUSHCC(VgpMalloc);
@@ -968,5 +994,5 @@ void* VG_(arena_malloc) ( ArenaId aid, I
vg_assert(req_pszB < 0x7FFFFFF0);
- req_pszW = (req_pszB + VKI_BYTES_PER_WORD - 1) / VKI_BYTES_PER_WORD;
+ req_pszW = req_pszB_to_req_pszW(req_pszB);
/* Keep gcc -O happy: */
@@ -1052,5 +1078,7 @@ void* VG_(arena_malloc) ( ArenaId aid, I
VGP_POPCC(VgpMalloc);
- return first_to_payload(a, b);
+ v = first_to_payload(a, b);
+ vg_assert( (((UInt)v) & 7) == 0 );
+ return v;
}
@@ -1179,4 +1207,5 @@ void* VG_(arena_malloc_aligned) ( ArenaI
UInt saved_bytes_on_loan;
Arena* a;
+ void* v;
VGP_PUSHCC(VgpMalloc);
@@ -1209,9 +1238,10 @@ void* VG_(arena_malloc_aligned) ( ArenaI
power of 2 >= word size, no need to align the alignment. Still,
we check. */
+ if (req_alignB == 4) req_alignB = 8;
req_alignW = req_alignB / VKI_BYTES_PER_WORD;
vg_assert(req_alignB == req_alignW * VKI_BYTES_PER_WORD);
/* Required payload size for the aligned chunk. */
- req_pszW = (req_pszB + VKI_BYTES_PER_WORD - 1) / VKI_BYTES_PER_WORD;
+ req_pszW = req_pszB_to_req_pszW(req_pszB);
/* Payload size to request for the big block that we will split
@@ -1278,5 +1308,7 @@ void* VG_(arena_malloc_aligned) ( ArenaI
VGP_POPCC(VgpMalloc);
- return align_p;
+ v = (void*)align_p;
+ vg_assert( (((UInt)v) % req_alignB) == 0 );
+ return v;
}
@@ -1296,5 +1328,5 @@ void* VG_(arena_calloc) ( ArenaId aid, I
vg_assert(size >= 0);
- if (alignB == 4)
+ if (alignB == 8)
p = VG_(arena_malloc) ( aid, size );
else
@@ -1339,5 +1371,5 @@ void* VG_(arena_realloc) ( ArenaId aid,
}
- if (req_alignB == 4)
+ if (req_alignB == 8)
p_new = VG_(arena_malloc) ( aid, req_pszB );
else
@@ -1373,10 +1405,10 @@ void VG_(free) ( void* ptr )
void* VG_(calloc) ( Int nmemb, Int nbytes )
{
- return VG_(arena_calloc) ( VG_AR_TOOL, /*alignment*/4, nmemb, nbytes );
+ return VG_(arena_calloc) ( VG_AR_TOOL, /*alignment*/8, nmemb, nbytes );
}
void* VG_(realloc) ( void* ptr, Int size )
{
- return VG_(arena_realloc) ( VG_AR_TOOL, ptr, /*alignment*/4, size );
+ return VG_(arena_realloc) ( VG_AR_TOOL, ptr, /*alignment*/8, size );
}
@@ -1389,6 +1421,6 @@ void* VG_(malloc_aligned) ( Int req_alig
void* VG_(cli_malloc) ( UInt align, Int nbytes )
{
- vg_assert(align >= 4);
- if (4 == align)
+ vg_assert(align >= 8);
+ if (8 == align)
return VG_(arena_malloc) ( VG_AR_CLIENT, nbytes );
else
|