aboutsummaryrefslogtreecommitdiffstats
path: root/src/ralloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ralloc.c')
-rw-r--r--src/ralloc.c326
1 files changed, 173 insertions, 153 deletions
diff --git a/src/ralloc.c b/src/ralloc.c
index 19d15664eec..5f25ef2c320 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-2012 Free Software Foundation, Inc. 2 Copyright (C) 1993, 1995, 2000-2013 Free Software Foundation, Inc.
3 3
4This file is part of GNU Emacs. 4This file is part of GNU Emacs.
5 5
@@ -25,7 +25,7 @@ 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
@@ -43,8 +43,6 @@ extern size_t __malloc_extra_blocks;
43#else /* not emacs */ 43#else /* not emacs */
44 44
45#include <stddef.h> 45#include <stddef.h>
46
47#include <unistd.h>
48#include <malloc.h> 46#include <malloc.h>
49 47
50#endif /* not emacs */ 48#endif /* not emacs */
@@ -52,10 +50,6 @@ extern size_t __malloc_extra_blocks;
52 50
53#include "getpagesize.h" 51#include "getpagesize.h"
54 52
55typedef size_t SIZE;
56typedef void *POINTER;
57#define NIL ((POINTER) 0)
58
59/* A flag to indicate whether we have initialized ralloc yet. For 53/* A flag to indicate whether we have initialized ralloc yet. For
60 Emacs's sake, please do not make this local to malloc_init; on some 54 Emacs's sake, please do not make this local to malloc_init; on some
61 machines, the dumping procedure makes all static variables 55 machines, the dumping procedure makes all static variables
@@ -72,14 +66,14 @@ static void r_alloc_init (void);
72/* Declarations for working with the malloc, ralloc, and system breaks. */ 66/* Declarations for working with the malloc, ralloc, and system breaks. */
73 67
74/* Function to set the real break value. */ 68/* Function to set the real break value. */
75POINTER (*real_morecore) (long int); 69void *(*real_morecore) (ptrdiff_t);
76 70
77/* The break value, as seen by malloc. */ 71/* The break value, as seen by malloc. */
78static POINTER virtual_break_value; 72static void *virtual_break_value;
79 73
80/* The address of the end of the last data in use by ralloc, 74/* The address of the end of the last data in use by ralloc,
81 including relocatable blocs as well as malloc data. */ 75 including relocatable blocs as well as malloc data. */
82static POINTER break_value; 76static void *break_value;
83 77
84/* This is the size of a page. We round memory requests to this boundary. */ 78/* This is the size of a page. We round memory requests to this boundary. */
85static int page_size; 79static int page_size;
@@ -91,18 +85,18 @@ static int extra_bytes;
91/* Macros for rounding. Note that rounding to any value is possible 85/* Macros for rounding. Note that rounding to any value is possible
92 by changing the definition of PAGE. */ 86 by changing the definition of PAGE. */
93#define PAGE (getpagesize ()) 87#define PAGE (getpagesize ())
94#define ROUNDUP(size) (((unsigned long int) (size) + page_size - 1) \ 88#define ROUNDUP(size) (((size_t) (size) + page_size - 1) \
95 & ~(page_size - 1)) 89 & ~((size_t) (page_size - 1)))
96 90
97#define MEM_ALIGN sizeof (double) 91#define MEM_ALIGN sizeof (double)
98#define MEM_ROUNDUP(addr) (((unsigned long int)(addr) + MEM_ALIGN - 1) \ 92#define MEM_ROUNDUP(addr) (((size_t) (addr) + MEM_ALIGN - 1) \
99 & ~(MEM_ALIGN - 1)) 93 & ~(MEM_ALIGN - 1))
100 94
101/* The hook `malloc' uses for the function which gets more space 95/* The hook `malloc' uses for the function which gets more space
102 from the system. */ 96 from the system. */
103 97
104#ifndef SYSTEM_MALLOC 98#ifndef SYSTEM_MALLOC
105extern POINTER (*__morecore) (long int); 99extern void *(*__morecore) (ptrdiff_t);
106#endif 100#endif
107 101
108 102
@@ -131,13 +125,13 @@ typedef struct heap
131 struct heap *next; 125 struct heap *next;
132 struct heap *prev; 126 struct heap *prev;
133 /* Start of memory range of this heap. */ 127 /* Start of memory range of this heap. */
134 POINTER start; 128 void *start;
135 /* End of memory range of this heap. */ 129 /* End of memory range of this heap. */
136 POINTER end; 130 void *end;
137 /* Start of relocatable data in this heap. */ 131 /* Start of relocatable data in this heap. */
138 POINTER bloc_start; 132 void *bloc_start;
139 /* Start of unused space in this heap. */ 133 /* Start of unused space in this heap. */
140 POINTER free; 134 void *free;
141 /* First bloc in this heap. */ 135 /* First bloc in this heap. */
142 struct bp *first_bloc; 136 struct bp *first_bloc;
143 /* Last bloc in this heap. */ 137 /* Last bloc in this heap. */
@@ -159,7 +153,7 @@ static heap_ptr first_heap, last_heap;
159 The data blocks abut each other; if b->next is non-nil, then 153 The data blocks abut each other; if b->next is non-nil, then
160 b->data + b->size == b->next->data. 154 b->data + b->size == b->next->data.
161 155
162 An element with variable==NIL denotes a freed block, which has not yet 156 An element with variable==NULL denotes a freed block, which has not yet
163 been collected. They may only appear while r_alloc_freeze_level > 0, 157 been collected. They may only appear while r_alloc_freeze_level > 0,
164 and will be freed when the arena is thawed. Currently, these blocs are 158 and will be freed when the arena is thawed. Currently, these blocs are
165 not reusable, while the arena is frozen. Very inefficient. */ 159 not reusable, while the arena is frozen. Very inefficient. */
@@ -168,10 +162,10 @@ typedef struct bp
168{ 162{
169 struct bp *next; 163 struct bp *next;
170 struct bp *prev; 164 struct bp *prev;
171 POINTER *variable; 165 void **variable;
172 POINTER data; 166 void *data;
173 SIZE size; 167 size_t size;
174 POINTER new_data; /* temporarily used for relocation */ 168 void *new_data; /* temporarily used for relocation */
175 struct heap *heap; /* Heap this bloc is in. */ 169 struct heap *heap; /* Heap this bloc is in. */
176} *bloc_ptr; 170} *bloc_ptr;
177 171
@@ -192,7 +186,7 @@ static int r_alloc_freeze_level;
192/* Find the heap that ADDRESS falls within. */ 186/* Find the heap that ADDRESS falls within. */
193 187
194static heap_ptr 188static heap_ptr
195find_heap (POINTER address) 189find_heap (void *address)
196{ 190{
197 heap_ptr heap; 191 heap_ptr heap;
198 192
@@ -223,11 +217,11 @@ find_heap (POINTER address)
223 Return the address of the space if all went well, or zero if we couldn't 217 Return the address of the space if all went well, or zero if we couldn't
224 allocate the memory. */ 218 allocate the memory. */
225 219
226static POINTER 220static void *
227obtain (POINTER address, SIZE size) 221obtain (void *address, size_t size)
228{ 222{
229 heap_ptr heap; 223 heap_ptr heap;
230 SIZE already_available; 224 size_t already_available;
231 225
232 /* Find the heap that ADDRESS falls within. */ 226 /* Find the heap that ADDRESS falls within. */
233 for (heap = last_heap; heap; heap = heap->prev) 227 for (heap = last_heap; heap; heap = heap->prev)
@@ -237,7 +231,7 @@ obtain (POINTER address, SIZE size)
237 } 231 }
238 232
239 if (! heap) 233 if (! heap)
240 abort (); 234 emacs_abort ();
241 235
242 /* If we can't fit SIZE bytes in that heap, 236 /* If we can't fit SIZE bytes in that heap,
243 try successive later heaps. */ 237 try successive later heaps. */
@@ -253,19 +247,19 @@ obtain (POINTER address, SIZE size)
253 get more space. */ 247 get more space. */
254 if (heap == NIL_HEAP) 248 if (heap == NIL_HEAP)
255 { 249 {
256 POINTER new = (*real_morecore)(0); 250 void *new = real_morecore (0);
257 SIZE get; 251 size_t get;
258 252
259 already_available = (char *)last_heap->end - (char *)address; 253 already_available = (char *) last_heap->end - (char *) address;
260 254
261 if (new != last_heap->end) 255 if (new != last_heap->end)
262 { 256 {
263 /* Someone else called sbrk. Make a new heap. */ 257 /* Someone else called sbrk. Make a new heap. */
264 258
265 heap_ptr new_heap = (heap_ptr) MEM_ROUNDUP (new); 259 heap_ptr new_heap = (heap_ptr) MEM_ROUNDUP (new);
266 POINTER bloc_start = (POINTER) MEM_ROUNDUP ((POINTER)(new_heap + 1)); 260 void *bloc_start = (void *) MEM_ROUNDUP ((void *) (new_heap + 1));
267 261
268 if ((*real_morecore) ((char *) bloc_start - (char *) new) != new) 262 if (real_morecore ((char *) bloc_start - (char *) new) != new)
269 return 0; 263 return 0;
270 264
271 new_heap->start = new; 265 new_heap->start = new;
@@ -287,10 +281,10 @@ obtain (POINTER address, SIZE size)
287 Get some extra, so we can come here less often. */ 281 Get some extra, so we can come here less often. */
288 282
289 get = size + extra_bytes - already_available; 283 get = size + extra_bytes - already_available;
290 get = (char *) ROUNDUP ((char *)last_heap->end + get) 284 get = (char *) ROUNDUP ((char *) last_heap->end + get)
291 - (char *) last_heap->end; 285 - (char *) last_heap->end;
292 286
293 if ((*real_morecore) (get) != last_heap->end) 287 if (real_morecore (get) != last_heap->end)
294 return 0; 288 return 0;
295 289
296 last_heap->end = (char *) last_heap->end + get; 290 last_heap->end = (char *) last_heap->end + get;
@@ -308,7 +302,7 @@ static void
308relinquish (void) 302relinquish (void)
309{ 303{
310 register heap_ptr h; 304 register heap_ptr h;
311 long excess = 0; 305 ptrdiff_t excess = 0;
312 306
313 /* Add the amount of space beyond break_value 307 /* Add the amount of space beyond break_value
314 in all heaps which have extend beyond break_value at all. */ 308 in all heaps which have extend beyond break_value at all. */
@@ -319,43 +313,44 @@ relinquish (void)
319 ? h->bloc_start : break_value); 313 ? h->bloc_start : break_value);
320 } 314 }
321 315
322 if (excess > extra_bytes * 2 && (*real_morecore) (0) == last_heap->end) 316 if (excess > extra_bytes * 2 && real_morecore (0) == last_heap->end)
323 { 317 {
324 /* Keep extra_bytes worth of empty space. 318 /* Keep extra_bytes worth of empty space.
325 And don't free anything unless we can free at least extra_bytes. */ 319 And don't free anything unless we can free at least extra_bytes. */
326 excess -= extra_bytes; 320 excess -= extra_bytes;
327 321
328 if ((char *)last_heap->end - (char *)last_heap->bloc_start <= excess) 322 if ((char *) last_heap->end - (char *) last_heap->bloc_start <= excess)
329 { 323 {
330 /* This heap should have no blocs in it. */ 324 heap_ptr lh_prev;
325
326 /* This heap should have no blocs in it. If it does, we
327 cannot return it to the system. */
331 if (last_heap->first_bloc != NIL_BLOC 328 if (last_heap->first_bloc != NIL_BLOC
332 || last_heap->last_bloc != NIL_BLOC) 329 || last_heap->last_bloc != NIL_BLOC)
333 abort (); 330 return;
334 331
335 /* Return the last heap, with its header, to the system. */ 332 /* Return the last heap, with its header, to the system. */
336 excess = (char *)last_heap->end - (char *)last_heap->start; 333 excess = (char *) last_heap->end - (char *) last_heap->start;
337 last_heap = last_heap->prev; 334 lh_prev = last_heap->prev;
338 last_heap->next = NIL_HEAP; 335 /* If the system doesn't want that much memory back, leave
336 last_heap unaltered to reflect that. This can occur if
337 break_value is still within the original data segment. */
338 if (real_morecore (- excess) != 0)
339 {
340 last_heap = lh_prev;
341 last_heap->next = NIL_HEAP;
342 }
339 } 343 }
340 else 344 else
341 { 345 {
342 excess = (char *) last_heap->end 346 excess = ((char *) last_heap->end
343 - (char *) ROUNDUP ((char *)last_heap->end - excess); 347 - (char *) ROUNDUP ((char *) last_heap->end - excess));
344 last_heap->end = (char *) last_heap->end - excess; 348 /* If the system doesn't want that much memory back, leave
345 } 349 the end of the last heap unchanged to reflect that. This
346 350 can occur if break_value is still within the original
347 if ((*real_morecore) (- excess) == 0) 351 data segment. */
348 { 352 if (real_morecore (- excess) != 0)
349 /* If the system didn't want that much memory back, adjust 353 last_heap->end = (char *) last_heap->end - excess;
350 the end of the last heap to reflect that. This can occur
351 if break_value is still within the original data segment. */
352 last_heap->end = (char *) last_heap->end + excess;
353 /* Make sure that the result of the adjustment is accurate.
354 It should be, for the else clause above; the other case,
355 which returns the entire last heap to the system, seems
356 unlikely to trigger this mode of failure. */
357 if (last_heap->end != (*real_morecore) (0))
358 abort ();
359 } 354 }
360 } 355 }
361} 356}
@@ -366,9 +361,9 @@ relinquish (void)
366 to that block. */ 361 to that block. */
367 362
368static bloc_ptr 363static bloc_ptr
369find_bloc (POINTER *ptr) 364find_bloc (void **ptr)
370{ 365{
371 register bloc_ptr p = first_bloc; 366 bloc_ptr p = first_bloc;
372 367
373 while (p != NIL_BLOC) 368 while (p != NIL_BLOC)
374 { 369 {
@@ -391,12 +386,12 @@ find_bloc (POINTER *ptr)
391 memory for the new block. */ 386 memory for the new block. */
392 387
393static bloc_ptr 388static bloc_ptr
394get_bloc (SIZE size) 389get_bloc (size_t size)
395{ 390{
396 register bloc_ptr new_bloc; 391 bloc_ptr new_bloc;
397 register heap_ptr heap; 392 heap_ptr heap;
398 393
399 if (! (new_bloc = (bloc_ptr) malloc (BLOC_PTR_SIZE)) 394 if (! (new_bloc = malloc (BLOC_PTR_SIZE))
400 || ! (new_bloc->data = obtain (break_value, size))) 395 || ! (new_bloc->data = obtain (break_value, size)))
401 { 396 {
402 free (new_bloc); 397 free (new_bloc);
@@ -408,7 +403,7 @@ get_bloc (SIZE size)
408 403
409 new_bloc->size = size; 404 new_bloc->size = size;
410 new_bloc->next = NIL_BLOC; 405 new_bloc->next = NIL_BLOC;
411 new_bloc->variable = (POINTER *) NIL; 406 new_bloc->variable = NULL;
412 new_bloc->new_data = 0; 407 new_bloc->new_data = 0;
413 408
414 /* Record in the heap that this space is in use. */ 409 /* Record in the heap that this space is in use. */
@@ -446,13 +441,13 @@ get_bloc (SIZE size)
446 Do not touch the contents of blocs or break_value. */ 441 Do not touch the contents of blocs or break_value. */
447 442
448static int 443static int
449relocate_blocs (bloc_ptr bloc, heap_ptr heap, POINTER address) 444relocate_blocs (bloc_ptr bloc, heap_ptr heap, void *address)
450{ 445{
451 register bloc_ptr b = bloc; 446 bloc_ptr b = bloc;
452 447
453 /* No need to ever call this if arena is frozen, bug somewhere! */ 448 /* No need to ever call this if arena is frozen, bug somewhere! */
454 if (r_alloc_freeze_level) 449 if (r_alloc_freeze_level)
455 abort (); 450 emacs_abort ();
456 451
457 while (b) 452 while (b)
458 { 453 {
@@ -470,8 +465,8 @@ relocate_blocs (bloc_ptr bloc, heap_ptr heap, POINTER address)
470 get enough new space to hold BLOC and all following blocs. */ 465 get enough new space to hold BLOC and all following blocs. */
471 if (heap == NIL_HEAP) 466 if (heap == NIL_HEAP)
472 { 467 {
473 register bloc_ptr tb = b; 468 bloc_ptr tb = b;
474 register SIZE s = 0; 469 size_t s = 0;
475 470
476 /* Add up the size of all the following blocs. */ 471 /* Add up the size of all the following blocs. */
477 while (tb != NIL_BLOC) 472 while (tb != NIL_BLOC)
@@ -567,16 +562,16 @@ update_heap_bloc_correspondence (bloc_ptr bloc, heap_ptr heap)
567 that come after BLOC in memory. */ 562 that come after BLOC in memory. */
568 563
569static int 564static int
570resize_bloc (bloc_ptr bloc, SIZE size) 565resize_bloc (bloc_ptr bloc, size_t size)
571{ 566{
572 register bloc_ptr b; 567 bloc_ptr b;
573 heap_ptr heap; 568 heap_ptr heap;
574 POINTER address; 569 void *address;
575 SIZE old_size; 570 size_t old_size;
576 571
577 /* No need to ever call this if arena is frozen, bug somewhere! */ 572 /* No need to ever call this if arena is frozen, bug somewhere! */
578 if (r_alloc_freeze_level) 573 if (r_alloc_freeze_level)
579 abort (); 574 emacs_abort ();
580 575
581 if (bloc == NIL_BLOC || size == bloc->size) 576 if (bloc == NIL_BLOC || size == bloc->size)
582 return 1; 577 return 1;
@@ -588,7 +583,7 @@ resize_bloc (bloc_ptr bloc, SIZE size)
588 } 583 }
589 584
590 if (heap == NIL_HEAP) 585 if (heap == NIL_HEAP)
591 abort (); 586 emacs_abort ();
592 587
593 old_size = bloc->size; 588 old_size = bloc->size;
594 bloc->size = size; 589 bloc->size = size;
@@ -670,10 +665,11 @@ static void
670free_bloc (bloc_ptr bloc) 665free_bloc (bloc_ptr bloc)
671{ 666{
672 heap_ptr heap = bloc->heap; 667 heap_ptr heap = bloc->heap;
668 heap_ptr h;
673 669
674 if (r_alloc_freeze_level) 670 if (r_alloc_freeze_level)
675 { 671 {
676 bloc->variable = (POINTER *) NIL; 672 bloc->variable = NULL;
677 return; 673 return;
678 } 674 }
679 675
@@ -699,20 +695,38 @@ free_bloc (bloc_ptr bloc)
699 bloc->prev->next = bloc->next; 695 bloc->prev->next = bloc->next;
700 } 696 }
701 697
702 /* Update the records of which blocs are in HEAP. */ 698 /* Sometimes, 'heap' obtained from bloc->heap above is not really a
703 if (heap->first_bloc == bloc) 699 'heap' structure. It can even be beyond the current break point,
700 which will cause crashes when we dereference it below (see
701 bug#12242). Evidently, the reason is bloc allocations done while
702 use_relocatable_buffers was non-positive, because additional
703 memory we get then is not recorded in the heaps we manage. If
704 bloc->heap records such a "heap", we cannot (and don't need to)
705 update its records. So we validate the 'heap' value by making
706 sure it is one of the heaps we manage via the heaps linked list,
707 and don't touch a 'heap' that isn't found there. This avoids
708 accessing memory we know nothing about. */
709 for (h = first_heap; h != NIL_HEAP; h = h->next)
710 if (heap == h)
711 break;
712
713 if (h)
704 { 714 {
705 if (bloc->next != 0 && bloc->next->heap == heap) 715 /* Update the records of which blocs are in HEAP. */
706 heap->first_bloc = bloc->next; 716 if (heap->first_bloc == bloc)
707 else 717 {
708 heap->first_bloc = heap->last_bloc = NIL_BLOC; 718 if (bloc->next != 0 && bloc->next->heap == heap)
709 } 719 heap->first_bloc = bloc->next;
710 if (heap->last_bloc == bloc) 720 else
711 { 721 heap->first_bloc = heap->last_bloc = NIL_BLOC;
712 if (bloc->prev != 0 && bloc->prev->heap == heap) 722 }
713 heap->last_bloc = bloc->prev; 723 if (heap->last_bloc == bloc)
714 else 724 {
715 heap->first_bloc = heap->last_bloc = NIL_BLOC; 725 if (bloc->prev != 0 && bloc->prev->heap == heap)
726 heap->last_bloc = bloc->prev;
727 else
728 heap->first_bloc = heap->last_bloc = NIL_BLOC;
729 }
716 } 730 }
717 731
718 relinquish (); 732 relinquish ();
@@ -732,17 +746,17 @@ free_bloc (bloc_ptr bloc)
732 __morecore hook values - in particular, __default_morecore in the 746 __morecore hook values - in particular, __default_morecore in the
733 GNU malloc package. */ 747 GNU malloc package. */
734 748
735static POINTER 749static void *
736r_alloc_sbrk (long int size) 750r_alloc_sbrk (ptrdiff_t size)
737{ 751{
738 register bloc_ptr b; 752 bloc_ptr b;
739 POINTER address; 753 void *address;
740 754
741 if (! r_alloc_initialized) 755 if (! r_alloc_initialized)
742 r_alloc_init (); 756 r_alloc_init ();
743 757
744 if (! use_relocatable_buffers) 758 if (use_relocatable_buffers <= 0)
745 return (*real_morecore) (size); 759 return real_morecore (size);
746 760
747 if (size == 0) 761 if (size == 0)
748 return virtual_break_value; 762 return virtual_break_value;
@@ -752,19 +766,19 @@ r_alloc_sbrk (long int size)
752 /* Allocate a page-aligned space. GNU malloc would reclaim an 766 /* Allocate a page-aligned space. GNU malloc would reclaim an
753 extra space if we passed an unaligned one. But we could 767 extra space if we passed an unaligned one. But we could
754 not always find a space which is contiguous to the previous. */ 768 not always find a space which is contiguous to the previous. */
755 POINTER new_bloc_start; 769 void *new_bloc_start;
756 heap_ptr h = first_heap; 770 heap_ptr h = first_heap;
757 SIZE get = ROUNDUP (size); 771 size_t get = ROUNDUP (size);
758 772
759 address = (POINTER) ROUNDUP (virtual_break_value); 773 address = (void *) ROUNDUP (virtual_break_value);
760 774
761 /* Search the list upward for a heap which is large enough. */ 775 /* Search the list upward for a heap which is large enough. */
762 while ((char *) h->end < (char *) MEM_ROUNDUP ((char *)address + get)) 776 while ((char *) h->end < (char *) MEM_ROUNDUP ((char *) address + get))
763 { 777 {
764 h = h->next; 778 h = h->next;
765 if (h == NIL_HEAP) 779 if (h == NIL_HEAP)
766 break; 780 break;
767 address = (POINTER) ROUNDUP (h->start); 781 address = (void *) ROUNDUP (h->start);
768 } 782 }
769 783
770 /* If not found, obtain more space. */ 784 /* If not found, obtain more space. */
@@ -776,19 +790,19 @@ r_alloc_sbrk (long int size)
776 return 0; 790 return 0;
777 791
778 if (first_heap == last_heap) 792 if (first_heap == last_heap)
779 address = (POINTER) ROUNDUP (virtual_break_value); 793 address = (void *) ROUNDUP (virtual_break_value);
780 else 794 else
781 address = (POINTER) ROUNDUP (last_heap->start); 795 address = (void *) ROUNDUP (last_heap->start);
782 h = last_heap; 796 h = last_heap;
783 } 797 }
784 798
785 new_bloc_start = (POINTER) MEM_ROUNDUP ((char *)address + get); 799 new_bloc_start = (void *) MEM_ROUNDUP ((char *) address + get);
786 800
787 if (first_heap->bloc_start < new_bloc_start) 801 if (first_heap->bloc_start < new_bloc_start)
788 { 802 {
789 /* This is no clean solution - no idea how to do it better. */ 803 /* This is no clean solution - no idea how to do it better. */
790 if (r_alloc_freeze_level) 804 if (r_alloc_freeze_level)
791 return NIL; 805 return NULL;
792 806
793 /* There is a bug here: if the above obtain call succeeded, but the 807 /* There is a bug here: if the above obtain call succeeded, but the
794 relocate_blocs call below does not succeed, we need to free 808 relocate_blocs call below does not succeed, we need to free
@@ -798,7 +812,7 @@ r_alloc_sbrk (long int size)
798 if (! relocate_blocs (first_bloc, h, new_bloc_start)) 812 if (! relocate_blocs (first_bloc, h, new_bloc_start))
799 return 0; 813 return 0;
800 814
801 /* Note that (POINTER)(h+1) <= new_bloc_start since 815 /* Note that (char *) (h + 1) <= (char *) new_bloc_start since
802 get >= page_size, so the following does not destroy the heap 816 get >= page_size, so the following does not destroy the heap
803 header. */ 817 header. */
804 for (b = last_bloc; b != NIL_BLOC; b = b->prev) 818 for (b = last_bloc; b != NIL_BLOC; b = b->prev)
@@ -835,8 +849,8 @@ r_alloc_sbrk (long int size)
835 } 849 }
836 else /* size < 0 */ 850 else /* size < 0 */
837 { 851 {
838 SIZE excess = (char *)first_heap->bloc_start 852 size_t excess = ((char *) first_heap->bloc_start
839 - ((char *)virtual_break_value + size); 853 - ((char *) virtual_break_value + size));
840 854
841 address = virtual_break_value; 855 address = virtual_break_value;
842 856
@@ -844,7 +858,7 @@ r_alloc_sbrk (long int size)
844 { 858 {
845 excess -= extra_bytes; 859 excess -= extra_bytes;
846 first_heap->bloc_start 860 first_heap->bloc_start
847 = (POINTER) MEM_ROUNDUP ((char *)first_heap->bloc_start - excess); 861 = (void *) MEM_ROUNDUP ((char *) first_heap->bloc_start - excess);
848 862
849 relocate_blocs (first_bloc, first_heap, first_heap->bloc_start); 863 relocate_blocs (first_bloc, first_heap, first_heap->bloc_start);
850 864
@@ -856,14 +870,14 @@ r_alloc_sbrk (long int size)
856 } 870 }
857 } 871 }
858 872
859 if ((char *)virtual_break_value + size < (char *)first_heap->start) 873 if ((char *) virtual_break_value + size < (char *) first_heap->start)
860 { 874 {
861 /* We found an additional space below the first heap */ 875 /* We found an additional space below the first heap */
862 first_heap->start = (POINTER) ((char *)virtual_break_value + size); 876 first_heap->start = (void *) ((char *) virtual_break_value + size);
863 } 877 }
864 } 878 }
865 879
866 virtual_break_value = (POINTER) ((char *)address + size); 880 virtual_break_value = (void *) ((char *) address + size);
867 break_value = (last_bloc 881 break_value = (last_bloc
868 ? (char *) last_bloc->data + last_bloc->size 882 ? (char *) last_bloc->data + last_bloc->size
869 : (char *) first_heap->bloc_start); 883 : (char *) first_heap->bloc_start);
@@ -885,10 +899,10 @@ r_alloc_sbrk (long int size)
885 If we can't allocate the necessary memory, set *PTR to zero, and 899 If we can't allocate the necessary memory, set *PTR to zero, and
886 return zero. */ 900 return zero. */
887 901
888POINTER 902void *
889r_alloc (POINTER *ptr, SIZE size) 903r_alloc (void **ptr, size_t size)
890{ 904{
891 register bloc_ptr new_bloc; 905 bloc_ptr new_bloc;
892 906
893 if (! r_alloc_initialized) 907 if (! r_alloc_initialized)
894 r_alloc_init (); 908 r_alloc_init ();
@@ -909,16 +923,16 @@ r_alloc (POINTER *ptr, SIZE size)
909 Store 0 in *PTR to show there's no block allocated. */ 923 Store 0 in *PTR to show there's no block allocated. */
910 924
911void 925void
912r_alloc_free (register POINTER *ptr) 926r_alloc_free (void **ptr)
913{ 927{
914 register bloc_ptr dead_bloc; 928 bloc_ptr dead_bloc;
915 929
916 if (! r_alloc_initialized) 930 if (! r_alloc_initialized)
917 r_alloc_init (); 931 r_alloc_init ();
918 932
919 dead_bloc = find_bloc (ptr); 933 dead_bloc = find_bloc (ptr);
920 if (dead_bloc == NIL_BLOC) 934 if (dead_bloc == NIL_BLOC)
921 abort (); /* Double free? PTR not originally used to allocate? */ 935 emacs_abort (); /* Double free? PTR not originally used to allocate? */
922 936
923 free_bloc (dead_bloc); 937 free_bloc (dead_bloc);
924 *ptr = 0; 938 *ptr = 0;
@@ -942,10 +956,10 @@ r_alloc_free (register POINTER *ptr)
942 If more memory cannot be allocated, then leave *PTR unchanged, and 956 If more memory cannot be allocated, then leave *PTR unchanged, and
943 return zero. */ 957 return zero. */
944 958
945POINTER 959void *
946r_re_alloc (POINTER *ptr, SIZE size) 960r_re_alloc (void **ptr, size_t size)
947{ 961{
948 register bloc_ptr bloc; 962 bloc_ptr bloc;
949 963
950 if (! r_alloc_initialized) 964 if (! r_alloc_initialized)
951 r_alloc_init (); 965 r_alloc_init ();
@@ -960,7 +974,7 @@ r_re_alloc (POINTER *ptr, SIZE size)
960 974
961 bloc = find_bloc (ptr); 975 bloc = find_bloc (ptr);
962 if (bloc == NIL_BLOC) 976 if (bloc == NIL_BLOC)
963 abort (); /* Already freed? PTR not originally used to allocate? */ 977 emacs_abort (); /* Already freed? PTR not originally used to allocate? */
964 978
965 if (size < bloc->size) 979 if (size < bloc->size)
966 { 980 {
@@ -984,15 +998,15 @@ r_re_alloc (POINTER *ptr, SIZE size)
984 { 998 {
985 new_bloc->variable = ptr; 999 new_bloc->variable = ptr;
986 *ptr = new_bloc->data; 1000 *ptr = new_bloc->data;
987 bloc->variable = (POINTER *) NIL; 1001 bloc->variable = NULL;
988 } 1002 }
989 else 1003 else
990 return NIL; 1004 return NULL;
991 } 1005 }
992 else 1006 else
993 { 1007 {
994 if (! resize_bloc (bloc, MEM_ROUNDUP (size))) 1008 if (! resize_bloc (bloc, MEM_ROUNDUP (size)))
995 return NIL; 1009 return NULL;
996 } 1010 }
997 } 1011 }
998 return *ptr; 1012 return *ptr;
@@ -1032,27 +1046,27 @@ r_alloc_check (void)
1032 return; 1046 return;
1033 1047
1034 assert (first_heap); 1048 assert (first_heap);
1035 assert (last_heap->end <= (POINTER) sbrk (0)); 1049 assert (last_heap->end <= (void *) sbrk (0));
1036 assert ((POINTER) first_heap < first_heap->start); 1050 assert ((void *) first_heap < first_heap->start);
1037 assert (first_heap->start <= virtual_break_value); 1051 assert (first_heap->start <= virtual_break_value);
1038 assert (virtual_break_value <= first_heap->end); 1052 assert (virtual_break_value <= first_heap->end);
1039 1053
1040 for (h = first_heap; h; h = h->next) 1054 for (h = first_heap; h; h = h->next)
1041 { 1055 {
1042 assert (h->prev == ph); 1056 assert (h->prev == ph);
1043 assert ((POINTER) ROUNDUP (h->end) == h->end); 1057 assert ((void *) ROUNDUP (h->end) == h->end);
1044#if 0 /* ??? The code in ralloc.c does not really try to ensure 1058#if 0 /* ??? The code in ralloc.c does not really try to ensure
1045 the heap start has any sort of alignment. 1059 the heap start has any sort of alignment.
1046 Perhaps it should. */ 1060 Perhaps it should. */
1047 assert ((POINTER) MEM_ROUNDUP (h->start) == h->start); 1061 assert ((void *) MEM_ROUNDUP (h->start) == h->start);
1048#endif 1062#endif
1049 assert ((POINTER) MEM_ROUNDUP (h->bloc_start) == h->bloc_start); 1063 assert ((void *) MEM_ROUNDUP (h->bloc_start) == h->bloc_start);
1050 assert (h->start <= h->bloc_start && h->bloc_start <= h->end); 1064 assert (h->start <= h->bloc_start && h->bloc_start <= h->end);
1051 1065
1052 if (ph) 1066 if (ph)
1053 { 1067 {
1054 assert (ph->end < h->start); 1068 assert (ph->end < h->start);
1055 assert (h->start <= (POINTER)h && (POINTER)(h+1) <= h->bloc_start); 1069 assert (h->start <= (void *) h && (void *) (h + 1) <= h->bloc_start);
1056 } 1070 }
1057 1071
1058 if (h->bloc_start <= break_value && break_value <= h->end) 1072 if (h->bloc_start <= break_value && break_value <= h->end)
@@ -1067,8 +1081,8 @@ r_alloc_check (void)
1067 for (b = first_bloc; b; b = b->next) 1081 for (b = first_bloc; b; b = b->next)
1068 { 1082 {
1069 assert (b->prev == pb); 1083 assert (b->prev == pb);
1070 assert ((POINTER) MEM_ROUNDUP (b->data) == b->data); 1084 assert ((void *) MEM_ROUNDUP (b->data) == b->data);
1071 assert ((SIZE) MEM_ROUNDUP (b->size) == b->size); 1085 assert ((size_t) MEM_ROUNDUP (b->size) == b->size);
1072 1086
1073 ph = 0; 1087 ph = 0;
1074 for (h = first_heap; h; h = h->next) 1088 for (h = first_heap; h; h = h->next)
@@ -1117,7 +1131,7 @@ r_alloc_check (void)
1117 is checked to ensure that memory corruption does not occur due to 1131 is checked to ensure that memory corruption does not occur due to
1118 misuse. */ 1132 misuse. */
1119void 1133void
1120r_alloc_reset_variable (POINTER *old, POINTER *new) 1134r_alloc_reset_variable (void **old, void **new)
1121{ 1135{
1122 bloc_ptr bloc = first_bloc; 1136 bloc_ptr bloc = first_bloc;
1123 1137
@@ -1133,7 +1147,7 @@ r_alloc_reset_variable (POINTER *old, POINTER *new)
1133 } 1147 }
1134 1148
1135 if (bloc == NIL_BLOC || bloc->variable != old) 1149 if (bloc == NIL_BLOC || bloc->variable != old)
1136 abort (); /* Already freed? OLD not originally used to allocate? */ 1150 emacs_abort (); /* Already freed? OLD not originally used to allocate? */
1137 1151
1138 /* Update variable to point to the new location. */ 1152 /* Update variable to point to the new location. */
1139 bloc->variable = new; 1153 bloc->variable = new;
@@ -1142,12 +1156,12 @@ r_alloc_reset_variable (POINTER *old, POINTER *new)
1142void 1156void
1143r_alloc_inhibit_buffer_relocation (int inhibit) 1157r_alloc_inhibit_buffer_relocation (int inhibit)
1144{ 1158{
1145 if (use_relocatable_buffers < 0) 1159 if (use_relocatable_buffers > 1)
1146 use_relocatable_buffers = 0; 1160 use_relocatable_buffers = 1;
1147 if (inhibit) 1161 if (inhibit)
1148 use_relocatable_buffers++;
1149 else if (use_relocatable_buffers > 0)
1150 use_relocatable_buffers--; 1162 use_relocatable_buffers--;
1163 else if (use_relocatable_buffers < 1)
1164 use_relocatable_buffers++;
1151} 1165}
1152 1166
1153 1167
@@ -1172,27 +1186,33 @@ r_alloc_init (void)
1172 first_heap = last_heap = &heap_base; 1186 first_heap = last_heap = &heap_base;
1173 first_heap->next = first_heap->prev = NIL_HEAP; 1187 first_heap->next = first_heap->prev = NIL_HEAP;
1174 first_heap->start = first_heap->bloc_start 1188 first_heap->start = first_heap->bloc_start
1175 = virtual_break_value = break_value = (*real_morecore) (0); 1189 = virtual_break_value = break_value = real_morecore (0);
1176 if (break_value == NIL) 1190 if (break_value == NULL)
1177 abort (); 1191 emacs_abort ();
1178 1192
1179 extra_bytes = ROUNDUP (50000); 1193 extra_bytes = ROUNDUP (50000);
1180#endif 1194#endif
1181 1195
1182#ifdef DOUG_LEA_MALLOC 1196#ifdef DOUG_LEA_MALLOC
1183 BLOCK_INPUT; 1197 block_input ();
1184 mallopt (M_TOP_PAD, 64 * 4096); 1198 mallopt (M_TOP_PAD, 64 * 4096);
1185 UNBLOCK_INPUT; 1199 unblock_input ();
1186#else 1200#else
1187#ifndef SYSTEM_MALLOC 1201#ifndef SYSTEM_MALLOC
1188 /* Give GNU malloc's morecore some hysteresis 1202 /* Give GNU malloc's morecore some hysteresis so that we move all
1189 so that we move all the relocatable blocks much less often. */ 1203 the relocatable blocks much less often. The number used to be
1190 __malloc_extra_blocks = 64; 1204 64, but alloc.c would override that with 32 in code that was
1205 removed when SYNC_INPUT became the only input handling mode.
1206 That code was conditioned on !DOUG_LEA_MALLOC, so the call to
1207 mallopt above is left unchanged. (Actually, I think there's no
1208 system nowadays that uses DOUG_LEA_MALLOC and also uses
1209 REL_ALLOC.) */
1210 __malloc_extra_blocks = 32;
1191#endif 1211#endif
1192#endif 1212#endif
1193 1213
1194#ifndef SYSTEM_MALLOC 1214#ifndef SYSTEM_MALLOC
1195 first_heap->end = (POINTER) ROUNDUP (first_heap->start); 1215 first_heap->end = (void *) ROUNDUP (first_heap->start);
1196 1216
1197 /* The extra call to real_morecore guarantees that the end of the 1217 /* The extra call to real_morecore guarantees that the end of the
1198 address space is a multiple of page_size, even if page_size is 1218 address space is a multiple of page_size, even if page_size is
@@ -1200,7 +1220,7 @@ r_alloc_init (void)
1200 which page_size is stored. This allows a binary to be built on a 1220 which page_size is stored. This allows a binary to be built on a
1201 system with one page size and run on a system with a smaller page 1221 system with one page size and run on a system with a smaller page
1202 size. */ 1222 size. */
1203 (*real_morecore) ((char *) first_heap->end - (char *) first_heap->start); 1223 real_morecore ((char *) first_heap->end - (char *) first_heap->start);
1204 1224
1205 /* Clear the rest of the last page; this memory is in our address space 1225 /* Clear the rest of the last page; this memory is in our address space
1206 even though it is after the sbrk value. */ 1226 even though it is after the sbrk value. */