diff options
Diffstat (limited to 'src/gmalloc.c')
| -rw-r--r-- | src/gmalloc.c | 64 |
1 files changed, 61 insertions, 3 deletions
diff --git a/src/gmalloc.c b/src/gmalloc.c index fa4aa1fdf6a..d49259b8ed7 100644 --- a/src/gmalloc.c +++ b/src/gmalloc.c | |||
| @@ -37,7 +37,7 @@ Fifth Floor, Boston, MA 02110-1301, USA. | |||
| 37 | #include <config.h> | 37 | #include <config.h> |
| 38 | #endif | 38 | #endif |
| 39 | 39 | ||
| 40 | #ifdef HAVE_GTK_AND_PTHREAD | 40 | #ifdef HAVE_PTHREAD |
| 41 | #define USE_PTHREAD | 41 | #define USE_PTHREAD |
| 42 | #endif | 42 | #endif |
| 43 | 43 | ||
| @@ -351,10 +351,21 @@ Fifth Floor, Boston, MA 02110-1301, USA. | |||
| 351 | #endif | 351 | #endif |
| 352 | #include <errno.h> | 352 | #include <errno.h> |
| 353 | 353 | ||
| 354 | /* How to really get more memory. */ | 354 | /* On Cygwin there are two heaps. temacs uses the static heap |
| 355 | #if defined(CYGWIN) | 355 | (defined in sheap.c and managed with bss_sbrk), and the dumped |
| 356 | emacs uses the Cygwin heap (managed with sbrk). When emacs starts | ||
| 357 | on Cygwin, it reinitializes malloc, and we save the old info for | ||
| 358 | use by free and realloc if they're called with a pointer into the | ||
| 359 | static heap. | ||
| 360 | |||
| 361 | Currently (2011-08-16) the Cygwin build doesn't use ralloc.c; if | ||
| 362 | this is changed in the future, we'll have to similarly deal with | ||
| 363 | reinitializing ralloc. */ | ||
| 364 | #ifdef CYGWIN | ||
| 356 | extern __ptr_t bss_sbrk PP ((ptrdiff_t __size)); | 365 | extern __ptr_t bss_sbrk PP ((ptrdiff_t __size)); |
| 357 | extern int bss_sbrk_did_unexec; | 366 | extern int bss_sbrk_did_unexec; |
| 367 | char *bss_sbrk_heapbase; /* _heapbase for static heap */ | ||
| 368 | malloc_info *bss_sbrk_heapinfo; /* _heapinfo for static heap */ | ||
| 358 | #endif | 369 | #endif |
| 359 | __ptr_t (*__morecore) PP ((__malloc_ptrdiff_t __size)) = __default_morecore; | 370 | __ptr_t (*__morecore) PP ((__malloc_ptrdiff_t __size)) = __default_morecore; |
| 360 | 371 | ||
| @@ -584,6 +595,16 @@ malloc_initialize_1 () | |||
| 584 | mcheck (NULL); | 595 | mcheck (NULL); |
| 585 | #endif | 596 | #endif |
| 586 | 597 | ||
| 598 | #ifdef CYGWIN | ||
| 599 | if (bss_sbrk_did_unexec) | ||
| 600 | /* we're reinitializing the dumped emacs */ | ||
| 601 | { | ||
| 602 | bss_sbrk_heapbase = _heapbase; | ||
| 603 | bss_sbrk_heapinfo = _heapinfo; | ||
| 604 | memset (_fraghead, 0, BLOCKLOG * sizeof (struct list)); | ||
| 605 | } | ||
| 606 | #endif | ||
| 607 | |||
| 587 | if (__malloc_initialize_hook) | 608 | if (__malloc_initialize_hook) |
| 588 | (*__malloc_initialize_hook) (); | 609 | (*__malloc_initialize_hook) (); |
| 589 | 610 | ||
| @@ -1054,6 +1075,12 @@ _free_internal_nolock (ptr) | |||
| 1054 | if (ptr == NULL) | 1075 | if (ptr == NULL) |
| 1055 | return; | 1076 | return; |
| 1056 | 1077 | ||
| 1078 | #ifdef CYGWIN | ||
| 1079 | if (ptr < _heapbase) | ||
| 1080 | /* We're being asked to free something in the static heap. */ | ||
| 1081 | return; | ||
| 1082 | #endif | ||
| 1083 | |||
| 1057 | PROTECT_MALLOC_STATE (0); | 1084 | PROTECT_MALLOC_STATE (0); |
| 1058 | 1085 | ||
| 1059 | LOCK_ALIGNED_BLOCKS (); | 1086 | LOCK_ALIGNED_BLOCKS (); |
| @@ -1349,6 +1376,31 @@ Fifth Floor, Boston, MA 02110-1301, USA. | |||
| 1349 | 1376 | ||
| 1350 | #define min(A, B) ((A) < (B) ? (A) : (B)) | 1377 | #define min(A, B) ((A) < (B) ? (A) : (B)) |
| 1351 | 1378 | ||
| 1379 | /* On Cygwin the dumped emacs may try to realloc storage allocated in | ||
| 1380 | the static heap. We just malloc space in the new heap and copy the | ||
| 1381 | data. */ | ||
| 1382 | #ifdef CYGWIN | ||
| 1383 | __ptr_t | ||
| 1384 | special_realloc (ptr, size) | ||
| 1385 | __ptr_t ptr; | ||
| 1386 | __malloc_size_t size; | ||
| 1387 | { | ||
| 1388 | __ptr_t result; | ||
| 1389 | int type; | ||
| 1390 | __malloc_size_t block, oldsize; | ||
| 1391 | |||
| 1392 | block = ((char *) ptr - bss_sbrk_heapbase) / BLOCKSIZE + 1; | ||
| 1393 | type = bss_sbrk_heapinfo[block].busy.type; | ||
| 1394 | oldsize = | ||
| 1395 | type == 0 ? bss_sbrk_heapinfo[block].busy.info.size * BLOCKSIZE | ||
| 1396 | : (__malloc_size_t) 1 << type; | ||
| 1397 | result = _malloc_internal_nolock (size); | ||
| 1398 | if (result != NULL) | ||
| 1399 | memcpy (result, ptr, min (oldsize, size)); | ||
| 1400 | return result; | ||
| 1401 | } | ||
| 1402 | #endif | ||
| 1403 | |||
| 1352 | /* Debugging hook for realloc. */ | 1404 | /* Debugging hook for realloc. */ |
| 1353 | __ptr_t (*__realloc_hook) PP ((__ptr_t __ptr, __malloc_size_t __size)); | 1405 | __ptr_t (*__realloc_hook) PP ((__ptr_t __ptr, __malloc_size_t __size)); |
| 1354 | 1406 | ||
| @@ -1375,6 +1427,12 @@ _realloc_internal_nolock (ptr, size) | |||
| 1375 | else if (ptr == NULL) | 1427 | else if (ptr == NULL) |
| 1376 | return _malloc_internal_nolock (size); | 1428 | return _malloc_internal_nolock (size); |
| 1377 | 1429 | ||
| 1430 | #ifdef CYGWIN | ||
| 1431 | if (ptr < _heapbase) | ||
| 1432 | /* ptr points into the static heap */ | ||
| 1433 | return special_realloc (ptr, size); | ||
| 1434 | #endif | ||
| 1435 | |||
| 1378 | block = BLOCK (ptr); | 1436 | block = BLOCK (ptr); |
| 1379 | 1437 | ||
| 1380 | PROTECT_MALLOC_STATE (0); | 1438 | PROTECT_MALLOC_STATE (0); |