diff options
| author | Bill Wohler | 2012-11-24 19:43:02 -0800 |
|---|---|---|
| committer | Bill Wohler | 2012-11-24 19:43:02 -0800 |
| commit | 5244bc019bf7376caff3bb198ff674e0ad9fb0e6 (patch) | |
| tree | 02ee1615e904771f692ec2957c79a08ae029a13d /src/ralloc.c | |
| parent | 9f7e719509474e92f85955e22e57ffeebd4e96f3 (diff) | |
| parent | c07a6ded1df2f4156badc9add2953579622c3722 (diff) | |
| download | emacs-5244bc019bf7376caff3bb198ff674e0ad9fb0e6.tar.gz emacs-5244bc019bf7376caff3bb198ff674e0ad9fb0e6.zip | |
Merge from trunk.
Diffstat (limited to 'src/ralloc.c')
| -rw-r--r-- | src/ralloc.c | 234 |
1 files changed, 107 insertions, 127 deletions
diff --git a/src/ralloc.c b/src/ralloc.c index 62189ad8fc7..e5bf76b0e6d 100644 --- a/src/ralloc.c +++ b/src/ralloc.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Block-relocating memory allocator. | 1 | /* Block-relocating memory allocator. |
| 2 | Copyright (C) 1993, 1995, 2000-2011 Free Software Foundation, Inc. | 2 | Copyright (C) 1993, 1995, 2000-2012 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
| @@ -25,15 +25,12 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 25 | #ifdef emacs | 25 | #ifdef emacs |
| 26 | 26 | ||
| 27 | #include <config.h> | 27 | #include <config.h> |
| 28 | #include <setjmp.h> | 28 | |
| 29 | #include "lisp.h" /* Needed for VALBITS. */ | 29 | #include "lisp.h" /* Needed for VALBITS. */ |
| 30 | #include "blockinput.h" | 30 | #include "blockinput.h" |
| 31 | 31 | ||
| 32 | #include <unistd.h> | 32 | #include <unistd.h> |
| 33 | 33 | ||
| 34 | typedef POINTER_TYPE *POINTER; | ||
| 35 | typedef size_t SIZE; | ||
| 36 | |||
| 37 | #ifdef DOUG_LEA_MALLOC | 34 | #ifdef DOUG_LEA_MALLOC |
| 38 | #define M_TOP_PAD -2 | 35 | #define M_TOP_PAD -2 |
| 39 | extern int mallopt (int, int); | 36 | extern int mallopt (int, int); |
| @@ -47,9 +44,6 @@ extern size_t __malloc_extra_blocks; | |||
| 47 | 44 | ||
| 48 | #include <stddef.h> | 45 | #include <stddef.h> |
| 49 | 46 | ||
| 50 | typedef size_t SIZE; | ||
| 51 | typedef void *POINTER; | ||
| 52 | |||
| 53 | #include <unistd.h> | 47 | #include <unistd.h> |
| 54 | #include <malloc.h> | 48 | #include <malloc.h> |
| 55 | 49 | ||
| @@ -58,6 +52,8 @@ typedef void *POINTER; | |||
| 58 | 52 | ||
| 59 | #include "getpagesize.h" | 53 | #include "getpagesize.h" |
| 60 | 54 | ||
| 55 | typedef size_t SIZE; | ||
| 56 | typedef void *POINTER; | ||
| 61 | #define NIL ((POINTER) 0) | 57 | #define NIL ((POINTER) 0) |
| 62 | 58 | ||
| 63 | /* A flag to indicate whether we have initialized ralloc yet. For | 59 | /* A flag to indicate whether we have initialized ralloc yet. For |
| @@ -76,7 +72,7 @@ static void r_alloc_init (void); | |||
| 76 | /* Declarations for working with the malloc, ralloc, and system breaks. */ | 72 | /* Declarations for working with the malloc, ralloc, and system breaks. */ |
| 77 | 73 | ||
| 78 | /* Function to set the real break value. */ | 74 | /* Function to set the real break value. */ |
| 79 | POINTER (*real_morecore) (long int); | 75 | POINTER (*real_morecore) (ptrdiff_t); |
| 80 | 76 | ||
| 81 | /* The break value, as seen by malloc. */ | 77 | /* The break value, as seen by malloc. */ |
| 82 | static POINTER virtual_break_value; | 78 | static POINTER virtual_break_value; |
| @@ -95,20 +91,18 @@ static int extra_bytes; | |||
| 95 | /* Macros for rounding. Note that rounding to any value is possible | 91 | /* Macros for rounding. Note that rounding to any value is possible |
| 96 | by changing the definition of PAGE. */ | 92 | by changing the definition of PAGE. */ |
| 97 | #define PAGE (getpagesize ()) | 93 | #define PAGE (getpagesize ()) |
| 98 | #define ALIGNED(addr) (((unsigned long int) (addr) & (page_size - 1)) == 0) | 94 | #define ROUNDUP(size) (((size_t) (size) + page_size - 1) \ |
| 99 | #define ROUNDUP(size) (((unsigned long int) (size) + page_size - 1) \ | 95 | & ~((size_t)(page_size - 1))) |
| 100 | & ~(page_size - 1)) | ||
| 101 | #define ROUND_TO_PAGE(addr) (addr & (~(page_size - 1))) | ||
| 102 | 96 | ||
| 103 | #define MEM_ALIGN sizeof (double) | 97 | #define MEM_ALIGN sizeof (double) |
| 104 | #define MEM_ROUNDUP(addr) (((unsigned long int)(addr) + MEM_ALIGN - 1) \ | 98 | #define MEM_ROUNDUP(addr) (((size_t)(addr) + MEM_ALIGN - 1) \ |
| 105 | & ~(MEM_ALIGN - 1)) | 99 | & ~(MEM_ALIGN - 1)) |
| 106 | 100 | ||
| 107 | /* The hook `malloc' uses for the function which gets more space | 101 | /* The hook `malloc' uses for the function which gets more space |
| 108 | from the system. */ | 102 | from the system. */ |
| 109 | 103 | ||
| 110 | #ifndef SYSTEM_MALLOC | 104 | #ifndef SYSTEM_MALLOC |
| 111 | extern POINTER (*__morecore) (long int); | 105 | extern POINTER (*__morecore) (ptrdiff_t); |
| 112 | #endif | 106 | #endif |
| 113 | 107 | ||
| 114 | 108 | ||
| @@ -151,7 +145,6 @@ typedef struct heap | |||
| 151 | } *heap_ptr; | 145 | } *heap_ptr; |
| 152 | 146 | ||
| 153 | #define NIL_HEAP ((heap_ptr) 0) | 147 | #define NIL_HEAP ((heap_ptr) 0) |
| 154 | #define HEAP_PTR_SIZE (sizeof (struct heap)) | ||
| 155 | 148 | ||
| 156 | /* This is the first heap object. | 149 | /* This is the first heap object. |
| 157 | If we need additional heap objects, each one resides at the beginning of | 150 | If we need additional heap objects, each one resides at the beginning of |
| @@ -244,7 +237,7 @@ obtain (POINTER address, SIZE size) | |||
| 244 | } | 237 | } |
| 245 | 238 | ||
| 246 | if (! heap) | 239 | if (! heap) |
| 247 | abort (); | 240 | emacs_abort (); |
| 248 | 241 | ||
| 249 | /* If we can't fit SIZE bytes in that heap, | 242 | /* If we can't fit SIZE bytes in that heap, |
| 250 | try successive later heaps. */ | 243 | try successive later heaps. */ |
| @@ -315,7 +308,7 @@ static void | |||
| 315 | relinquish (void) | 308 | relinquish (void) |
| 316 | { | 309 | { |
| 317 | register heap_ptr h; | 310 | register heap_ptr h; |
| 318 | long excess = 0; | 311 | ptrdiff_t excess = 0; |
| 319 | 312 | ||
| 320 | /* Add the amount of space beyond break_value | 313 | /* Add the amount of space beyond break_value |
| 321 | in all heaps which have extend beyond break_value at all. */ | 314 | in all heaps which have extend beyond break_value at all. */ |
| @@ -334,47 +327,39 @@ relinquish (void) | |||
| 334 | 327 | ||
| 335 | if ((char *)last_heap->end - (char *)last_heap->bloc_start <= excess) | 328 | if ((char *)last_heap->end - (char *)last_heap->bloc_start <= excess) |
| 336 | { | 329 | { |
| 337 | /* This heap should have no blocs in it. */ | 330 | heap_ptr lh_prev; |
| 331 | |||
| 332 | /* This heap should have no blocs in it. If it does, we | ||
| 333 | cannot return it to the system. */ | ||
| 338 | if (last_heap->first_bloc != NIL_BLOC | 334 | if (last_heap->first_bloc != NIL_BLOC |
| 339 | || last_heap->last_bloc != NIL_BLOC) | 335 | || last_heap->last_bloc != NIL_BLOC) |
| 340 | abort (); | 336 | return; |
| 341 | 337 | ||
| 342 | /* Return the last heap, with its header, to the system. */ | 338 | /* Return the last heap, with its header, to the system. */ |
| 343 | excess = (char *)last_heap->end - (char *)last_heap->start; | 339 | excess = (char *)last_heap->end - (char *)last_heap->start; |
| 344 | last_heap = last_heap->prev; | 340 | lh_prev = last_heap->prev; |
| 345 | last_heap->next = NIL_HEAP; | 341 | /* If the system doesn't want that much memory back, leave |
| 342 | last_heap unaltered to reflect that. This can occur if | ||
| 343 | break_value is still within the original data segment. */ | ||
| 344 | if ((*real_morecore) (- excess) != 0) | ||
| 345 | { | ||
| 346 | last_heap = lh_prev; | ||
| 347 | last_heap->next = NIL_HEAP; | ||
| 348 | } | ||
| 346 | } | 349 | } |
| 347 | else | 350 | else |
| 348 | { | 351 | { |
| 349 | excess = (char *) last_heap->end | 352 | excess = (char *) last_heap->end |
| 350 | - (char *) ROUNDUP ((char *)last_heap->end - excess); | 353 | - (char *) ROUNDUP ((char *)last_heap->end - excess); |
| 351 | last_heap->end = (char *) last_heap->end - excess; | 354 | /* If the system doesn't want that much memory back, leave |
| 352 | } | 355 | the end of the last heap unchanged to reflect that. This |
| 353 | 356 | can occur if break_value is still within the original | |
| 354 | if ((*real_morecore) (- excess) == 0) | 357 | data segment. */ |
| 355 | { | 358 | if ((*real_morecore) (- excess) != 0) |
| 356 | /* If the system didn't want that much memory back, adjust | 359 | last_heap->end = (char *) last_heap->end - excess; |
| 357 | the end of the last heap to reflect that. This can occur | ||
| 358 | if break_value is still within the original data segment. */ | ||
| 359 | last_heap->end = (char *) last_heap->end + excess; | ||
| 360 | /* Make sure that the result of the adjustment is accurate. | ||
| 361 | It should be, for the else clause above; the other case, | ||
| 362 | which returns the entire last heap to the system, seems | ||
| 363 | unlikely to trigger this mode of failure. */ | ||
| 364 | if (last_heap->end != (*real_morecore) (0)) | ||
| 365 | abort (); | ||
| 366 | } | 360 | } |
| 367 | } | 361 | } |
| 368 | } | 362 | } |
| 369 | |||
| 370 | /* Return the total size in use by relocating allocator, | ||
| 371 | above where malloc gets space. */ | ||
| 372 | |||
| 373 | long | ||
| 374 | r_alloc_size_in_use (void) | ||
| 375 | { | ||
| 376 | return (char *) break_value - (char *) virtual_break_value; | ||
| 377 | } | ||
| 378 | 363 | ||
| 379 | /* The meat - allocating, freeing, and relocating blocs. */ | 364 | /* The meat - allocating, freeing, and relocating blocs. */ |
| 380 | 365 | ||
| @@ -412,7 +397,7 @@ get_bloc (SIZE size) | |||
| 412 | register bloc_ptr new_bloc; | 397 | register bloc_ptr new_bloc; |
| 413 | register heap_ptr heap; | 398 | register heap_ptr heap; |
| 414 | 399 | ||
| 415 | if (! (new_bloc = (bloc_ptr) malloc (BLOC_PTR_SIZE)) | 400 | if (! (new_bloc = malloc (BLOC_PTR_SIZE)) |
| 416 | || ! (new_bloc->data = obtain (break_value, size))) | 401 | || ! (new_bloc->data = obtain (break_value, size))) |
| 417 | { | 402 | { |
| 418 | free (new_bloc); | 403 | free (new_bloc); |
| @@ -468,7 +453,7 @@ relocate_blocs (bloc_ptr bloc, heap_ptr heap, POINTER address) | |||
| 468 | 453 | ||
| 469 | /* No need to ever call this if arena is frozen, bug somewhere! */ | 454 | /* No need to ever call this if arena is frozen, bug somewhere! */ |
| 470 | if (r_alloc_freeze_level) | 455 | if (r_alloc_freeze_level) |
| 471 | abort (); | 456 | emacs_abort (); |
| 472 | 457 | ||
| 473 | while (b) | 458 | while (b) |
| 474 | { | 459 | { |
| @@ -592,7 +577,7 @@ resize_bloc (bloc_ptr bloc, SIZE size) | |||
| 592 | 577 | ||
| 593 | /* No need to ever call this if arena is frozen, bug somewhere! */ | 578 | /* No need to ever call this if arena is frozen, bug somewhere! */ |
| 594 | if (r_alloc_freeze_level) | 579 | if (r_alloc_freeze_level) |
| 595 | abort (); | 580 | emacs_abort (); |
| 596 | 581 | ||
| 597 | if (bloc == NIL_BLOC || size == bloc->size) | 582 | if (bloc == NIL_BLOC || size == bloc->size) |
| 598 | return 1; | 583 | return 1; |
| @@ -604,7 +589,7 @@ resize_bloc (bloc_ptr bloc, SIZE size) | |||
| 604 | } | 589 | } |
| 605 | 590 | ||
| 606 | if (heap == NIL_HEAP) | 591 | if (heap == NIL_HEAP) |
| 607 | abort (); | 592 | emacs_abort (); |
| 608 | 593 | ||
| 609 | old_size = bloc->size; | 594 | old_size = bloc->size; |
| 610 | bloc->size = size; | 595 | bloc->size = size; |
| @@ -636,7 +621,8 @@ resize_bloc (bloc_ptr bloc, SIZE size) | |||
| 636 | } | 621 | } |
| 637 | else | 622 | else |
| 638 | { | 623 | { |
| 639 | memmove (b->new_data, b->data, b->size); | 624 | if (b->new_data != b->data) |
| 625 | memmove (b->new_data, b->data, b->size); | ||
| 640 | *b->variable = b->data = b->new_data; | 626 | *b->variable = b->data = b->new_data; |
| 641 | } | 627 | } |
| 642 | } | 628 | } |
| @@ -647,7 +633,8 @@ resize_bloc (bloc_ptr bloc, SIZE size) | |||
| 647 | } | 633 | } |
| 648 | else | 634 | else |
| 649 | { | 635 | { |
| 650 | memmove (bloc->new_data, bloc->data, old_size); | 636 | if (bloc->new_data != bloc->data) |
| 637 | memmove (bloc->new_data, bloc->data, old_size); | ||
| 651 | memset ((char *) bloc->new_data + old_size, 0, size - old_size); | 638 | memset ((char *) bloc->new_data + old_size, 0, size - old_size); |
| 652 | *bloc->variable = bloc->data = bloc->new_data; | 639 | *bloc->variable = bloc->data = bloc->new_data; |
| 653 | } | 640 | } |
| @@ -663,7 +650,8 @@ resize_bloc (bloc_ptr bloc, SIZE size) | |||
| 663 | } | 650 | } |
| 664 | else | 651 | else |
| 665 | { | 652 | { |
| 666 | memmove (b->new_data, b->data, b->size); | 653 | if (b->new_data != b->data) |
| 654 | memmove (b->new_data, b->data, b->size); | ||
| 667 | *b->variable = b->data = b->new_data; | 655 | *b->variable = b->data = b->new_data; |
| 668 | } | 656 | } |
| 669 | } | 657 | } |
| @@ -683,6 +671,7 @@ static void | |||
| 683 | free_bloc (bloc_ptr bloc) | 671 | free_bloc (bloc_ptr bloc) |
| 684 | { | 672 | { |
| 685 | heap_ptr heap = bloc->heap; | 673 | heap_ptr heap = bloc->heap; |
| 674 | heap_ptr h; | ||
| 686 | 675 | ||
| 687 | if (r_alloc_freeze_level) | 676 | if (r_alloc_freeze_level) |
| 688 | { | 677 | { |
| @@ -712,20 +701,38 @@ free_bloc (bloc_ptr bloc) | |||
| 712 | bloc->prev->next = bloc->next; | 701 | bloc->prev->next = bloc->next; |
| 713 | } | 702 | } |
| 714 | 703 | ||
| 715 | /* Update the records of which blocs are in HEAP. */ | 704 | /* Sometimes, 'heap' obtained from bloc->heap above is not really a |
| 716 | if (heap->first_bloc == bloc) | 705 | 'heap' structure. It can even be beyond the current break point, |
| 717 | { | 706 | which will cause crashes when we dereference it below (see |
| 718 | if (bloc->next != 0 && bloc->next->heap == heap) | 707 | bug#12242). Evidently, the reason is bloc allocations done while |
| 719 | heap->first_bloc = bloc->next; | 708 | use_relocatable_buffers was non-positive, because additional |
| 720 | else | 709 | memory we get then is not recorded in the heaps we manage. If |
| 721 | heap->first_bloc = heap->last_bloc = NIL_BLOC; | 710 | bloc->heap records such a "heap", we cannot (and don't need to) |
| 722 | } | 711 | update its records. So we validate the 'heap' value by making |
| 723 | if (heap->last_bloc == bloc) | 712 | sure it is one of the heaps we manage via the heaps linked list, |
| 713 | and don't touch a 'heap' that isn't found there. This avoids | ||
| 714 | accessing memory we know nothing about. */ | ||
| 715 | for (h = first_heap; h != NIL_HEAP; h = h->next) | ||
| 716 | if (heap == h) | ||
| 717 | break; | ||
| 718 | |||
| 719 | if (h) | ||
| 724 | { | 720 | { |
| 725 | if (bloc->prev != 0 && bloc->prev->heap == heap) | 721 | /* Update the records of which blocs are in HEAP. */ |
| 726 | heap->last_bloc = bloc->prev; | 722 | if (heap->first_bloc == bloc) |
| 727 | else | 723 | { |
| 728 | heap->first_bloc = heap->last_bloc = NIL_BLOC; | 724 | if (bloc->next != 0 && bloc->next->heap == heap) |
| 725 | heap->first_bloc = bloc->next; | ||
| 726 | else | ||
| 727 | heap->first_bloc = heap->last_bloc = NIL_BLOC; | ||
| 728 | } | ||
| 729 | if (heap->last_bloc == bloc) | ||
| 730 | { | ||
| 731 | if (bloc->prev != 0 && bloc->prev->heap == heap) | ||
| 732 | heap->last_bloc = bloc->prev; | ||
| 733 | else | ||
| 734 | heap->first_bloc = heap->last_bloc = NIL_BLOC; | ||
| 735 | } | ||
| 729 | } | 736 | } |
| 730 | 737 | ||
| 731 | relinquish (); | 738 | relinquish (); |
| @@ -745,8 +752,8 @@ free_bloc (bloc_ptr bloc) | |||
| 745 | __morecore hook values - in particular, __default_morecore in the | 752 | __morecore hook values - in particular, __default_morecore in the |
| 746 | GNU malloc package. */ | 753 | GNU malloc package. */ |
| 747 | 754 | ||
| 748 | POINTER | 755 | static POINTER |
| 749 | r_alloc_sbrk (long int size) | 756 | r_alloc_sbrk (ptrdiff_t size) |
| 750 | { | 757 | { |
| 751 | register bloc_ptr b; | 758 | register bloc_ptr b; |
| 752 | POINTER address; | 759 | POINTER address; |
| @@ -754,7 +761,7 @@ r_alloc_sbrk (long int size) | |||
| 754 | if (! r_alloc_initialized) | 761 | if (! r_alloc_initialized) |
| 755 | r_alloc_init (); | 762 | r_alloc_init (); |
| 756 | 763 | ||
| 757 | if (! use_relocatable_buffers) | 764 | if (use_relocatable_buffers <= 0) |
| 758 | return (*real_morecore) (size); | 765 | return (*real_morecore) (size); |
| 759 | 766 | ||
| 760 | if (size == 0) | 767 | if (size == 0) |
| @@ -816,7 +823,8 @@ r_alloc_sbrk (long int size) | |||
| 816 | header. */ | 823 | header. */ |
| 817 | for (b = last_bloc; b != NIL_BLOC; b = b->prev) | 824 | for (b = last_bloc; b != NIL_BLOC; b = b->prev) |
| 818 | { | 825 | { |
| 819 | memmove (b->new_data, b->data, b->size); | 826 | if (b->new_data != b->data) |
| 827 | memmove (b->new_data, b->data, b->size); | ||
| 820 | *b->variable = b->data = b->new_data; | 828 | *b->variable = b->data = b->new_data; |
| 821 | } | 829 | } |
| 822 | 830 | ||
| @@ -862,7 +870,8 @@ r_alloc_sbrk (long int size) | |||
| 862 | 870 | ||
| 863 | for (b = first_bloc; b != NIL_BLOC; b = b->next) | 871 | for (b = first_bloc; b != NIL_BLOC; b = b->next) |
| 864 | { | 872 | { |
| 865 | memmove (b->new_data, b->data, b->size); | 873 | if (b->new_data != b->data) |
| 874 | memmove (b->new_data, b->data, b->size); | ||
| 866 | *b->variable = b->data = b->new_data; | 875 | *b->variable = b->data = b->new_data; |
| 867 | } | 876 | } |
| 868 | } | 877 | } |
| @@ -929,7 +938,7 @@ r_alloc_free (register POINTER *ptr) | |||
| 929 | 938 | ||
| 930 | dead_bloc = find_bloc (ptr); | 939 | dead_bloc = find_bloc (ptr); |
| 931 | if (dead_bloc == NIL_BLOC) | 940 | if (dead_bloc == NIL_BLOC) |
| 932 | abort (); /* Double free? PTR not originally used to allocate? */ | 941 | emacs_abort (); /* Double free? PTR not originally used to allocate? */ |
| 933 | 942 | ||
| 934 | free_bloc (dead_bloc); | 943 | free_bloc (dead_bloc); |
| 935 | *ptr = 0; | 944 | *ptr = 0; |
| @@ -971,7 +980,7 @@ r_re_alloc (POINTER *ptr, SIZE size) | |||
| 971 | 980 | ||
| 972 | bloc = find_bloc (ptr); | 981 | bloc = find_bloc (ptr); |
| 973 | if (bloc == NIL_BLOC) | 982 | if (bloc == NIL_BLOC) |
| 974 | abort (); /* Already freed? PTR not originally used to allocate? */ | 983 | emacs_abort (); /* Already freed? PTR not originally used to allocate? */ |
| 975 | 984 | ||
| 976 | if (size < bloc->size) | 985 | if (size < bloc->size) |
| 977 | { | 986 | { |
| @@ -1009,52 +1018,6 @@ r_re_alloc (POINTER *ptr, SIZE size) | |||
| 1009 | return *ptr; | 1018 | return *ptr; |
| 1010 | } | 1019 | } |
| 1011 | 1020 | ||
| 1012 | /* Disable relocations, after making room for at least SIZE bytes | ||
| 1013 | of non-relocatable heap if possible. The relocatable blocs are | ||
| 1014 | guaranteed to hold still until thawed, even if this means that | ||
| 1015 | malloc must return a null pointer. */ | ||
| 1016 | |||
| 1017 | void | ||
| 1018 | r_alloc_freeze (long int size) | ||
| 1019 | { | ||
| 1020 | if (! r_alloc_initialized) | ||
| 1021 | r_alloc_init (); | ||
| 1022 | |||
| 1023 | /* If already frozen, we can't make any more room, so don't try. */ | ||
| 1024 | if (r_alloc_freeze_level > 0) | ||
| 1025 | size = 0; | ||
| 1026 | /* If we can't get the amount requested, half is better than nothing. */ | ||
| 1027 | while (size > 0 && r_alloc_sbrk (size) == 0) | ||
| 1028 | size /= 2; | ||
| 1029 | ++r_alloc_freeze_level; | ||
| 1030 | if (size > 0) | ||
| 1031 | r_alloc_sbrk (-size); | ||
| 1032 | } | ||
| 1033 | |||
| 1034 | void | ||
| 1035 | r_alloc_thaw (void) | ||
| 1036 | { | ||
| 1037 | |||
| 1038 | if (! r_alloc_initialized) | ||
| 1039 | r_alloc_init (); | ||
| 1040 | |||
| 1041 | if (--r_alloc_freeze_level < 0) | ||
| 1042 | abort (); | ||
| 1043 | |||
| 1044 | /* This frees all unused blocs. It is not too inefficient, as the resize | ||
| 1045 | and memcpy is done only once. Afterwards, all unreferenced blocs are | ||
| 1046 | already shrunk to zero size. */ | ||
| 1047 | if (!r_alloc_freeze_level) | ||
| 1048 | { | ||
| 1049 | bloc_ptr *b = &first_bloc; | ||
| 1050 | while (*b) | ||
| 1051 | if (!(*b)->variable) | ||
| 1052 | free_bloc (*b); | ||
| 1053 | else | ||
| 1054 | b = &(*b)->next; | ||
| 1055 | } | ||
| 1056 | } | ||
| 1057 | |||
| 1058 | 1021 | ||
| 1059 | #if defined (emacs) && defined (DOUG_LEA_MALLOC) | 1022 | #if defined (emacs) && defined (DOUG_LEA_MALLOC) |
| 1060 | 1023 | ||
| @@ -1190,12 +1153,23 @@ r_alloc_reset_variable (POINTER *old, POINTER *new) | |||
| 1190 | } | 1153 | } |
| 1191 | 1154 | ||
| 1192 | if (bloc == NIL_BLOC || bloc->variable != old) | 1155 | if (bloc == NIL_BLOC || bloc->variable != old) |
| 1193 | abort (); /* Already freed? OLD not originally used to allocate? */ | 1156 | emacs_abort (); /* Already freed? OLD not originally used to allocate? */ |
| 1194 | 1157 | ||
| 1195 | /* Update variable to point to the new location. */ | 1158 | /* Update variable to point to the new location. */ |
| 1196 | bloc->variable = new; | 1159 | bloc->variable = new; |
| 1197 | } | 1160 | } |
| 1198 | 1161 | ||
| 1162 | void | ||
| 1163 | r_alloc_inhibit_buffer_relocation (int inhibit) | ||
| 1164 | { | ||
| 1165 | if (use_relocatable_buffers > 1) | ||
| 1166 | use_relocatable_buffers = 1; | ||
| 1167 | if (inhibit) | ||
| 1168 | use_relocatable_buffers--; | ||
| 1169 | else if (use_relocatable_buffers < 1) | ||
| 1170 | use_relocatable_buffers++; | ||
| 1171 | } | ||
| 1172 | |||
| 1199 | 1173 | ||
| 1200 | /*********************************************************************** | 1174 | /*********************************************************************** |
| 1201 | Initialization | 1175 | Initialization |
| @@ -1220,20 +1194,26 @@ r_alloc_init (void) | |||
| 1220 | first_heap->start = first_heap->bloc_start | 1194 | first_heap->start = first_heap->bloc_start |
| 1221 | = virtual_break_value = break_value = (*real_morecore) (0); | 1195 | = virtual_break_value = break_value = (*real_morecore) (0); |
| 1222 | if (break_value == NIL) | 1196 | if (break_value == NIL) |
| 1223 | abort (); | 1197 | emacs_abort (); |
| 1224 | 1198 | ||
| 1225 | extra_bytes = ROUNDUP (50000); | 1199 | extra_bytes = ROUNDUP (50000); |
| 1226 | #endif | 1200 | #endif |
| 1227 | 1201 | ||
| 1228 | #ifdef DOUG_LEA_MALLOC | 1202 | #ifdef DOUG_LEA_MALLOC |
| 1229 | BLOCK_INPUT; | 1203 | block_input (); |
| 1230 | mallopt (M_TOP_PAD, 64 * 4096); | 1204 | mallopt (M_TOP_PAD, 64 * 4096); |
| 1231 | UNBLOCK_INPUT; | 1205 | unblock_input (); |
| 1232 | #else | 1206 | #else |
| 1233 | #ifndef SYSTEM_MALLOC | 1207 | #ifndef SYSTEM_MALLOC |
| 1234 | /* Give GNU malloc's morecore some hysteresis | 1208 | /* Give GNU malloc's morecore some hysteresis so that we move all |
| 1235 | so that we move all the relocatable blocks much less often. */ | 1209 | the relocatable blocks much less often. The number used to be |
| 1236 | __malloc_extra_blocks = 64; | 1210 | 64, but alloc.c would override that with 32 in code that was |
| 1211 | removed when SYNC_INPUT became the only input handling mode. | ||
| 1212 | That code was conditioned on !DOUG_LEA_MALLOC, so the call to | ||
| 1213 | mallopt above is left unchanged. (Actually, I think there's no | ||
| 1214 | system nowadays that uses DOUG_LEA_MALLOC and also uses | ||
| 1215 | REL_ALLOC.) */ | ||
| 1216 | __malloc_extra_blocks = 32; | ||
| 1237 | #endif | 1217 | #endif |
| 1238 | #endif | 1218 | #endif |
| 1239 | 1219 | ||