diff options
| author | Miles Bader | 2006-01-16 08:37:27 +0000 |
|---|---|---|
| committer | Miles Bader | 2006-01-16 08:37:27 +0000 |
| commit | 41882805d6711e32ac0f066119226d84dbdedc13 (patch) | |
| tree | 44f756cef3fbc4de2f229e93613a1a326da7f55d /src/alloc.c | |
| parent | 6a2bd1a5019d2130c87ac5cf17f1322bf614b624 (diff) | |
| parent | 28f74fdf77eaab2e9daf54e2d5b0b729c5201e4f (diff) | |
| download | emacs-41882805d6711e32ac0f066119226d84dbdedc13.tar.gz emacs-41882805d6711e32ac0f066119226d84dbdedc13.zip | |
Revision: miles@gnu.org--gnu-2005/emacs--unicode--0--patch-97
Merge from emacs--cvs-trunk--0
Patches applied:
* emacs--cvs-trunk--0 (patch 616-696)
- Add lisp/mh-e/.arch-inventory
- Update from CVS
- Merge from gnus--rel--5.10
- Update from CVS: lisp/smerge-mode.el: Add 'tools' to file keywords.
- lisp/gnus/ChangeLog: Remove duplicate entry
* gnus--rel--5.10 (patch 147-181)
- Update from CVS
- Merge from emacs--cvs-trunk--0
- Update from CVS: lisp/mml.el (mml-preview): Doc fix.
- Update from CVS: texi/message.texi: Fix default values.
- Update from CVS: texi/gnus.texi (RSS): Addition.
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 291 |
1 files changed, 216 insertions, 75 deletions
diff --git a/src/alloc.c b/src/alloc.c index 5d8b1c1a359..1ef8f97b040 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -66,6 +66,14 @@ Boston, MA 02110-1301, USA. */ | |||
| 66 | extern POINTER_TYPE *sbrk (); | 66 | extern POINTER_TYPE *sbrk (); |
| 67 | #endif | 67 | #endif |
| 68 | 68 | ||
| 69 | #ifdef HAVE_FCNTL_H | ||
| 70 | #define INCLUDED_FCNTL | ||
| 71 | #include <fcntl.h> | ||
| 72 | #endif | ||
| 73 | #ifndef O_WRONLY | ||
| 74 | #define O_WRONLY 1 | ||
| 75 | #endif | ||
| 76 | |||
| 69 | #ifdef DOUG_LEA_MALLOC | 77 | #ifdef DOUG_LEA_MALLOC |
| 70 | 78 | ||
| 71 | #include <malloc.h> | 79 | #include <malloc.h> |
| @@ -138,6 +146,8 @@ static pthread_mutex_t alloc_mutex; | |||
| 138 | 146 | ||
| 139 | static __malloc_size_t bytes_used_when_full; | 147 | static __malloc_size_t bytes_used_when_full; |
| 140 | 148 | ||
| 149 | static __malloc_size_t bytes_used_when_reconsidered; | ||
| 150 | |||
| 141 | /* Mark, unmark, query mark bit of a Lisp string. S must be a pointer | 151 | /* Mark, unmark, query mark bit of a Lisp string. S must be a pointer |
| 142 | to a struct Lisp_String. */ | 152 | to a struct Lisp_String. */ |
| 143 | 153 | ||
| @@ -182,6 +192,11 @@ EMACS_INT gc_relative_threshold; | |||
| 182 | 192 | ||
| 183 | static Lisp_Object Vgc_cons_percentage; | 193 | static Lisp_Object Vgc_cons_percentage; |
| 184 | 194 | ||
| 195 | /* Minimum number of bytes of consing since GC before next GC, | ||
| 196 | when memory is full. */ | ||
| 197 | |||
| 198 | EMACS_INT memory_full_cons_threshold; | ||
| 199 | |||
| 185 | /* Nonzero during GC. */ | 200 | /* Nonzero during GC. */ |
| 186 | 201 | ||
| 187 | int gc_in_progress; | 202 | int gc_in_progress; |
| @@ -213,11 +228,12 @@ static int total_free_conses, total_free_markers, total_free_symbols; | |||
| 213 | static int total_free_floats, total_floats; | 228 | static int total_free_floats, total_floats; |
| 214 | 229 | ||
| 215 | /* Points to memory space allocated as "spare", to be freed if we run | 230 | /* Points to memory space allocated as "spare", to be freed if we run |
| 216 | out of memory. */ | 231 | out of memory. We keep one large block, four cons-blocks, and |
| 232 | two string blocks. */ | ||
| 217 | 233 | ||
| 218 | static char *spare_memory; | 234 | char *spare_memory[7]; |
| 219 | 235 | ||
| 220 | /* Amount of spare memory to keep in reserve. */ | 236 | /* Amount of spare memory to keep in large reserve block. */ |
| 221 | 237 | ||
| 222 | #define SPARE_MEMORY (1 << 14) | 238 | #define SPARE_MEMORY (1 << 14) |
| 223 | 239 | ||
| @@ -350,6 +366,11 @@ enum mem_type | |||
| 350 | MEM_TYPE_WINDOW | 366 | MEM_TYPE_WINDOW |
| 351 | }; | 367 | }; |
| 352 | 368 | ||
| 369 | static POINTER_TYPE *lisp_align_malloc P_ ((size_t, enum mem_type)); | ||
| 370 | static POINTER_TYPE *lisp_malloc P_ ((size_t, enum mem_type)); | ||
| 371 | void refill_memory_reserve (); | ||
| 372 | |||
| 373 | |||
| 353 | #if GC_MARK_STACK || defined GC_MALLOC_CHECK | 374 | #if GC_MARK_STACK || defined GC_MALLOC_CHECK |
| 354 | 375 | ||
| 355 | #if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES | 376 | #if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES |
| @@ -450,6 +471,7 @@ static void mem_delete P_ ((struct mem_node *)); | |||
| 450 | static void mem_delete_fixup P_ ((struct mem_node *)); | 471 | static void mem_delete_fixup P_ ((struct mem_node *)); |
| 451 | static INLINE struct mem_node *mem_find P_ ((void *)); | 472 | static INLINE struct mem_node *mem_find P_ ((void *)); |
| 452 | 473 | ||
| 474 | |||
| 453 | #if GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS | 475 | #if GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS |
| 454 | static void check_gcpros P_ ((void)); | 476 | static void check_gcpros P_ ((void)); |
| 455 | #endif | 477 | #endif |
| @@ -510,57 +532,10 @@ display_malloc_warning () | |||
| 510 | 532 | ||
| 511 | 533 | ||
| 512 | #ifdef DOUG_LEA_MALLOC | 534 | #ifdef DOUG_LEA_MALLOC |
| 513 | # define BYTES_USED (mallinfo ().arena) | 535 | # define BYTES_USED (mallinfo ().uordblks) |
| 514 | #else | 536 | #else |
| 515 | # define BYTES_USED _bytes_used | 537 | # define BYTES_USED _bytes_used |
| 516 | #endif | 538 | #endif |
| 517 | |||
| 518 | |||
| 519 | /* Called if malloc returns zero. */ | ||
| 520 | |||
| 521 | void | ||
| 522 | memory_full () | ||
| 523 | { | ||
| 524 | Vmemory_full = Qt; | ||
| 525 | |||
| 526 | #ifndef SYSTEM_MALLOC | ||
| 527 | bytes_used_when_full = BYTES_USED; | ||
| 528 | #endif | ||
| 529 | |||
| 530 | /* The first time we get here, free the spare memory. */ | ||
| 531 | if (spare_memory) | ||
| 532 | { | ||
| 533 | free (spare_memory); | ||
| 534 | spare_memory = 0; | ||
| 535 | } | ||
| 536 | |||
| 537 | /* This used to call error, but if we've run out of memory, we could | ||
| 538 | get infinite recursion trying to build the string. */ | ||
| 539 | while (1) | ||
| 540 | Fsignal (Qnil, Vmemory_signal_data); | ||
| 541 | } | ||
| 542 | |||
| 543 | DEFUN ("memory-full-p", Fmemory_full_p, Smemory_full_p, 0, 0, 0, | ||
| 544 | doc: /* t if memory is nearly full, nil otherwise. */) | ||
| 545 | () | ||
| 546 | { | ||
| 547 | return (spare_memory ? Qnil : Qt); | ||
| 548 | } | ||
| 549 | |||
| 550 | /* If we released our reserve (due to running out of memory), | ||
| 551 | and we have a fair amount free once again, | ||
| 552 | try to set aside another reserve in case we run out once more. | ||
| 553 | |||
| 554 | This is called when a relocatable block is freed in ralloc.c. */ | ||
| 555 | |||
| 556 | void | ||
| 557 | refill_memory_reserve () | ||
| 558 | { | ||
| 559 | #ifndef SYSTEM_MALLOC | ||
| 560 | if (spare_memory == 0) | ||
| 561 | spare_memory = (char *) malloc ((size_t) SPARE_MEMORY); | ||
| 562 | #endif | ||
| 563 | } | ||
| 564 | 539 | ||
| 565 | /* Called if we can't allocate relocatable space for a buffer. */ | 540 | /* Called if we can't allocate relocatable space for a buffer. */ |
| 566 | 541 | ||
| @@ -578,8 +553,6 @@ buffer_memory_full () | |||
| 578 | memory_full (); | 553 | memory_full (); |
| 579 | #endif | 554 | #endif |
| 580 | 555 | ||
| 581 | Vmemory_full = Qt; | ||
| 582 | |||
| 583 | /* This used to call error, but if we've run out of memory, we could | 556 | /* This used to call error, but if we've run out of memory, we could |
| 584 | get infinite recursion trying to build the string. */ | 557 | get infinite recursion trying to build the string. */ |
| 585 | while (1) | 558 | while (1) |
| @@ -805,6 +778,9 @@ xfree (block) | |||
| 805 | BLOCK_INPUT; | 778 | BLOCK_INPUT; |
| 806 | free (block); | 779 | free (block); |
| 807 | UNBLOCK_INPUT; | 780 | UNBLOCK_INPUT; |
| 781 | /* We don't call refill_memory_reserve here | ||
| 782 | because that duplicates doing so in emacs_blocked_free | ||
| 783 | and the criterion should go there. */ | ||
| 808 | } | 784 | } |
| 809 | 785 | ||
| 810 | 786 | ||
| @@ -1178,6 +1154,8 @@ emacs_blocked_free (ptr, ptr2) | |||
| 1178 | void *ptr; | 1154 | void *ptr; |
| 1179 | const void *ptr2; | 1155 | const void *ptr2; |
| 1180 | { | 1156 | { |
| 1157 | EMACS_INT bytes_used_now; | ||
| 1158 | |||
| 1181 | BLOCK_INPUT_ALLOC; | 1159 | BLOCK_INPUT_ALLOC; |
| 1182 | 1160 | ||
| 1183 | #ifdef GC_MALLOC_CHECK | 1161 | #ifdef GC_MALLOC_CHECK |
| @@ -1206,14 +1184,15 @@ emacs_blocked_free (ptr, ptr2) | |||
| 1206 | /* If we released our reserve (due to running out of memory), | 1184 | /* If we released our reserve (due to running out of memory), |
| 1207 | and we have a fair amount free once again, | 1185 | and we have a fair amount free once again, |
| 1208 | try to set aside another reserve in case we run out once more. */ | 1186 | try to set aside another reserve in case we run out once more. */ |
| 1209 | if (spare_memory == 0 | 1187 | if (! NILP (Vmemory_full) |
| 1210 | /* Verify there is enough space that even with the malloc | 1188 | /* Verify there is enough space that even with the malloc |
| 1211 | hysteresis this call won't run out again. | 1189 | hysteresis this call won't run out again. |
| 1212 | The code here is correct as long as SPARE_MEMORY | 1190 | The code here is correct as long as SPARE_MEMORY |
| 1213 | is substantially larger than the block size malloc uses. */ | 1191 | is substantially larger than the block size malloc uses. */ |
| 1214 | && (bytes_used_when_full | 1192 | && (bytes_used_when_full |
| 1215 | > BYTES_USED + max (malloc_hysteresis, 4) * SPARE_MEMORY)) | 1193 | > ((bytes_used_when_reconsidered = BYTES_USED) |
| 1216 | spare_memory = (char *) malloc ((size_t) SPARE_MEMORY); | 1194 | + max (malloc_hysteresis, 4) * SPARE_MEMORY))) |
| 1195 | refill_memory_reserve (); | ||
| 1217 | 1196 | ||
| 1218 | __free_hook = emacs_blocked_free; | 1197 | __free_hook = emacs_blocked_free; |
| 1219 | UNBLOCK_INPUT_ALLOC; | 1198 | UNBLOCK_INPUT_ALLOC; |
| @@ -2560,7 +2539,7 @@ void | |||
| 2560 | free_float (ptr) | 2539 | free_float (ptr) |
| 2561 | struct Lisp_Float *ptr; | 2540 | struct Lisp_Float *ptr; |
| 2562 | { | 2541 | { |
| 2563 | *(struct Lisp_Float **)&ptr->data = float_free_list; | 2542 | ptr->u.chain = float_free_list; |
| 2564 | float_free_list = ptr; | 2543 | float_free_list = ptr; |
| 2565 | } | 2544 | } |
| 2566 | 2545 | ||
| @@ -2578,7 +2557,7 @@ make_float (float_value) | |||
| 2578 | /* We use the data field for chaining the free list | 2557 | /* We use the data field for chaining the free list |
| 2579 | so that we won't use the same field that has the mark bit. */ | 2558 | so that we won't use the same field that has the mark bit. */ |
| 2580 | XSETFLOAT (val, float_free_list); | 2559 | XSETFLOAT (val, float_free_list); |
| 2581 | float_free_list = *(struct Lisp_Float **)&float_free_list->data; | 2560 | float_free_list = float_free_list->u.chain; |
| 2582 | } | 2561 | } |
| 2583 | else | 2562 | else |
| 2584 | { | 2563 | { |
| @@ -2678,7 +2657,7 @@ void | |||
| 2678 | free_cons (ptr) | 2657 | free_cons (ptr) |
| 2679 | struct Lisp_Cons *ptr; | 2658 | struct Lisp_Cons *ptr; |
| 2680 | { | 2659 | { |
| 2681 | *(struct Lisp_Cons **)&ptr->cdr = cons_free_list; | 2660 | ptr->u.chain = cons_free_list; |
| 2682 | #if GC_MARK_STACK | 2661 | #if GC_MARK_STACK |
| 2683 | ptr->car = Vdead; | 2662 | ptr->car = Vdead; |
| 2684 | #endif | 2663 | #endif |
| @@ -2697,7 +2676,7 @@ DEFUN ("cons", Fcons, Scons, 2, 2, 0, | |||
| 2697 | /* We use the cdr for chaining the free list | 2676 | /* We use the cdr for chaining the free list |
| 2698 | so that we won't use the same field that has the mark bit. */ | 2677 | so that we won't use the same field that has the mark bit. */ |
| 2699 | XSETCONS (val, cons_free_list); | 2678 | XSETCONS (val, cons_free_list); |
| 2700 | cons_free_list = *(struct Lisp_Cons **)&cons_free_list->cdr; | 2679 | cons_free_list = cons_free_list->u.chain; |
| 2701 | } | 2680 | } |
| 2702 | else | 2681 | else |
| 2703 | { | 2682 | { |
| @@ -2732,7 +2711,7 @@ check_cons_list () | |||
| 2732 | struct Lisp_Cons *tail = cons_free_list; | 2711 | struct Lisp_Cons *tail = cons_free_list; |
| 2733 | 2712 | ||
| 2734 | while (tail) | 2713 | while (tail) |
| 2735 | tail = *(struct Lisp_Cons **)&tail->cdr; | 2714 | tail = tail->u.chain; |
| 2736 | #endif | 2715 | #endif |
| 2737 | } | 2716 | } |
| 2738 | 2717 | ||
| @@ -3126,7 +3105,7 @@ Its value and function definition are void, and its property list is nil. */) | |||
| 3126 | if (symbol_free_list) | 3105 | if (symbol_free_list) |
| 3127 | { | 3106 | { |
| 3128 | XSETSYMBOL (val, symbol_free_list); | 3107 | XSETSYMBOL (val, symbol_free_list); |
| 3129 | symbol_free_list = *(struct Lisp_Symbol **)&symbol_free_list->value; | 3108 | symbol_free_list = symbol_free_list->next; |
| 3130 | } | 3109 | } |
| 3131 | else | 3110 | else |
| 3132 | { | 3111 | { |
| @@ -3337,6 +3316,83 @@ make_event_array (nargs, args) | |||
| 3337 | 3316 | ||
| 3338 | 3317 | ||
| 3339 | /************************************************************************ | 3318 | /************************************************************************ |
| 3319 | Memory Full Handling | ||
| 3320 | ************************************************************************/ | ||
| 3321 | |||
| 3322 | |||
| 3323 | /* Called if malloc returns zero. */ | ||
| 3324 | |||
| 3325 | void | ||
| 3326 | memory_full () | ||
| 3327 | { | ||
| 3328 | int i; | ||
| 3329 | |||
| 3330 | Vmemory_full = Qt; | ||
| 3331 | |||
| 3332 | memory_full_cons_threshold = sizeof (struct cons_block); | ||
| 3333 | |||
| 3334 | /* The first time we get here, free the spare memory. */ | ||
| 3335 | for (i = 0; i < sizeof (spare_memory) / sizeof (char *); i++) | ||
| 3336 | if (spare_memory[i]) | ||
| 3337 | { | ||
| 3338 | if (i == 0) | ||
| 3339 | free (spare_memory[i]); | ||
| 3340 | else if (i >= 1 && i <= 4) | ||
| 3341 | lisp_align_free (spare_memory[i]); | ||
| 3342 | else | ||
| 3343 | lisp_free (spare_memory[i]); | ||
| 3344 | spare_memory[i] = 0; | ||
| 3345 | } | ||
| 3346 | |||
| 3347 | /* Record the space now used. When it decreases substantially, | ||
| 3348 | we can refill the memory reserve. */ | ||
| 3349 | #ifndef SYSTEM_MALLOC | ||
| 3350 | bytes_used_when_full = BYTES_USED; | ||
| 3351 | #endif | ||
| 3352 | |||
| 3353 | /* This used to call error, but if we've run out of memory, we could | ||
| 3354 | get infinite recursion trying to build the string. */ | ||
| 3355 | while (1) | ||
| 3356 | Fsignal (Qnil, Vmemory_signal_data); | ||
| 3357 | } | ||
| 3358 | |||
| 3359 | /* If we released our reserve (due to running out of memory), | ||
| 3360 | and we have a fair amount free once again, | ||
| 3361 | try to set aside another reserve in case we run out once more. | ||
| 3362 | |||
| 3363 | This is called when a relocatable block is freed in ralloc.c, | ||
| 3364 | and also directly from this file, in case we're not using ralloc.c. */ | ||
| 3365 | |||
| 3366 | void | ||
| 3367 | refill_memory_reserve () | ||
| 3368 | { | ||
| 3369 | #ifndef SYSTEM_MALLOC | ||
| 3370 | if (spare_memory[0] == 0) | ||
| 3371 | spare_memory[0] = (char *) malloc ((size_t) SPARE_MEMORY); | ||
| 3372 | if (spare_memory[1] == 0) | ||
| 3373 | spare_memory[1] = (char *) lisp_align_malloc (sizeof (struct cons_block), | ||
| 3374 | MEM_TYPE_CONS); | ||
| 3375 | if (spare_memory[2] == 0) | ||
| 3376 | spare_memory[2] = (char *) lisp_align_malloc (sizeof (struct cons_block), | ||
| 3377 | MEM_TYPE_CONS); | ||
| 3378 | if (spare_memory[3] == 0) | ||
| 3379 | spare_memory[3] = (char *) lisp_align_malloc (sizeof (struct cons_block), | ||
| 3380 | MEM_TYPE_CONS); | ||
| 3381 | if (spare_memory[4] == 0) | ||
| 3382 | spare_memory[4] = (char *) lisp_align_malloc (sizeof (struct cons_block), | ||
| 3383 | MEM_TYPE_CONS); | ||
| 3384 | if (spare_memory[5] == 0) | ||
| 3385 | spare_memory[5] = (char *) lisp_malloc (sizeof (struct string_block), | ||
| 3386 | MEM_TYPE_STRING); | ||
| 3387 | if (spare_memory[6] == 0) | ||
| 3388 | spare_memory[6] = (char *) lisp_malloc (sizeof (struct string_block), | ||
| 3389 | MEM_TYPE_STRING); | ||
| 3390 | if (spare_memory[0] && spare_memory[1] && spare_memory[5]) | ||
| 3391 | Vmemory_full = Qnil; | ||
| 3392 | #endif | ||
| 3393 | } | ||
| 3394 | |||
| 3395 | /************************************************************************ | ||
| 3340 | C Stack Marking | 3396 | C Stack Marking |
| 3341 | ************************************************************************/ | 3397 | ************************************************************************/ |
| 3342 | 3398 | ||
| @@ -4393,10 +4449,96 @@ mark_stack () | |||
| 4393 | #endif | 4449 | #endif |
| 4394 | } | 4450 | } |
| 4395 | 4451 | ||
| 4396 | |||
| 4397 | #endif /* GC_MARK_STACK != 0 */ | 4452 | #endif /* GC_MARK_STACK != 0 */ |
| 4398 | 4453 | ||
| 4399 | 4454 | ||
| 4455 | |||
| 4456 | /* Return 1 if OBJ is a valid lisp object. | ||
| 4457 | Return 0 if OBJ is NOT a valid lisp object. | ||
| 4458 | Return -1 if we cannot validate OBJ. | ||
| 4459 | This function can be quite slow, | ||
| 4460 | so it should only be used in code for manual debugging. */ | ||
| 4461 | |||
| 4462 | int | ||
| 4463 | valid_lisp_object_p (obj) | ||
| 4464 | Lisp_Object obj; | ||
| 4465 | { | ||
| 4466 | void *p; | ||
| 4467 | #if !GC_MARK_STACK | ||
| 4468 | int fd; | ||
| 4469 | #else | ||
| 4470 | struct mem_node *m; | ||
| 4471 | #endif | ||
| 4472 | |||
| 4473 | if (INTEGERP (obj)) | ||
| 4474 | return 1; | ||
| 4475 | |||
| 4476 | p = (void *) XPNTR (obj); | ||
| 4477 | if (PURE_POINTER_P (p)) | ||
| 4478 | return 1; | ||
| 4479 | |||
| 4480 | #if !GC_MARK_STACK | ||
| 4481 | /* We need to determine whether it is safe to access memory at | ||
| 4482 | address P. Obviously, we cannot just access it (we would SEGV | ||
| 4483 | trying), so we trick the o/s to tell us whether p is a valid | ||
| 4484 | pointer. Unfortunately, we cannot use NULL_DEVICE here, as | ||
| 4485 | emacs_write may not validate p in that case. */ | ||
| 4486 | if ((fd = emacs_open ("__Valid__Lisp__Object__", O_CREAT | O_WRONLY | O_TRUNC, 0666)) >= 0) | ||
| 4487 | { | ||
| 4488 | int valid = (emacs_write (fd, (char *)p, 16) == 16); | ||
| 4489 | emacs_close (fd); | ||
| 4490 | unlink ("__Valid__Lisp__Object__"); | ||
| 4491 | return valid; | ||
| 4492 | } | ||
| 4493 | |||
| 4494 | return -1; | ||
| 4495 | #else | ||
| 4496 | |||
| 4497 | m = mem_find (p); | ||
| 4498 | |||
| 4499 | if (m == MEM_NIL) | ||
| 4500 | return 0; | ||
| 4501 | |||
| 4502 | switch (m->type) | ||
| 4503 | { | ||
| 4504 | case MEM_TYPE_NON_LISP: | ||
| 4505 | return 0; | ||
| 4506 | |||
| 4507 | case MEM_TYPE_BUFFER: | ||
| 4508 | return live_buffer_p (m, p); | ||
| 4509 | |||
| 4510 | case MEM_TYPE_CONS: | ||
| 4511 | return live_cons_p (m, p); | ||
| 4512 | |||
| 4513 | case MEM_TYPE_STRING: | ||
| 4514 | return live_string_p (m, p); | ||
| 4515 | |||
| 4516 | case MEM_TYPE_MISC: | ||
| 4517 | return live_misc_p (m, p); | ||
| 4518 | |||
| 4519 | case MEM_TYPE_SYMBOL: | ||
| 4520 | return live_symbol_p (m, p); | ||
| 4521 | |||
| 4522 | case MEM_TYPE_FLOAT: | ||
| 4523 | return live_float_p (m, p); | ||
| 4524 | |||
| 4525 | case MEM_TYPE_VECTOR: | ||
| 4526 | case MEM_TYPE_PROCESS: | ||
| 4527 | case MEM_TYPE_HASH_TABLE: | ||
| 4528 | case MEM_TYPE_FRAME: | ||
| 4529 | case MEM_TYPE_WINDOW: | ||
| 4530 | return live_vector_p (m, p); | ||
| 4531 | |||
| 4532 | default: | ||
| 4533 | break; | ||
| 4534 | } | ||
| 4535 | |||
| 4536 | return 0; | ||
| 4537 | #endif | ||
| 4538 | } | ||
| 4539 | |||
| 4540 | |||
| 4541 | |||
| 4400 | 4542 | ||
| 4401 | /*********************************************************************** | 4543 | /*********************************************************************** |
| 4402 | Pure Storage Management | 4544 | Pure Storage Management |
| @@ -4876,7 +5018,7 @@ returns nil, because real GC can't be done. */) | |||
| 4876 | total += total_floats * sizeof (struct Lisp_Float); | 5018 | total += total_floats * sizeof (struct Lisp_Float); |
| 4877 | total += total_intervals * sizeof (struct interval); | 5019 | total += total_intervals * sizeof (struct interval); |
| 4878 | total += total_strings * sizeof (struct Lisp_String); | 5020 | total += total_strings * sizeof (struct Lisp_String); |
| 4879 | 5021 | ||
| 4880 | gc_relative_threshold = total * XFLOAT_DATA (Vgc_cons_percentage); | 5022 | gc_relative_threshold = total * XFLOAT_DATA (Vgc_cons_percentage); |
| 4881 | } | 5023 | } |
| 4882 | else | 5024 | else |
| @@ -5403,14 +5545,14 @@ mark_object (arg) | |||
| 5403 | CHECK_ALLOCATED_AND_LIVE (live_cons_p); | 5545 | CHECK_ALLOCATED_AND_LIVE (live_cons_p); |
| 5404 | CONS_MARK (ptr); | 5546 | CONS_MARK (ptr); |
| 5405 | /* If the cdr is nil, avoid recursion for the car. */ | 5547 | /* If the cdr is nil, avoid recursion for the car. */ |
| 5406 | if (EQ (ptr->cdr, Qnil)) | 5548 | if (EQ (ptr->u.cdr, Qnil)) |
| 5407 | { | 5549 | { |
| 5408 | obj = ptr->car; | 5550 | obj = ptr->car; |
| 5409 | cdr_count = 0; | 5551 | cdr_count = 0; |
| 5410 | goto loop; | 5552 | goto loop; |
| 5411 | } | 5553 | } |
| 5412 | mark_object (ptr->car); | 5554 | mark_object (ptr->car); |
| 5413 | obj = ptr->cdr; | 5555 | obj = ptr->u.cdr; |
| 5414 | cdr_count++; | 5556 | cdr_count++; |
| 5415 | if (cdr_count == mark_object_loop_halt) | 5557 | if (cdr_count == mark_object_loop_halt) |
| 5416 | abort (); | 5558 | abort (); |
| @@ -5557,7 +5699,7 @@ gc_sweep () | |||
| 5557 | if (!CONS_MARKED_P (&cblk->conses[i])) | 5699 | if (!CONS_MARKED_P (&cblk->conses[i])) |
| 5558 | { | 5700 | { |
| 5559 | this_free++; | 5701 | this_free++; |
| 5560 | *(struct Lisp_Cons **)&cblk->conses[i].cdr = cons_free_list; | 5702 | cblk->conses[i].u.chain = cons_free_list; |
| 5561 | cons_free_list = &cblk->conses[i]; | 5703 | cons_free_list = &cblk->conses[i]; |
| 5562 | #if GC_MARK_STACK | 5704 | #if GC_MARK_STACK |
| 5563 | cons_free_list->car = Vdead; | 5705 | cons_free_list->car = Vdead; |
| @@ -5576,7 +5718,7 @@ gc_sweep () | |||
| 5576 | { | 5718 | { |
| 5577 | *cprev = cblk->next; | 5719 | *cprev = cblk->next; |
| 5578 | /* Unhook from the free list. */ | 5720 | /* Unhook from the free list. */ |
| 5579 | cons_free_list = *(struct Lisp_Cons **) &cblk->conses[0].cdr; | 5721 | cons_free_list = cblk->conses[0].u.chain; |
| 5580 | lisp_align_free (cblk); | 5722 | lisp_align_free (cblk); |
| 5581 | n_cons_blocks--; | 5723 | n_cons_blocks--; |
| 5582 | } | 5724 | } |
| @@ -5607,7 +5749,7 @@ gc_sweep () | |||
| 5607 | if (!FLOAT_MARKED_P (&fblk->floats[i])) | 5749 | if (!FLOAT_MARKED_P (&fblk->floats[i])) |
| 5608 | { | 5750 | { |
| 5609 | this_free++; | 5751 | this_free++; |
| 5610 | *(struct Lisp_Float **)&fblk->floats[i].data = float_free_list; | 5752 | fblk->floats[i].u.chain = float_free_list; |
| 5611 | float_free_list = &fblk->floats[i]; | 5753 | float_free_list = &fblk->floats[i]; |
| 5612 | } | 5754 | } |
| 5613 | else | 5755 | else |
| @@ -5623,7 +5765,7 @@ gc_sweep () | |||
| 5623 | { | 5765 | { |
| 5624 | *fprev = fblk->next; | 5766 | *fprev = fblk->next; |
| 5625 | /* Unhook from the free list. */ | 5767 | /* Unhook from the free list. */ |
| 5626 | float_free_list = *(struct Lisp_Float **) &fblk->floats[0].data; | 5768 | float_free_list = fblk->floats[0].u.chain; |
| 5627 | lisp_align_free (fblk); | 5769 | lisp_align_free (fblk); |
| 5628 | n_float_blocks--; | 5770 | n_float_blocks--; |
| 5629 | } | 5771 | } |
| @@ -5711,7 +5853,7 @@ gc_sweep () | |||
| 5711 | 5853 | ||
| 5712 | if (!sym->gcmarkbit && !pure_p) | 5854 | if (!sym->gcmarkbit && !pure_p) |
| 5713 | { | 5855 | { |
| 5714 | *(struct Lisp_Symbol **) &sym->value = symbol_free_list; | 5856 | sym->next = symbol_free_list; |
| 5715 | symbol_free_list = sym; | 5857 | symbol_free_list = sym; |
| 5716 | #if GC_MARK_STACK | 5858 | #if GC_MARK_STACK |
| 5717 | symbol_free_list->function = Vdead; | 5859 | symbol_free_list->function = Vdead; |
| @@ -5735,7 +5877,7 @@ gc_sweep () | |||
| 5735 | { | 5877 | { |
| 5736 | *sprev = sblk->next; | 5878 | *sprev = sblk->next; |
| 5737 | /* Unhook from the free list. */ | 5879 | /* Unhook from the free list. */ |
| 5738 | symbol_free_list = *(struct Lisp_Symbol **)&sblk->symbols[0].value; | 5880 | symbol_free_list = sblk->symbols[0].next; |
| 5739 | lisp_free (sblk); | 5881 | lisp_free (sblk); |
| 5740 | n_symbol_blocks--; | 5882 | n_symbol_blocks--; |
| 5741 | } | 5883 | } |
| @@ -5963,7 +6105,7 @@ init_alloc_once () | |||
| 5963 | malloc_hysteresis = 0; | 6105 | malloc_hysteresis = 0; |
| 5964 | #endif | 6106 | #endif |
| 5965 | 6107 | ||
| 5966 | spare_memory = (char *) malloc (SPARE_MEMORY); | 6108 | refill_memory_reserve (); |
| 5967 | 6109 | ||
| 5968 | ignore_warnings = 0; | 6110 | ignore_warnings = 0; |
| 5969 | gcprolist = 0; | 6111 | gcprolist = 0; |
| @@ -6064,7 +6206,7 @@ This means that certain objects should be allocated in shared (pure) space. */) | |||
| 6064 | build_string ("Memory exhausted--use M-x save-some-buffers then exit and restart Emacs")); | 6206 | build_string ("Memory exhausted--use M-x save-some-buffers then exit and restart Emacs")); |
| 6065 | 6207 | ||
| 6066 | DEFVAR_LISP ("memory-full", &Vmemory_full, | 6208 | DEFVAR_LISP ("memory-full", &Vmemory_full, |
| 6067 | doc: /* Non-nil means we are handling a memory-full error. */); | 6209 | doc: /* Non-nil means Emacs cannot get much more Lisp memory. */); |
| 6068 | Vmemory_full = Qnil; | 6210 | Vmemory_full = Qnil; |
| 6069 | 6211 | ||
| 6070 | staticpro (&Qgc_cons_threshold); | 6212 | staticpro (&Qgc_cons_threshold); |
| @@ -6079,7 +6221,6 @@ The time is in seconds as a floating point value. */); | |||
| 6079 | DEFVAR_INT ("gcs-done", &gcs_done, | 6221 | DEFVAR_INT ("gcs-done", &gcs_done, |
| 6080 | doc: /* Accumulated number of garbage collections done. */); | 6222 | doc: /* Accumulated number of garbage collections done. */); |
| 6081 | 6223 | ||
| 6082 | defsubr (&Smemory_full_p); | ||
| 6083 | defsubr (&Scons); | 6224 | defsubr (&Scons); |
| 6084 | defsubr (&Slist); | 6225 | defsubr (&Slist); |
| 6085 | defsubr (&Svector); | 6226 | defsubr (&Svector); |