diff options
| author | Paul Eggert | 2016-02-09 14:23:53 -0800 |
|---|---|---|
| committer | Paul Eggert | 2016-02-09 14:23:53 -0800 |
| commit | 05595c2e59983db469e620c4f34b2eef5123391b (patch) | |
| tree | 9c72fdb703ebbacb66a9ca08c7a3d4c5bef01049 /src/alloc.c | |
| parent | 8fa67e959bcc835c359981aae01f0dad3213451a (diff) | |
| parent | 821213572075b3f5a97676f48aeb6733bf437277 (diff) | |
| download | emacs-05595c2e59983db469e620c4f34b2eef5123391b.tar.gz emacs-05595c2e59983db469e620c4f34b2eef5123391b.zip | |
-
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 70 |
1 files changed, 64 insertions, 6 deletions
diff --git a/src/alloc.c b/src/alloc.c index 7364d7c4047..81cfdb011dc 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -819,8 +819,10 @@ malloc_unblock_input (void) | |||
| 819 | malloc_probe (size); \ | 819 | malloc_probe (size); \ |
| 820 | } while (0) | 820 | } while (0) |
| 821 | 821 | ||
| 822 | static void *lmalloc (size_t) ATTRIBUTE_MALLOC_SIZE ((1)); | ||
| 823 | static void *lrealloc (void *, size_t); | ||
| 822 | 824 | ||
| 823 | /* Like malloc but check for no memory and block interrupt input.. */ | 825 | /* Like malloc but check for no memory and block interrupt input. */ |
| 824 | 826 | ||
| 825 | void * | 827 | void * |
| 826 | xmalloc (size_t size) | 828 | xmalloc (size_t size) |
| @@ -828,7 +830,7 @@ xmalloc (size_t size) | |||
| 828 | void *val; | 830 | void *val; |
| 829 | 831 | ||
| 830 | MALLOC_BLOCK_INPUT; | 832 | MALLOC_BLOCK_INPUT; |
| 831 | val = malloc (size); | 833 | val = lmalloc (size); |
| 832 | MALLOC_UNBLOCK_INPUT; | 834 | MALLOC_UNBLOCK_INPUT; |
| 833 | 835 | ||
| 834 | if (!val && size) | 836 | if (!val && size) |
| @@ -845,7 +847,7 @@ xzalloc (size_t size) | |||
| 845 | void *val; | 847 | void *val; |
| 846 | 848 | ||
| 847 | MALLOC_BLOCK_INPUT; | 849 | MALLOC_BLOCK_INPUT; |
| 848 | val = malloc (size); | 850 | val = lmalloc (size); |
| 849 | MALLOC_UNBLOCK_INPUT; | 851 | MALLOC_UNBLOCK_INPUT; |
| 850 | 852 | ||
| 851 | if (!val && size) | 853 | if (!val && size) |
| @@ -866,9 +868,9 @@ xrealloc (void *block, size_t size) | |||
| 866 | /* We must call malloc explicitly when BLOCK is 0, since some | 868 | /* We must call malloc explicitly when BLOCK is 0, since some |
| 867 | reallocs don't do this. */ | 869 | reallocs don't do this. */ |
| 868 | if (! block) | 870 | if (! block) |
| 869 | val = malloc (size); | 871 | val = lmalloc (size); |
| 870 | else | 872 | else |
| 871 | val = realloc (block, size); | 873 | val = lrealloc (block, size); |
| 872 | MALLOC_UNBLOCK_INPUT; | 874 | MALLOC_UNBLOCK_INPUT; |
| 873 | 875 | ||
| 874 | if (!val && size) | 876 | if (!val && size) |
| @@ -1070,7 +1072,7 @@ lisp_malloc (size_t nbytes, enum mem_type type) | |||
| 1070 | allocated_mem_type = type; | 1072 | allocated_mem_type = type; |
| 1071 | #endif | 1073 | #endif |
| 1072 | 1074 | ||
| 1073 | val = malloc (nbytes); | 1075 | val = lmalloc (nbytes); |
| 1074 | 1076 | ||
| 1075 | #if ! USE_LSB_TAG | 1077 | #if ! USE_LSB_TAG |
| 1076 | /* If the memory just allocated cannot be addressed thru a Lisp | 1078 | /* If the memory just allocated cannot be addressed thru a Lisp |
| @@ -1364,6 +1366,62 @@ lisp_align_free (void *block) | |||
| 1364 | MALLOC_UNBLOCK_INPUT; | 1366 | MALLOC_UNBLOCK_INPUT; |
| 1365 | } | 1367 | } |
| 1366 | 1368 | ||
| 1369 | #if !defined __GNUC__ && !defined __alignof__ | ||
| 1370 | # define __alignof__(type) alignof (type) | ||
| 1371 | #endif | ||
| 1372 | |||
| 1373 | /* True if malloc returns a multiple of GCALIGNMENT. In practice this | ||
| 1374 | holds if __alignof__ (max_align_t) is a multiple. Use __alignof__ | ||
| 1375 | if available, as otherwise this check would fail with GCC x86. | ||
| 1376 | This is a macro, not an enum constant, for portability to HP-UX | ||
| 1377 | 10.20 cc and AIX 3.2.5 xlc. */ | ||
| 1378 | #define MALLOC_IS_GC_ALIGNED (__alignof__ (max_align_t) % GCALIGNMENT == 0) | ||
| 1379 | |||
| 1380 | /* True if P is suitably aligned for SIZE, where Lisp alignment may be | ||
| 1381 | needed if SIZE is Lisp-aligned. */ | ||
| 1382 | |||
| 1383 | static bool | ||
| 1384 | laligned (void *p, size_t size) | ||
| 1385 | { | ||
| 1386 | return (MALLOC_IS_GC_ALIGNED || size % GCALIGNMENT != 0 | ||
| 1387 | || (intptr_t) p % GCALIGNMENT == 0); | ||
| 1388 | } | ||
| 1389 | |||
| 1390 | /* Like malloc and realloc except that if SIZE is Lisp-aligned, make | ||
| 1391 | sure the result is too. */ | ||
| 1392 | |||
| 1393 | static void * | ||
| 1394 | lmalloc (size_t size) | ||
| 1395 | { | ||
| 1396 | #if USE_ALIGNED_ALLOC | ||
| 1397 | if (! MALLOC_IS_GC_ALIGNED) | ||
| 1398 | return aligned_alloc (GCALIGNMENT, size); | ||
| 1399 | #endif | ||
| 1400 | |||
| 1401 | void *p; | ||
| 1402 | while (true) | ||
| 1403 | { | ||
| 1404 | p = malloc (size); | ||
| 1405 | if (laligned (p, size)) | ||
| 1406 | break; | ||
| 1407 | free (p); | ||
| 1408 | } | ||
| 1409 | |||
| 1410 | eassert ((intptr_t) p % GCALIGNMENT == 0); | ||
| 1411 | return p; | ||
| 1412 | } | ||
| 1413 | |||
| 1414 | static void * | ||
| 1415 | lrealloc (void *p, size_t size) | ||
| 1416 | { | ||
| 1417 | do | ||
| 1418 | p = realloc (p, size); | ||
| 1419 | while (! laligned (p, size)); | ||
| 1420 | |||
| 1421 | eassert ((intptr_t) p % GCALIGNMENT == 0); | ||
| 1422 | return p; | ||
| 1423 | } | ||
| 1424 | |||
| 1367 | 1425 | ||
| 1368 | /*********************************************************************** | 1426 | /*********************************************************************** |
| 1369 | Interval Allocation | 1427 | Interval Allocation |