diff options
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 6c6c1aade8e..8816411bcaf 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -802,8 +802,10 @@ malloc_unblock_input (void) | |||
| 802 | malloc_probe (size); \ | 802 | malloc_probe (size); \ |
| 803 | } while (0) | 803 | } while (0) |
| 804 | 804 | ||
| 805 | static void *lmalloc (size_t) ATTRIBUTE_MALLOC_SIZE ((1)); | ||
| 806 | static void *lrealloc (void *, size_t); | ||
| 805 | 807 | ||
| 806 | /* Like malloc but check for no memory and block interrupt input.. */ | 808 | /* Like malloc but check for no memory and block interrupt input. */ |
| 807 | 809 | ||
| 808 | void * | 810 | void * |
| 809 | xmalloc (size_t size) | 811 | xmalloc (size_t size) |
| @@ -811,7 +813,7 @@ xmalloc (size_t size) | |||
| 811 | void *val; | 813 | void *val; |
| 812 | 814 | ||
| 813 | MALLOC_BLOCK_INPUT; | 815 | MALLOC_BLOCK_INPUT; |
| 814 | val = malloc (size); | 816 | val = lmalloc (size); |
| 815 | MALLOC_UNBLOCK_INPUT; | 817 | MALLOC_UNBLOCK_INPUT; |
| 816 | 818 | ||
| 817 | if (!val && size) | 819 | if (!val && size) |
| @@ -828,7 +830,7 @@ xzalloc (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) |
| @@ -849,9 +851,9 @@ xrealloc (void *block, size_t size) | |||
| 849 | /* We must call malloc explicitly when BLOCK is 0, since some | 851 | /* We must call malloc explicitly when BLOCK is 0, since some |
| 850 | reallocs don't do this. */ | 852 | reallocs don't do this. */ |
| 851 | if (! block) | 853 | if (! block) |
| 852 | val = malloc (size); | 854 | val = lmalloc (size); |
| 853 | else | 855 | else |
| 854 | val = realloc (block, size); | 856 | val = lrealloc (block, size); |
| 855 | MALLOC_UNBLOCK_INPUT; | 857 | MALLOC_UNBLOCK_INPUT; |
| 856 | 858 | ||
| 857 | if (!val && size) | 859 | if (!val && size) |
| @@ -1053,7 +1055,7 @@ lisp_malloc (size_t nbytes, enum mem_type type) | |||
| 1053 | allocated_mem_type = type; | 1055 | allocated_mem_type = type; |
| 1054 | #endif | 1056 | #endif |
| 1055 | 1057 | ||
| 1056 | val = malloc (nbytes); | 1058 | val = lmalloc (nbytes); |
| 1057 | 1059 | ||
| 1058 | #if ! USE_LSB_TAG | 1060 | #if ! USE_LSB_TAG |
| 1059 | /* If the memory just allocated cannot be addressed thru a Lisp | 1061 | /* If the memory just allocated cannot be addressed thru a Lisp |
| @@ -1356,6 +1358,62 @@ lisp_align_free (void *block) | |||
| 1356 | MALLOC_UNBLOCK_INPUT; | 1358 | MALLOC_UNBLOCK_INPUT; |
| 1357 | } | 1359 | } |
| 1358 | 1360 | ||
| 1361 | #if !defined __GNUC__ && !defined __alignof__ | ||
| 1362 | # define __alignof__(type) alignof (type) | ||
| 1363 | #endif | ||
| 1364 | |||
| 1365 | /* True if malloc returns a multiple of GCALIGNMENT. In practice this | ||
| 1366 | holds if __alignof__ (max_align_t) is a multiple. Use __alignof__ | ||
| 1367 | if available, as otherwise this check would fail with GCC x86. | ||
| 1368 | This is a macro, not an enum constant, for portability to HP-UX | ||
| 1369 | 10.20 cc and AIX 3.2.5 xlc. */ | ||
| 1370 | #define MALLOC_IS_GC_ALIGNED (__alignof__ (max_align_t) % GCALIGNMENT == 0) | ||
| 1371 | |||
| 1372 | /* True if P is suitably aligned for SIZE, where Lisp alignment may be | ||
| 1373 | needed if SIZE is Lisp-aligned. */ | ||
| 1374 | |||
| 1375 | static bool | ||
| 1376 | laligned (void *p, size_t size) | ||
| 1377 | { | ||
| 1378 | return (MALLOC_IS_GC_ALIGNED || size % GCALIGNMENT != 0 | ||
| 1379 | || (intptr_t) p % GCALIGNMENT == 0); | ||
| 1380 | } | ||
| 1381 | |||
| 1382 | /* Like malloc and realloc except that if SIZE is Lisp-aligned, make | ||
| 1383 | sure the result is too. */ | ||
| 1384 | |||
| 1385 | static void * | ||
| 1386 | lmalloc (size_t size) | ||
| 1387 | { | ||
| 1388 | #if USE_ALIGNED_ALLOC | ||
| 1389 | if (! MALLOC_IS_GC_ALIGNED) | ||
| 1390 | return aligned_alloc (GCALIGNMENT, size); | ||
| 1391 | #endif | ||
| 1392 | |||
| 1393 | void *p; | ||
| 1394 | while (true) | ||
| 1395 | { | ||
| 1396 | p = malloc (size); | ||
| 1397 | if (laligned (p, size)) | ||
| 1398 | break; | ||
| 1399 | free (p); | ||
| 1400 | } | ||
| 1401 | |||
| 1402 | eassert ((intptr_t) p % GCALIGNMENT == 0); | ||
| 1403 | return p; | ||
| 1404 | } | ||
| 1405 | |||
| 1406 | static void * | ||
| 1407 | lrealloc (void *p, size_t size) | ||
| 1408 | { | ||
| 1409 | do | ||
| 1410 | p = realloc (p, size); | ||
| 1411 | while (! laligned (p, size)); | ||
| 1412 | |||
| 1413 | eassert ((intptr_t) p % GCALIGNMENT == 0); | ||
| 1414 | return p; | ||
| 1415 | } | ||
| 1416 | |||
| 1359 | 1417 | ||
| 1360 | /*********************************************************************** | 1418 | /*********************************************************************** |
| 1361 | Interval Allocation | 1419 | Interval Allocation |