diff options
| author | Paul Eggert | 2016-02-08 11:38:35 -0800 |
|---|---|---|
| committer | Paul Eggert | 2016-02-08 11:39:54 -0800 |
| commit | 463a8eae61ef3d5ae98452f4ee133c1f9b957462 (patch) | |
| tree | b4924ccade6bc82f34727eb86fd3256fa04749ec /src | |
| parent | 37eae51767fc013eec3411c174d27bd8a18e5bc8 (diff) | |
| download | emacs-463a8eae61ef3d5ae98452f4ee133c1f9b957462.tar.gz emacs-463a8eae61ef3d5ae98452f4ee133c1f9b957462.zip | |
Port to FreeBSD 11-CURRENT i386
Problem reported by Herbert J. Skuhra in:
http://lists.gnu.org/archive/html/emacs-devel/2016-02/msg00354.html
Instead of trying
* src/alloc.c (lmalloc, lrealloc, laligned): New functions.
(xmalloc, xzalloc, xrealloc, lisp_malloc): Use them.
(__alignof__) [!__GNUC__ && !__alignof__]: New macro.
(MALLOC_IS_GC_ALIGNED): New macro.
* src/lisp.h (NONPOINTER_BITS): Remove. All uses removed.
No longer needed now that alloc.c uses lmalloc and lrealloc.
Diffstat (limited to 'src')
| -rw-r--r-- | src/alloc.c | 70 | ||||
| -rw-r--r-- | src/lisp.h | 19 |
2 files changed, 66 insertions, 23 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 |
diff --git a/src/lisp.h b/src/lisp.h index 82cbca8e6ba..e8eab7be9eb 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -67,19 +67,6 @@ DEFINE_GDB_SYMBOL_BEGIN (int, GCTYPEBITS) | |||
| 67 | #define GCTYPEBITS 3 | 67 | #define GCTYPEBITS 3 |
| 68 | DEFINE_GDB_SYMBOL_END (GCTYPEBITS) | 68 | DEFINE_GDB_SYMBOL_END (GCTYPEBITS) |
| 69 | 69 | ||
| 70 | /* The number of bits needed in an EMACS_INT over and above the number | ||
| 71 | of bits in a pointer. This is 0 on systems where: | ||
| 72 | 1. We can specify multiple-of-8 alignment on static variables. | ||
| 73 | 2. We know malloc returns a multiple of 8. */ | ||
| 74 | #if (defined alignas \ | ||
| 75 | && (defined GNU_MALLOC || defined DOUG_LEA_MALLOC || defined __GLIBC__ \ | ||
| 76 | || defined DARWIN_OS || defined __sun || defined __MINGW32__ \ | ||
| 77 | || defined CYGWIN)) | ||
| 78 | # define NONPOINTER_BITS 0 | ||
| 79 | #else | ||
| 80 | # define NONPOINTER_BITS GCTYPEBITS | ||
| 81 | #endif | ||
| 82 | |||
| 83 | /* EMACS_INT - signed integer wide enough to hold an Emacs value | 70 | /* EMACS_INT - signed integer wide enough to hold an Emacs value |
| 84 | EMACS_INT_MAX - maximum value of EMACS_INT; can be used in #if | 71 | EMACS_INT_MAX - maximum value of EMACS_INT; can be used in #if |
| 85 | pI - printf length modifier for EMACS_INT | 72 | pI - printf length modifier for EMACS_INT |
| @@ -87,18 +74,16 @@ DEFINE_GDB_SYMBOL_END (GCTYPEBITS) | |||
| 87 | #ifndef EMACS_INT_MAX | 74 | #ifndef EMACS_INT_MAX |
| 88 | # if INTPTR_MAX <= 0 | 75 | # if INTPTR_MAX <= 0 |
| 89 | # error "INTPTR_MAX misconfigured" | 76 | # error "INTPTR_MAX misconfigured" |
| 90 | # elif INTPTR_MAX <= INT_MAX >> NONPOINTER_BITS && !defined WIDE_EMACS_INT | 77 | # elif INTPTR_MAX <= INT_MAX && !defined WIDE_EMACS_INT |
| 91 | typedef int EMACS_INT; | 78 | typedef int EMACS_INT; |
| 92 | typedef unsigned int EMACS_UINT; | 79 | typedef unsigned int EMACS_UINT; |
| 93 | # define EMACS_INT_MAX INT_MAX | 80 | # define EMACS_INT_MAX INT_MAX |
| 94 | # define pI "" | 81 | # define pI "" |
| 95 | # elif INTPTR_MAX <= LONG_MAX >> NONPOINTER_BITS && !defined WIDE_EMACS_INT | 82 | # elif INTPTR_MAX <= LONG_MAX && !defined WIDE_EMACS_INT |
| 96 | typedef long int EMACS_INT; | 83 | typedef long int EMACS_INT; |
| 97 | typedef unsigned long EMACS_UINT; | 84 | typedef unsigned long EMACS_UINT; |
| 98 | # define EMACS_INT_MAX LONG_MAX | 85 | # define EMACS_INT_MAX LONG_MAX |
| 99 | # define pI "l" | 86 | # define pI "l" |
| 100 | /* Check versus LLONG_MAX, not LLONG_MAX >> NONPOINTER_BITS. | ||
| 101 | In theory this is not safe, but in practice it seems to be OK. */ | ||
| 102 | # elif INTPTR_MAX <= LLONG_MAX | 87 | # elif INTPTR_MAX <= LLONG_MAX |
| 103 | typedef long long int EMACS_INT; | 88 | typedef long long int EMACS_INT; |
| 104 | typedef unsigned long long int EMACS_UINT; | 89 | typedef unsigned long long int EMACS_UINT; |