644 |
|
|
645 |
/* BLOCK_ALIGN has to be a power of 2. */ |
/* BLOCK_ALIGN has to be a power of 2. */ |
646 |
#define BLOCK_ALIGN (1 << 10) |
#define BLOCK_ALIGN (1 << 10) |
|
#define BLOCK_BYTES \ |
|
|
(BLOCK_ALIGN - sizeof (struct alinged_block *) - ABLOCKS_PADDING) |
|
|
|
|
|
/* Internal data structures and constants. */ |
|
647 |
|
|
648 |
/* Padding to leave at the end of a malloc'd block. This is to give |
/* Padding to leave at the end of a malloc'd block. This is to give |
649 |
malloc a chance to minimize the amount of memory wasted to alignment. |
malloc a chance to minimize the amount of memory wasted to alignment. |
650 |
It should be tuned to the particular malloc library used. |
It should be tuned to the particular malloc library used. |
651 |
The current setting is based on glibc-2.3.2. */ |
On glibc-2.3.2, malloc never tries to align, so a padding of 0 is best. |
652 |
#define ABLOCKS_PADDING 0 |
posix_memalign on the other hand would ideally prefer a value of 4 |
653 |
|
because otherwise, there's 1020 bytes wasted between each ablocks. |
654 |
|
But testing shows that those 1020 will most of the time be efficiently |
655 |
|
used by malloc to place other objects, so a value of 0 is still preferable |
656 |
|
unless you have a lot of cons&floats and virtually nothing else. */ |
657 |
|
#define BLOCK_PADDING 0 |
658 |
|
#define BLOCK_BYTES \ |
659 |
|
(BLOCK_ALIGN - sizeof (struct aligned_block *) - BLOCK_PADDING) |
660 |
|
|
661 |
|
/* Internal data structures and constants. */ |
662 |
|
|
663 |
#define ABLOCKS_SIZE 16 |
#define ABLOCKS_SIZE 16 |
664 |
|
|
665 |
/* An aligned block of memory. */ |
/* An aligned block of memory. */ |
682 |
struct ablocks *abase; |
struct ablocks *abase; |
683 |
/* The padding of all but the last ablock is unused. The padding of |
/* The padding of all but the last ablock is unused. The padding of |
684 |
the last ablock in an ablocks is not allocated. */ |
the last ablock in an ablocks is not allocated. */ |
685 |
#if ABLOCKS_PADDING |
#if BLOCK_PADDING |
686 |
char padding[ABLOCKS_PADDING]; |
char padding[BLOCK_PADDING]; |
687 |
#endif |
#endif |
688 |
}; |
}; |
689 |
|
|
694 |
}; |
}; |
695 |
|
|
696 |
/* Size of the block requested from malloc or memalign. */ |
/* Size of the block requested from malloc or memalign. */ |
697 |
#define ABLOCKS_BYTES (sizeof (struct ablocks) - ABLOCKS_PADDING) |
#define ABLOCKS_BYTES (sizeof (struct ablocks) - BLOCK_PADDING) |
698 |
|
|
699 |
#define ABLOCK_ABASE(block) \ |
#define ABLOCK_ABASE(block) \ |
700 |
(((unsigned long) (block)->abase) <= (1 + 2 * ABLOCKS_SIZE) \ |
(((unsigned long) (block)->abase) <= (1 + 2 * ABLOCKS_SIZE) \ |
705 |
#define ABLOCKS_BUSY(abase) ((abase)->blocks[0].abase) |
#define ABLOCKS_BUSY(abase) ((abase)->blocks[0].abase) |
706 |
|
|
707 |
/* Pointer to the (not necessarily aligned) malloc block. */ |
/* Pointer to the (not necessarily aligned) malloc block. */ |
708 |
|
#ifdef HAVE_POSIX_MEMALIGN |
709 |
|
#define ABLOCKS_BASE(abase) (abase) |
710 |
|
#else |
711 |
#define ABLOCKS_BASE(abase) \ |
#define ABLOCKS_BASE(abase) \ |
712 |
(1 & (int) ABLOCKS_BUSY (abase) ? abase : ((void**)abase)[-1]) |
(1 & (int) ABLOCKS_BUSY (abase) ? abase : ((void**)abase)[-1]) |
713 |
|
#endif |
714 |
|
|
715 |
/* The list of free ablock. */ |
/* The list of free ablock. */ |
716 |
static struct ablock *free_ablock; |
static struct ablock *free_ablock; |
745 |
mallopt (M_MMAP_MAX, 0); |
mallopt (M_MMAP_MAX, 0); |
746 |
#endif |
#endif |
747 |
|
|
748 |
|
#ifdef HAVE_POSIX_MEMALIGN |
749 |
|
{ |
750 |
|
int err = posix_memalign (&base, BLOCK_ALIGN, ABLOCKS_BYTES); |
751 |
|
abase = err ? (base = NULL) : base; |
752 |
|
} |
753 |
|
#else |
754 |
base = malloc (ABLOCKS_BYTES); |
base = malloc (ABLOCKS_BYTES); |
755 |
abase = ALIGN (base, BLOCK_ALIGN); |
abase = ALIGN (base, BLOCK_ALIGN); |
756 |
|
#endif |
757 |
|
|
758 |
aligned = (base == abase); |
aligned = (base == abase); |
759 |
if (!aligned) |
if (!aligned) |
774 |
} |
} |
775 |
ABLOCKS_BUSY (abase) = (struct ablocks *) aligned; |
ABLOCKS_BUSY (abase) = (struct ablocks *) aligned; |
776 |
|
|
777 |
|
eassert (0 == ((EMACS_UINT)abase) % BLOCK_ALIGN); |
778 |
eassert (ABLOCK_ABASE (&abase->blocks[3]) == abase); /* 3 is arbitrary */ |
eassert (ABLOCK_ABASE (&abase->blocks[3]) == abase); /* 3 is arbitrary */ |
779 |
eassert (ABLOCK_ABASE (&abase->blocks[0]) == abase); |
eassert (ABLOCK_ABASE (&abase->blocks[0]) == abase); |
780 |
eassert (ABLOCKS_BASE (abase) == base); |
eassert (ABLOCKS_BASE (abase) == base); |
1329 |
/* Number of Lisp strings in a string_block structure. The 1020 is |
/* Number of Lisp strings in a string_block structure. The 1020 is |
1330 |
1024 minus malloc overhead. */ |
1024 minus malloc overhead. */ |
1331 |
|
|
1332 |
#define STRINGS_IN_STRING_BLOCK \ |
#define STRING_BLOCK_SIZE \ |
1333 |
((1020 - sizeof (struct string_block *)) / sizeof (struct Lisp_String)) |
((1020 - sizeof (struct string_block *)) / sizeof (struct Lisp_String)) |
1334 |
|
|
1335 |
/* Structure describing a block from which Lisp_String structures |
/* Structure describing a block from which Lisp_String structures |
1338 |
struct string_block |
struct string_block |
1339 |
{ |
{ |
1340 |
struct string_block *next; |
struct string_block *next; |
1341 |
struct Lisp_String strings[STRINGS_IN_STRING_BLOCK]; |
struct Lisp_String strings[STRING_BLOCK_SIZE]; |
1342 |
}; |
}; |
1343 |
|
|
1344 |
/* Head and tail of the list of sblock structures holding Lisp string |
/* Head and tail of the list of sblock structures holding Lisp string |
1533 |
string_blocks = b; |
string_blocks = b; |
1534 |
++n_string_blocks; |
++n_string_blocks; |
1535 |
|
|
1536 |
for (i = STRINGS_IN_STRING_BLOCK - 1; i >= 0; --i) |
for (i = STRING_BLOCK_SIZE - 1; i >= 0; --i) |
1537 |
{ |
{ |
1538 |
s = b->strings + i; |
s = b->strings + i; |
1539 |
NEXT_FREE_LISP_STRING (s) = string_free_list; |
NEXT_FREE_LISP_STRING (s) = string_free_list; |
1540 |
string_free_list = s; |
string_free_list = s; |
1541 |
} |
} |
1542 |
|
|
1543 |
total_free_strings += STRINGS_IN_STRING_BLOCK; |
total_free_strings += STRING_BLOCK_SIZE; |
1544 |
} |
} |
1545 |
|
|
1546 |
/* Pop a Lisp_String off the free-list. */ |
/* Pop a Lisp_String off the free-list. */ |
1691 |
|
|
1692 |
next = b->next; |
next = b->next; |
1693 |
|
|
1694 |
for (i = 0; i < STRINGS_IN_STRING_BLOCK; ++i) |
for (i = 0; i < STRING_BLOCK_SIZE; ++i) |
1695 |
{ |
{ |
1696 |
struct Lisp_String *s = b->strings + i; |
struct Lisp_String *s = b->strings + i; |
1697 |
|
|
1746 |
|
|
1747 |
/* Free blocks that contain free Lisp_Strings only, except |
/* Free blocks that contain free Lisp_Strings only, except |
1748 |
the first two of them. */ |
the first two of them. */ |
1749 |
if (nfree == STRINGS_IN_STRING_BLOCK |
if (nfree == STRING_BLOCK_SIZE |
1750 |
&& total_free_strings > STRINGS_IN_STRING_BLOCK) |
&& total_free_strings > STRING_BLOCK_SIZE) |
1751 |
{ |
{ |
1752 |
lisp_free (b); |
lisp_free (b); |
1753 |
--n_string_blocks; |
--n_string_blocks; |