diff options
| author | Eli Zaretskii | 2013-03-28 20:13:59 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2013-03-28 20:13:59 +0200 |
| commit | d76bf86f438d4f5f9fe493ab76f02ffc78f3ae2e (patch) | |
| tree | 04fa8bc7bd2058a316a7ee30f8741d25bfd0b060 /src/alloc.c | |
| parent | 2ef26ceb192c7683754cf0b4aa3087f501254332 (diff) | |
| parent | e74aeda863cd6896e06e92586f87b45d63d67d15 (diff) | |
| download | emacs-d76bf86f438d4f5f9fe493ab76f02ffc78f3ae2e.tar.gz emacs-d76bf86f438d4f5f9fe493ab76f02ffc78f3ae2e.zip | |
Merge from trunk and resolve conflicts.
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 215 |
1 files changed, 125 insertions, 90 deletions
diff --git a/src/alloc.c b/src/alloc.c index 28c9b51dab4..0a7950273f6 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* Storage allocation and gc for GNU Emacs Lisp interpreter. | 1 | /* Storage allocation and gc for GNU Emacs Lisp interpreter. |
| 2 | 2 | ||
| 3 | Copyright (C) 1985-1986, 1988, 1993-1995, 1997-2012 | 3 | Copyright (C) 1985-1986, 1988, 1993-1995, 1997-2013 Free Software |
| 4 | Free Software Foundation, Inc. | 4 | Foundation, Inc. |
| 5 | 5 | ||
| 6 | This file is part of GNU Emacs. | 6 | This file is part of GNU Emacs. |
| 7 | 7 | ||
| @@ -26,7 +26,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 26 | #include <limits.h> /* For CHAR_BIT. */ | 26 | #include <limits.h> /* For CHAR_BIT. */ |
| 27 | 27 | ||
| 28 | #ifdef ENABLE_CHECKING | 28 | #ifdef ENABLE_CHECKING |
| 29 | #include <signal.h> /* For SIGABRT. */ | 29 | #include <signal.h> /* For SIGABRT. */ |
| 30 | #endif | 30 | #endif |
| 31 | 31 | ||
| 32 | #ifdef HAVE_PTHREAD | 32 | #ifdef HAVE_PTHREAD |
| @@ -209,6 +209,7 @@ Lisp_Object Qchar_table_extra_slots; | |||
| 209 | 209 | ||
| 210 | static Lisp_Object Qpost_gc_hook; | 210 | static Lisp_Object Qpost_gc_hook; |
| 211 | 211 | ||
| 212 | static void free_save_value (Lisp_Object); | ||
| 212 | static void mark_terminals (void); | 213 | static void mark_terminals (void); |
| 213 | static void gc_sweep (void); | 214 | static void gc_sweep (void); |
| 214 | static Lisp_Object make_pure_vector (ptrdiff_t); | 215 | static Lisp_Object make_pure_vector (ptrdiff_t); |
| @@ -219,7 +220,6 @@ static void refill_memory_reserve (void); | |||
| 219 | #endif | 220 | #endif |
| 220 | static void compact_small_strings (void); | 221 | static void compact_small_strings (void); |
| 221 | static void free_large_strings (void); | 222 | static void free_large_strings (void); |
| 222 | static void free_misc (Lisp_Object); | ||
| 223 | extern Lisp_Object which_symbols (Lisp_Object, EMACS_INT) EXTERNALLY_VISIBLE; | 223 | extern Lisp_Object which_symbols (Lisp_Object, EMACS_INT) EXTERNALLY_VISIBLE; |
| 224 | 224 | ||
| 225 | /* When scanning the C stack for live Lisp objects, Emacs keeps track of | 225 | /* When scanning the C stack for live Lisp objects, Emacs keeps track of |
| @@ -323,20 +323,7 @@ static void *min_heap_address, *max_heap_address; | |||
| 323 | static struct mem_node mem_z; | 323 | static struct mem_node mem_z; |
| 324 | #define MEM_NIL &mem_z | 324 | #define MEM_NIL &mem_z |
| 325 | 325 | ||
| 326 | static struct Lisp_Vector *allocate_vectorlike (ptrdiff_t); | ||
| 327 | static void lisp_free (void *); | ||
| 328 | static void mark_stack (void); | ||
| 329 | static bool live_vector_p (struct mem_node *, void *); | ||
| 330 | static bool live_buffer_p (struct mem_node *, void *); | ||
| 331 | static bool live_string_p (struct mem_node *, void *); | ||
| 332 | static bool live_cons_p (struct mem_node *, void *); | ||
| 333 | static bool live_symbol_p (struct mem_node *, void *); | ||
| 334 | static bool live_float_p (struct mem_node *, void *); | ||
| 335 | static bool live_misc_p (struct mem_node *, void *); | ||
| 336 | static void mark_maybe_object (Lisp_Object); | ||
| 337 | static void mark_memory (void *, void *); | ||
| 338 | #if GC_MARK_STACK || defined GC_MALLOC_CHECK | 326 | #if GC_MARK_STACK || defined GC_MALLOC_CHECK |
| 339 | static void mem_init (void); | ||
| 340 | static struct mem_node *mem_insert (void *, void *, enum mem_type); | 327 | static struct mem_node *mem_insert (void *, void *, enum mem_type); |
| 341 | static void mem_insert_fixup (struct mem_node *); | 328 | static void mem_insert_fixup (struct mem_node *); |
| 342 | static void mem_rotate_left (struct mem_node *); | 329 | static void mem_rotate_left (struct mem_node *); |
| @@ -346,11 +333,6 @@ static void mem_delete_fixup (struct mem_node *); | |||
| 346 | static struct mem_node *mem_find (void *); | 333 | static struct mem_node *mem_find (void *); |
| 347 | #endif | 334 | #endif |
| 348 | 335 | ||
| 349 | |||
| 350 | #if GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS | ||
| 351 | static void check_gcpros (void); | ||
| 352 | #endif | ||
| 353 | |||
| 354 | #endif /* GC_MARK_STACK || GC_MALLOC_CHECK */ | 336 | #endif /* GC_MARK_STACK || GC_MALLOC_CHECK */ |
| 355 | 337 | ||
| 356 | #ifndef DEADP | 338 | #ifndef DEADP |
| @@ -422,11 +404,11 @@ buffer_memory_full (ptrdiff_t nbytes) | |||
| 422 | 404 | ||
| 423 | #ifndef REL_ALLOC | 405 | #ifndef REL_ALLOC |
| 424 | memory_full (nbytes); | 406 | memory_full (nbytes); |
| 425 | #endif | 407 | #else |
| 426 | |||
| 427 | /* This used to call error, but if we've run out of memory, we could | 408 | /* This used to call error, but if we've run out of memory, we could |
| 428 | get infinite recursion trying to build the string. */ | 409 | get infinite recursion trying to build the string. */ |
| 429 | xsignal (Qnil, Vmemory_signal_data); | 410 | xsignal (Qnil, Vmemory_signal_data); |
| 411 | #endif | ||
| 430 | } | 412 | } |
| 431 | 413 | ||
| 432 | /* A common multiple of the positive integers A and B. Ideally this | 414 | /* A common multiple of the positive integers A and B. Ideally this |
| @@ -761,13 +743,17 @@ xnrealloc (void *pa, ptrdiff_t nitems, ptrdiff_t item_size) | |||
| 761 | infinity. | 743 | infinity. |
| 762 | 744 | ||
| 763 | If PA is null, then allocate a new array instead of reallocating | 745 | If PA is null, then allocate a new array instead of reallocating |
| 764 | the old one. Thus, to grow an array A without saving its old | 746 | the old one. |
| 765 | contents, invoke xfree (A) immediately followed by xgrowalloc (0, | ||
| 766 | &NITEMS, ...). | ||
| 767 | 747 | ||
| 768 | Block interrupt input as needed. If memory exhaustion occurs, set | 748 | Block interrupt input as needed. If memory exhaustion occurs, set |
| 769 | *NITEMS to zero if PA is null, and signal an error (i.e., do not | 749 | *NITEMS to zero if PA is null, and signal an error (i.e., do not |
| 770 | return). */ | 750 | return). |
| 751 | |||
| 752 | Thus, to grow an array A without saving its old contents, do | ||
| 753 | { xfree (A); A = NULL; A = xpalloc (NULL, &AITEMS, ...); }. | ||
| 754 | The A = NULL avoids a dangling pointer if xpalloc exhausts memory | ||
| 755 | and signals an error, and later this code is reexecuted and | ||
| 756 | attempts to free A. */ | ||
| 771 | 757 | ||
| 772 | void * | 758 | void * |
| 773 | xpalloc (void *pa, ptrdiff_t *nitems, ptrdiff_t nitems_incr_min, | 759 | xpalloc (void *pa, ptrdiff_t *nitems, ptrdiff_t nitems_incr_min, |
| @@ -793,7 +779,7 @@ xpalloc (void *pa, ptrdiff_t *nitems, ptrdiff_t nitems_incr_min, | |||
| 793 | ptrdiff_t nitems_incr_max = n_max - n; | 779 | ptrdiff_t nitems_incr_max = n_max - n; |
| 794 | ptrdiff_t incr = max (nitems_incr_min, min (incr_estimate, nitems_incr_max)); | 780 | ptrdiff_t incr = max (nitems_incr_min, min (incr_estimate, nitems_incr_max)); |
| 795 | 781 | ||
| 796 | eassert (0 < item_size && 0 < nitems_incr_min && 0 <= n && -1 <= nitems_max); | 782 | eassert (item_size > 0 && nitems_incr_min > 0 && n >= 0 && nitems_max >= -1); |
| 797 | if (! pa) | 783 | if (! pa) |
| 798 | *nitems = 0; | 784 | *nitems = 0; |
| 799 | if (nitems_incr_max < incr) | 785 | if (nitems_incr_max < incr) |
| @@ -816,18 +802,22 @@ xstrdup (const char *s) | |||
| 816 | return p; | 802 | return p; |
| 817 | } | 803 | } |
| 818 | 804 | ||
| 805 | /* Like putenv, but (1) use the equivalent of xmalloc and (2) the | ||
| 806 | argument is a const pointer. */ | ||
| 807 | |||
| 808 | void | ||
| 809 | xputenv (char const *string) | ||
| 810 | { | ||
| 811 | if (putenv ((char *) string) != 0) | ||
| 812 | memory_full (0); | ||
| 813 | } | ||
| 819 | 814 | ||
| 820 | /* Unwind for SAFE_ALLOCA */ | 815 | /* Unwind for SAFE_ALLOCA */ |
| 821 | 816 | ||
| 822 | Lisp_Object | 817 | Lisp_Object |
| 823 | safe_alloca_unwind (Lisp_Object arg) | 818 | safe_alloca_unwind (Lisp_Object arg) |
| 824 | { | 819 | { |
| 825 | register struct Lisp_Save_Value *p = XSAVE_VALUE (arg); | 820 | free_save_value (arg); |
| 826 | |||
| 827 | p->dogc = 0; | ||
| 828 | xfree (p->pointer); | ||
| 829 | p->pointer = 0; | ||
| 830 | free_misc (arg); | ||
| 831 | return Qnil; | 821 | return Qnil; |
| 832 | } | 822 | } |
| 833 | 823 | ||
| @@ -837,7 +827,7 @@ void * | |||
| 837 | record_xmalloc (size_t size) | 827 | record_xmalloc (size_t size) |
| 838 | { | 828 | { |
| 839 | void *p = xmalloc (size); | 829 | void *p = xmalloc (size); |
| 840 | record_unwind_protect (safe_alloca_unwind, make_save_value (p, 0)); | 830 | record_unwind_protect (safe_alloca_unwind, make_save_pointer (p)); |
| 841 | return p; | 831 | return p; |
| 842 | } | 832 | } |
| 843 | 833 | ||
| @@ -1154,7 +1144,7 @@ lisp_align_free (void *block) | |||
| 1154 | #define INTERVAL_BLOCK_SIZE \ | 1144 | #define INTERVAL_BLOCK_SIZE \ |
| 1155 | ((1020 - sizeof (struct interval_block *)) / sizeof (struct interval)) | 1145 | ((1020 - sizeof (struct interval_block *)) / sizeof (struct interval)) |
| 1156 | 1146 | ||
| 1157 | /* Intervals are allocated in chunks in form of an interval_block | 1147 | /* Intervals are allocated in chunks in the form of an interval_block |
| 1158 | structure. */ | 1148 | structure. */ |
| 1159 | 1149 | ||
| 1160 | struct interval_block | 1150 | struct interval_block |
| @@ -1676,7 +1666,7 @@ allocate_string_data (struct Lisp_String *s, | |||
| 1676 | b = lisp_malloc (size + GC_STRING_EXTRA, MEM_TYPE_NON_LISP); | 1666 | b = lisp_malloc (size + GC_STRING_EXTRA, MEM_TYPE_NON_LISP); |
| 1677 | 1667 | ||
| 1678 | #ifdef DOUG_LEA_MALLOC | 1668 | #ifdef DOUG_LEA_MALLOC |
| 1679 | /* Back to a reasonable maximum of mmap'ed areas. */ | 1669 | /* Back to a reasonable maximum of mmap'ed areas. */ |
| 1680 | mallopt (M_MMAP_MAX, MMAP_MAX_AREAS); | 1670 | mallopt (M_MMAP_MAX, MMAP_MAX_AREAS); |
| 1681 | #endif | 1671 | #endif |
| 1682 | 1672 | ||
| @@ -1893,7 +1883,7 @@ compact_small_strings (void) | |||
| 1893 | 1883 | ||
| 1894 | #ifdef GC_CHECK_STRING_BYTES | 1884 | #ifdef GC_CHECK_STRING_BYTES |
| 1895 | /* Check that the string size recorded in the string is the | 1885 | /* Check that the string size recorded in the string is the |
| 1896 | same as the one recorded in the sdata structure. */ | 1886 | same as the one recorded in the sdata structure. */ |
| 1897 | if (s && string_bytes (s) != SDATA_NBYTES (from)) | 1887 | if (s && string_bytes (s) != SDATA_NBYTES (from)) |
| 1898 | emacs_abort (); | 1888 | emacs_abort (); |
| 1899 | #endif /* GC_CHECK_STRING_BYTES */ | 1889 | #endif /* GC_CHECK_STRING_BYTES */ |
| @@ -3097,13 +3087,10 @@ Any number of arguments, even zero arguments, are allowed. | |||
| 3097 | usage: (vector &rest OBJECTS) */) | 3087 | usage: (vector &rest OBJECTS) */) |
| 3098 | (ptrdiff_t nargs, Lisp_Object *args) | 3088 | (ptrdiff_t nargs, Lisp_Object *args) |
| 3099 | { | 3089 | { |
| 3100 | register Lisp_Object len, val; | ||
| 3101 | ptrdiff_t i; | 3090 | ptrdiff_t i; |
| 3102 | register struct Lisp_Vector *p; | 3091 | register Lisp_Object val = make_uninit_vector (nargs); |
| 3092 | register struct Lisp_Vector *p = XVECTOR (val); | ||
| 3103 | 3093 | ||
| 3104 | XSETFASTINT (len, nargs); | ||
| 3105 | val = Fmake_vector (len, Qnil); | ||
| 3106 | p = XVECTOR (val); | ||
| 3107 | for (i = 0; i < nargs; i++) | 3094 | for (i = 0; i < nargs; i++) |
| 3108 | p->contents[i] = args[i]; | 3095 | p->contents[i] = args[i]; |
| 3109 | return val; | 3096 | return val; |
| @@ -3141,9 +3128,9 @@ stack before executing the byte-code. | |||
| 3141 | usage: (make-byte-code ARGLIST BYTE-CODE CONSTANTS DEPTH &optional DOCSTRING INTERACTIVE-SPEC &rest ELEMENTS) */) | 3128 | usage: (make-byte-code ARGLIST BYTE-CODE CONSTANTS DEPTH &optional DOCSTRING INTERACTIVE-SPEC &rest ELEMENTS) */) |
| 3142 | (ptrdiff_t nargs, Lisp_Object *args) | 3129 | (ptrdiff_t nargs, Lisp_Object *args) |
| 3143 | { | 3130 | { |
| 3144 | register Lisp_Object len, val; | ||
| 3145 | ptrdiff_t i; | 3131 | ptrdiff_t i; |
| 3146 | register struct Lisp_Vector *p; | 3132 | register Lisp_Object val = make_uninit_vector (nargs); |
| 3133 | register struct Lisp_Vector *p = XVECTOR (val); | ||
| 3147 | 3134 | ||
| 3148 | /* We used to purecopy everything here, if purify-flag was set. This worked | 3135 | /* We used to purecopy everything here, if purify-flag was set. This worked |
| 3149 | OK for Emacs-23, but with Emacs-24's lexical binding code, it can be | 3136 | OK for Emacs-23, but with Emacs-24's lexical binding code, it can be |
| @@ -3153,10 +3140,6 @@ usage: (make-byte-code ARGLIST BYTE-CODE CONSTANTS DEPTH &optional DOCSTRING INT | |||
| 3153 | just wasteful and other times plainly wrong (e.g. those free vars may want | 3140 | just wasteful and other times plainly wrong (e.g. those free vars may want |
| 3154 | to be setcar'd). */ | 3141 | to be setcar'd). */ |
| 3155 | 3142 | ||
| 3156 | XSETFASTINT (len, nargs); | ||
| 3157 | val = Fmake_vector (len, Qnil); | ||
| 3158 | |||
| 3159 | p = XVECTOR (val); | ||
| 3160 | for (i = 0; i < nargs; i++) | 3143 | for (i = 0; i < nargs; i++) |
| 3161 | p->contents[i] = args[i]; | 3144 | p->contents[i] = args[i]; |
| 3162 | make_byte_code (p); | 3145 | make_byte_code (p); |
| @@ -3331,9 +3314,9 @@ allocate_misc (enum Lisp_Misc_Type type) | |||
| 3331 | return val; | 3314 | return val; |
| 3332 | } | 3315 | } |
| 3333 | 3316 | ||
| 3334 | /* Free a Lisp_Misc object */ | 3317 | /* Free a Lisp_Misc object. */ |
| 3335 | 3318 | ||
| 3336 | static void | 3319 | void |
| 3337 | free_misc (Lisp_Object misc) | 3320 | free_misc (Lisp_Object misc) |
| 3338 | { | 3321 | { |
| 3339 | XMISCTYPE (misc) = Lisp_Misc_Free; | 3322 | XMISCTYPE (misc) = Lisp_Misc_Free; |
| @@ -3343,24 +3326,75 @@ free_misc (Lisp_Object misc) | |||
| 3343 | total_free_markers++; | 3326 | total_free_markers++; |
| 3344 | } | 3327 | } |
| 3345 | 3328 | ||
| 3346 | /* Return a Lisp_Misc_Save_Value object containing POINTER and | 3329 | /* Verify properties of Lisp_Save_Value's representation |
| 3347 | INTEGER. This is used to package C values to call record_unwind_protect. | 3330 | that are assumed here and elsewhere. */ |
| 3348 | The unwind function can get the C values back using XSAVE_VALUE. */ | 3331 | |
| 3332 | verify (SAVE_UNUSED == 0); | ||
| 3333 | verify ((SAVE_INTEGER | SAVE_POINTER | SAVE_OBJECT) >> SAVE_SLOT_BITS == 0); | ||
| 3334 | |||
| 3335 | /* Return a Lisp_Save_Value object with the data saved according to | ||
| 3336 | DATA_TYPE. DATA_TYPE should be one of SAVE_TYPE_INT_INT, etc. */ | ||
| 3349 | 3337 | ||
| 3350 | Lisp_Object | 3338 | Lisp_Object |
| 3351 | make_save_value (void *pointer, ptrdiff_t integer) | 3339 | make_save_value (enum Lisp_Save_Type save_type, ...) |
| 3352 | { | 3340 | { |
| 3353 | register Lisp_Object val; | 3341 | va_list ap; |
| 3354 | register struct Lisp_Save_Value *p; | 3342 | int i; |
| 3343 | Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value); | ||
| 3344 | struct Lisp_Save_Value *p = XSAVE_VALUE (val); | ||
| 3345 | |||
| 3346 | eassert (0 < save_type | ||
| 3347 | && (save_type < 1 << (SAVE_TYPE_BITS - 1) | ||
| 3348 | || save_type == SAVE_TYPE_MEMORY)); | ||
| 3349 | p->save_type = save_type; | ||
| 3350 | va_start (ap, save_type); | ||
| 3351 | save_type &= ~ (1 << (SAVE_TYPE_BITS - 1)); | ||
| 3352 | |||
| 3353 | for (i = 0; save_type; i++, save_type >>= SAVE_SLOT_BITS) | ||
| 3354 | switch (save_type & ((1 << SAVE_SLOT_BITS) - 1)) | ||
| 3355 | { | ||
| 3356 | case SAVE_POINTER: | ||
| 3357 | p->data[i].pointer = va_arg (ap, void *); | ||
| 3358 | break; | ||
| 3359 | |||
| 3360 | case SAVE_INTEGER: | ||
| 3361 | p->data[i].integer = va_arg (ap, ptrdiff_t); | ||
| 3362 | break; | ||
| 3363 | |||
| 3364 | case SAVE_OBJECT: | ||
| 3365 | p->data[i].object = va_arg (ap, Lisp_Object); | ||
| 3366 | break; | ||
| 3367 | |||
| 3368 | default: | ||
| 3369 | emacs_abort (); | ||
| 3370 | } | ||
| 3371 | |||
| 3372 | va_end (ap); | ||
| 3373 | return val; | ||
| 3374 | } | ||
| 3375 | |||
| 3376 | /* The most common task it to save just one C pointer. */ | ||
| 3355 | 3377 | ||
| 3356 | val = allocate_misc (Lisp_Misc_Save_Value); | 3378 | Lisp_Object |
| 3357 | p = XSAVE_VALUE (val); | 3379 | make_save_pointer (void *pointer) |
| 3358 | p->pointer = pointer; | 3380 | { |
| 3359 | p->integer = integer; | 3381 | Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value); |
| 3360 | p->dogc = 0; | 3382 | struct Lisp_Save_Value *p = XSAVE_VALUE (val); |
| 3383 | p->save_type = SAVE_POINTER; | ||
| 3384 | p->data[0].pointer = pointer; | ||
| 3361 | return val; | 3385 | return val; |
| 3362 | } | 3386 | } |
| 3363 | 3387 | ||
| 3388 | /* Free a Lisp_Save_Value object. Do not use this function | ||
| 3389 | if SAVE contains pointer other than returned by xmalloc. */ | ||
| 3390 | |||
| 3391 | static void | ||
| 3392 | free_save_value (Lisp_Object save) | ||
| 3393 | { | ||
| 3394 | xfree (XSAVE_POINTER (save, 0)); | ||
| 3395 | free_misc (save); | ||
| 3396 | } | ||
| 3397 | |||
| 3364 | /* Return a Lisp_Misc_Overlay object with specified START, END and PLIST. */ | 3398 | /* Return a Lisp_Misc_Overlay object with specified START, END and PLIST. */ |
| 3365 | 3399 | ||
| 3366 | Lisp_Object | 3400 | Lisp_Object |
| @@ -4425,11 +4459,6 @@ mark_memory (void *start, void *end) | |||
| 4425 | } | 4459 | } |
| 4426 | } | 4460 | } |
| 4427 | 4461 | ||
| 4428 | /* setjmp will work with GCC unless NON_SAVING_SETJMP is defined in | ||
| 4429 | the GCC system configuration. In gcc 3.2, the only systems for | ||
| 4430 | which this is so are i386-sco5 non-ELF, i386-sysv3 (maybe included | ||
| 4431 | by others?) and ns32k-pc532-min. */ | ||
| 4432 | |||
| 4433 | #if !defined GC_SAVE_REGISTERS_ON_STACK && !defined GC_SETJMP_WORKS | 4462 | #if !defined GC_SAVE_REGISTERS_ON_STACK && !defined GC_SETJMP_WORKS |
| 4434 | 4463 | ||
| 4435 | static bool setjmp_tested_p; | 4464 | static bool setjmp_tested_p; |
| @@ -4700,12 +4729,12 @@ valid_pointer_p (void *p) | |||
| 4700 | #endif | 4729 | #endif |
| 4701 | } | 4730 | } |
| 4702 | 4731 | ||
| 4703 | /* Return 2 if OBJ is a killed or special buffer object. | 4732 | /* Return 2 if OBJ is a killed or special buffer object, 1 if OBJ is a |
| 4704 | Return 1 if OBJ is a valid lisp object. | 4733 | valid lisp object, 0 if OBJ is NOT a valid lisp object, or -1 if we |
| 4705 | Return 0 if OBJ is NOT a valid lisp object. | 4734 | cannot validate OBJ. This function can be quite slow, so its primary |
| 4706 | Return -1 if we cannot validate OBJ. | 4735 | use is the manual debugging. The only exception is print_object, where |
| 4707 | This function can be quite slow, | 4736 | we use it to check whether the memory referenced by the pointer of |
| 4708 | so it should only be used in code for manual debugging. */ | 4737 | Lisp_Save_Value object contains valid objects. */ |
| 4709 | 4738 | ||
| 4710 | int | 4739 | int |
| 4711 | valid_lisp_object_p (Lisp_Object obj) | 4740 | valid_lisp_object_p (Lisp_Object obj) |
| @@ -5347,7 +5376,7 @@ See Info node `(elisp)Garbage Collection'. */) | |||
| 5347 | double tot = total_bytes_of_live_objects (); | 5376 | double tot = total_bytes_of_live_objects (); |
| 5348 | 5377 | ||
| 5349 | tot *= XFLOAT_DATA (Vgc_cons_percentage); | 5378 | tot *= XFLOAT_DATA (Vgc_cons_percentage); |
| 5350 | if (0 < tot) | 5379 | if (tot > 0) |
| 5351 | { | 5380 | { |
| 5352 | if (tot < TYPE_MAXIMUM (EMACS_INT)) | 5381 | if (tot < TYPE_MAXIMUM (EMACS_INT)) |
| 5353 | gc_relative_threshold = tot; | 5382 | gc_relative_threshold = tot; |
| @@ -5781,14 +5810,13 @@ mark_object (Lisp_Object arg) | |||
| 5781 | case PVEC_WINDOW: | 5810 | case PVEC_WINDOW: |
| 5782 | { | 5811 | { |
| 5783 | struct window *w = (struct window *) ptr; | 5812 | struct window *w = (struct window *) ptr; |
| 5784 | bool leaf = NILP (w->hchild) && NILP (w->vchild); | ||
| 5785 | 5813 | ||
| 5786 | mark_vectorlike (ptr); | 5814 | mark_vectorlike (ptr); |
| 5787 | 5815 | ||
| 5788 | /* Mark glyphs for leaf windows. Marking window | 5816 | /* Mark glyph matrices, if any. Marking window |
| 5789 | matrices is sufficient because frame matrices | 5817 | matrices is sufficient because frame matrices |
| 5790 | use the same glyph memory. */ | 5818 | use the same glyph memory. */ |
| 5791 | if (leaf && w->current_matrix) | 5819 | if (w->current_matrix) |
| 5792 | { | 5820 | { |
| 5793 | mark_glyph_matrix (w->current_matrix); | 5821 | mark_glyph_matrix (w->current_matrix); |
| 5794 | mark_glyph_matrix (w->desired_matrix); | 5822 | mark_glyph_matrix (w->desired_matrix); |
| @@ -5919,20 +5947,27 @@ mark_object (Lisp_Object arg) | |||
| 5919 | 5947 | ||
| 5920 | case Lisp_Misc_Save_Value: | 5948 | case Lisp_Misc_Save_Value: |
| 5921 | XMISCANY (obj)->gcmarkbit = 1; | 5949 | XMISCANY (obj)->gcmarkbit = 1; |
| 5922 | #if GC_MARK_STACK | ||
| 5923 | { | 5950 | { |
| 5924 | register struct Lisp_Save_Value *ptr = XSAVE_VALUE (obj); | 5951 | struct Lisp_Save_Value *ptr = XSAVE_VALUE (obj); |
| 5925 | /* If DOGC is set, POINTER is the address of a memory | 5952 | /* If `save_type' is zero, `data[0].pointer' is the address |
| 5926 | area containing INTEGER potential Lisp_Objects. */ | 5953 | of a memory area containing `data[1].integer' potential |
| 5927 | if (ptr->dogc) | 5954 | Lisp_Objects. */ |
| 5955 | if (GC_MARK_STACK && ptr->save_type == SAVE_TYPE_MEMORY) | ||
| 5928 | { | 5956 | { |
| 5929 | Lisp_Object *p = (Lisp_Object *) ptr->pointer; | 5957 | Lisp_Object *p = ptr->data[0].pointer; |
| 5930 | ptrdiff_t nelt; | 5958 | ptrdiff_t nelt; |
| 5931 | for (nelt = ptr->integer; nelt > 0; nelt--, p++) | 5959 | for (nelt = ptr->data[1].integer; nelt > 0; nelt--, p++) |
| 5932 | mark_maybe_object (*p); | 5960 | mark_maybe_object (*p); |
| 5933 | } | 5961 | } |
| 5962 | else | ||
| 5963 | { | ||
| 5964 | /* Find Lisp_Objects in `data[N]' slots and mark them. */ | ||
| 5965 | int i; | ||
| 5966 | for (i = 0; i < SAVE_VALUE_SLOTS; i++) | ||
| 5967 | if (save_type (ptr, i) == SAVE_OBJECT) | ||
| 5968 | mark_object (ptr->data[i].object); | ||
| 5969 | } | ||
| 5934 | } | 5970 | } |
| 5935 | #endif | ||
| 5936 | break; | 5971 | break; |
| 5937 | 5972 | ||
| 5938 | case Lisp_Misc_Overlay: | 5973 | case Lisp_Misc_Overlay: |
| @@ -6488,7 +6523,7 @@ die (const char *msg, const char *file, int line) | |||
| 6488 | } | 6523 | } |
| 6489 | #endif | 6524 | #endif |
| 6490 | 6525 | ||
| 6491 | /* Initialization */ | 6526 | /* Initialization. */ |
| 6492 | 6527 | ||
| 6493 | void | 6528 | void |
| 6494 | init_alloc_once (void) | 6529 | init_alloc_once (void) |
| @@ -6503,9 +6538,9 @@ init_alloc_once (void) | |||
| 6503 | #endif | 6538 | #endif |
| 6504 | 6539 | ||
| 6505 | #ifdef DOUG_LEA_MALLOC | 6540 | #ifdef DOUG_LEA_MALLOC |
| 6506 | mallopt (M_TRIM_THRESHOLD, 128*1024); /* trim threshold */ | 6541 | mallopt (M_TRIM_THRESHOLD, 128 * 1024); /* Trim threshold. */ |
| 6507 | mallopt (M_MMAP_THRESHOLD, 64*1024); /* mmap threshold */ | 6542 | mallopt (M_MMAP_THRESHOLD, 64 * 1024); /* Mmap threshold. */ |
| 6508 | mallopt (M_MMAP_MAX, MMAP_MAX_AREAS); /* max. number of mmap'ed areas */ | 6543 | mallopt (M_MMAP_MAX, MMAP_MAX_AREAS); /* Max. number of mmap'ed areas. */ |
| 6509 | #endif | 6544 | #endif |
| 6510 | init_strings (); | 6545 | init_strings (); |
| 6511 | init_vectors (); | 6546 | init_vectors (); |