diff options
| author | Paul Eggert | 2020-01-18 13:18:27 -0800 |
|---|---|---|
| committer | Paul Eggert | 2020-01-18 13:21:20 -0800 |
| commit | b222e1aaf968b9c8da5313906ab7536a868020be (patch) | |
| tree | c03701e006abdc3b4bc842b34d6b7b0f0fe1669b /src/alloc.c | |
| parent | 447bb1313a6abc07776d93ee78cd976ab43856e5 (diff) | |
| download | emacs-b222e1aaf968b9c8da5313906ab7536a868020be.tar.gz emacs-b222e1aaf968b9c8da5313906ab7536a868020be.zip | |
Don’t assume sizeof (size_t) == 4 in allocators
This removes some old 32-bit assumptions in Emacs allocator tuning,
and improves performance of ‘make compile-always’ by about 7% on a
couple of 64-bit GNU/Linux platforms I tried it on. It should not
affect performance on 32-bit platforms.
* src/alloc.c (MALLOC_SIZE_NEAR): New macro.
(MALLOC_ALIGNMENT): New constant.
(INTERVAL_BLOCK_SIZE, SBLOCK_SIZE, STRING_BLOCK_SIZE): Use the new
macro. Make these enum constants since they need not be macros.
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 41 |
1 files changed, 30 insertions, 11 deletions
diff --git a/src/alloc.c b/src/alloc.c index 9dc6ef79e39..99d5ca149d5 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -104,6 +104,26 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 104 | #include "w32heap.h" /* for sbrk */ | 104 | #include "w32heap.h" /* for sbrk */ |
| 105 | #endif | 105 | #endif |
| 106 | 106 | ||
| 107 | /* MALLOC_SIZE_NEAR (N) is a good number to pass to malloc when | ||
| 108 | allocating a block of memory with size close to N bytes. | ||
| 109 | For best results N should be a power of 2. | ||
| 110 | |||
| 111 | When calculating how much memory to allocate, GNU malloc (SIZE) | ||
| 112 | adds sizeof (size_t) to SIZE for internal overhead, and then rounds | ||
| 113 | up to a multiple of MALLOC_ALIGNMENT. Emacs can improve | ||
| 114 | performance a bit on GNU platforms by arranging for the resulting | ||
| 115 | size to be a power of two. This heuristic is good for glibc 2.0 | ||
| 116 | (1997) through at least glibc 2.31 (2020), and does not affect | ||
| 117 | correctness on other platforms. */ | ||
| 118 | |||
| 119 | #define MALLOC_SIZE_NEAR(n) \ | ||
| 120 | (ROUNDUP (max (n, sizeof (size_t)), MALLOC_ALIGNMENT) - sizeof (size_t)) | ||
| 121 | #ifdef __i386 | ||
| 122 | enum { MALLOC_ALIGNMENT = 16 }; | ||
| 123 | #else | ||
| 124 | enum { MALLOC_ALIGNMENT = max (2 * sizeof (size_t), alignof (long double)) }; | ||
| 125 | #endif | ||
| 126 | |||
| 107 | #ifdef DOUG_LEA_MALLOC | 127 | #ifdef DOUG_LEA_MALLOC |
| 108 | 128 | ||
| 109 | /* Specify maximum number of areas to mmap. It would be nice to use a | 129 | /* Specify maximum number of areas to mmap. It would be nice to use a |
| @@ -1332,11 +1352,11 @@ lrealloc (void *p, size_t size) | |||
| 1332 | Interval Allocation | 1352 | Interval Allocation |
| 1333 | ***********************************************************************/ | 1353 | ***********************************************************************/ |
| 1334 | 1354 | ||
| 1335 | /* Number of intervals allocated in an interval_block structure. | 1355 | /* Number of intervals allocated in an interval_block structure. */ |
| 1336 | The 1020 is 1024 minus malloc overhead. */ | ||
| 1337 | 1356 | ||
| 1338 | #define INTERVAL_BLOCK_SIZE \ | 1357 | enum { INTERVAL_BLOCK_SIZE |
| 1339 | ((1020 - sizeof (struct interval_block *)) / sizeof (struct interval)) | 1358 | = ((MALLOC_SIZE_NEAR (1024) - sizeof (struct interval_block *)) |
| 1359 | / sizeof (struct interval)) }; | ||
| 1340 | 1360 | ||
| 1341 | /* Intervals are allocated in chunks in the form of an interval_block | 1361 | /* Intervals are allocated in chunks in the form of an interval_block |
| 1342 | structure. */ | 1362 | structure. */ |
| @@ -1448,10 +1468,9 @@ mark_interval_tree (INTERVAL i) | |||
| 1448 | longer used, can be easily recognized, and it's easy to compact the | 1468 | longer used, can be easily recognized, and it's easy to compact the |
| 1449 | sblocks of small strings which we do in compact_small_strings. */ | 1469 | sblocks of small strings which we do in compact_small_strings. */ |
| 1450 | 1470 | ||
| 1451 | /* Size in bytes of an sblock structure used for small strings. This | 1471 | /* Size in bytes of an sblock structure used for small strings. */ |
| 1452 | is 8192 minus malloc overhead. */ | ||
| 1453 | 1472 | ||
| 1454 | #define SBLOCK_SIZE 8188 | 1473 | enum { SBLOCK_SIZE = MALLOC_SIZE_NEAR (8192) }; |
| 1455 | 1474 | ||
| 1456 | /* Strings larger than this are considered large strings. String data | 1475 | /* Strings larger than this are considered large strings. String data |
| 1457 | for large strings is allocated from individual sblocks. */ | 1476 | for large strings is allocated from individual sblocks. */ |
| @@ -1526,11 +1545,11 @@ struct sblock | |||
| 1526 | sdata data[FLEXIBLE_ARRAY_MEMBER]; | 1545 | sdata data[FLEXIBLE_ARRAY_MEMBER]; |
| 1527 | }; | 1546 | }; |
| 1528 | 1547 | ||
| 1529 | /* Number of Lisp strings in a string_block structure. The 1020 is | 1548 | /* Number of Lisp strings in a string_block structure. */ |
| 1530 | 1024 minus malloc overhead. */ | ||
| 1531 | 1549 | ||
| 1532 | #define STRING_BLOCK_SIZE \ | 1550 | enum { STRING_BLOCK_SIZE |
| 1533 | ((1020 - sizeof (struct string_block *)) / sizeof (struct Lisp_String)) | 1551 | = ((MALLOC_SIZE_NEAR (1024) - sizeof (struct string_block *)) |
| 1552 | / sizeof (struct Lisp_String)) }; | ||
| 1534 | 1553 | ||
| 1535 | /* Structure describing a block from which Lisp_String structures | 1554 | /* Structure describing a block from which Lisp_String structures |
| 1536 | are allocated. */ | 1555 | are allocated. */ |