diff options
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 132 |
1 files changed, 48 insertions, 84 deletions
diff --git a/src/alloc.c b/src/alloc.c index e427c1f5676..ea7886dd4dc 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -155,6 +155,7 @@ int malloc_sbrk_unused; | |||
| 155 | 155 | ||
| 156 | EMACS_INT undo_limit; | 156 | EMACS_INT undo_limit; |
| 157 | EMACS_INT undo_strong_limit; | 157 | EMACS_INT undo_strong_limit; |
| 158 | EMACS_INT undo_outer_limit; | ||
| 158 | 159 | ||
| 159 | /* Number of live and free conses etc. */ | 160 | /* Number of live and free conses etc. */ |
| 160 | 161 | ||
| @@ -256,6 +257,7 @@ EMACS_INT gcs_done; /* accumulated GCs */ | |||
| 256 | 257 | ||
| 257 | static void mark_buffer P_ ((Lisp_Object)); | 258 | static void mark_buffer P_ ((Lisp_Object)); |
| 258 | extern void mark_kboards P_ ((void)); | 259 | extern void mark_kboards P_ ((void)); |
| 260 | extern void mark_backtrace P_ ((void)); | ||
| 259 | static void gc_sweep P_ ((void)); | 261 | static void gc_sweep P_ ((void)); |
| 260 | static void mark_glyph_matrix P_ ((struct glyph_matrix *)); | 262 | static void mark_glyph_matrix P_ ((struct glyph_matrix *)); |
| 261 | static void mark_face_cache P_ ((struct face_cache *)); | 263 | static void mark_face_cache P_ ((struct face_cache *)); |
| @@ -753,17 +755,20 @@ lisp_align_malloc (nbytes, type) | |||
| 753 | #ifdef HAVE_POSIX_MEMALIGN | 755 | #ifdef HAVE_POSIX_MEMALIGN |
| 754 | { | 756 | { |
| 755 | int err = posix_memalign (&base, BLOCK_ALIGN, ABLOCKS_BYTES); | 757 | int err = posix_memalign (&base, BLOCK_ALIGN, ABLOCKS_BYTES); |
| 756 | abase = err ? (base = NULL) : base; | 758 | if (err) |
| 759 | base = NULL; | ||
| 760 | abase = base; | ||
| 757 | } | 761 | } |
| 758 | #else | 762 | #else |
| 759 | base = malloc (ABLOCKS_BYTES); | 763 | base = malloc (ABLOCKS_BYTES); |
| 760 | abase = ALIGN (base, BLOCK_ALIGN); | 764 | abase = ALIGN (base, BLOCK_ALIGN); |
| 765 | #endif | ||
| 766 | |||
| 761 | if (base == 0) | 767 | if (base == 0) |
| 762 | { | 768 | { |
| 763 | UNBLOCK_INPUT; | 769 | UNBLOCK_INPUT; |
| 764 | memory_full (); | 770 | memory_full (); |
| 765 | } | 771 | } |
| 766 | #endif | ||
| 767 | 772 | ||
| 768 | aligned = (base == abase); | 773 | aligned = (base == abase); |
| 769 | if (!aligned) | 774 | if (!aligned) |
| @@ -844,7 +849,7 @@ lisp_align_free (block) | |||
| 844 | free_ablock = ablock; | 849 | free_ablock = ablock; |
| 845 | /* Update busy count. */ | 850 | /* Update busy count. */ |
| 846 | ABLOCKS_BUSY (abase) = (struct ablocks *) (-2 + (long) ABLOCKS_BUSY (abase)); | 851 | ABLOCKS_BUSY (abase) = (struct ablocks *) (-2 + (long) ABLOCKS_BUSY (abase)); |
| 847 | 852 | ||
| 848 | if (2 > (long) ABLOCKS_BUSY (abase)) | 853 | if (2 > (long) ABLOCKS_BUSY (abase)) |
| 849 | { /* All the blocks are free. */ | 854 | { /* All the blocks are free. */ |
| 850 | int i = 0, aligned = (long) ABLOCKS_BUSY (abase); | 855 | int i = 0, aligned = (long) ABLOCKS_BUSY (abase); |
| @@ -1893,8 +1898,9 @@ compact_small_strings () | |||
| 1893 | 1898 | ||
| 1894 | 1899 | ||
| 1895 | DEFUN ("make-string", Fmake_string, Smake_string, 2, 2, 0, | 1900 | DEFUN ("make-string", Fmake_string, Smake_string, 2, 2, 0, |
| 1896 | doc: /* Return a newly created string of length LENGTH, with each element being INIT. | 1901 | doc: /* Return a newly created string of length LENGTH, with INIT in each element. |
| 1897 | Both LENGTH and INIT must be numbers. */) | 1902 | LENGTH must be an integer. |
| 1903 | INIT must be an integer that represents a character. */) | ||
| 1898 | (length, init) | 1904 | (length, init) |
| 1899 | Lisp_Object length, init; | 1905 | Lisp_Object length, init; |
| 1900 | { | 1906 | { |
| @@ -1949,10 +1955,11 @@ LENGTH must be a number. INIT matters only in whether it is t or nil. */) | |||
| 1949 | 1955 | ||
| 1950 | CHECK_NATNUM (length); | 1956 | CHECK_NATNUM (length); |
| 1951 | 1957 | ||
| 1952 | bits_per_value = sizeof (EMACS_INT) * BITS_PER_CHAR; | 1958 | bits_per_value = sizeof (EMACS_INT) * BOOL_VECTOR_BITS_PER_CHAR; |
| 1953 | 1959 | ||
| 1954 | length_in_elts = (XFASTINT (length) + bits_per_value - 1) / bits_per_value; | 1960 | length_in_elts = (XFASTINT (length) + bits_per_value - 1) / bits_per_value; |
| 1955 | length_in_chars = ((XFASTINT (length) + BITS_PER_CHAR - 1) / BITS_PER_CHAR); | 1961 | length_in_chars = ((XFASTINT (length) + BOOL_VECTOR_BITS_PER_CHAR - 1) |
| 1962 | / BOOL_VECTOR_BITS_PER_CHAR); | ||
| 1956 | 1963 | ||
| 1957 | /* We must allocate one more elements than LENGTH_IN_ELTS for the | 1964 | /* We must allocate one more elements than LENGTH_IN_ELTS for the |
| 1958 | slot `size' of the struct Lisp_Bool_Vector. */ | 1965 | slot `size' of the struct Lisp_Bool_Vector. */ |
| @@ -1969,9 +1976,9 @@ LENGTH must be a number. INIT matters only in whether it is t or nil. */) | |||
| 1969 | p->data[i] = real_init; | 1976 | p->data[i] = real_init; |
| 1970 | 1977 | ||
| 1971 | /* Clear the extraneous bits in the last byte. */ | 1978 | /* Clear the extraneous bits in the last byte. */ |
| 1972 | if (XINT (length) != length_in_chars * BITS_PER_CHAR) | 1979 | if (XINT (length) != length_in_chars * BOOL_VECTOR_BITS_PER_CHAR) |
| 1973 | XBOOL_VECTOR (val)->data[length_in_chars - 1] | 1980 | XBOOL_VECTOR (val)->data[length_in_chars - 1] |
| 1974 | &= (1 << (XINT (length) % BITS_PER_CHAR)) - 1; | 1981 | &= (1 << (XINT (length) % BOOL_VECTOR_BITS_PER_CHAR)) - 1; |
| 1975 | 1982 | ||
| 1976 | return val; | 1983 | return val; |
| 1977 | } | 1984 | } |
| @@ -2333,7 +2340,6 @@ free_cons (ptr) | |||
| 2333 | cons_free_list = ptr; | 2340 | cons_free_list = ptr; |
| 2334 | } | 2341 | } |
| 2335 | 2342 | ||
| 2336 | |||
| 2337 | DEFUN ("cons", Fcons, Scons, 2, 2, 0, | 2343 | DEFUN ("cons", Fcons, Scons, 2, 2, 0, |
| 2338 | doc: /* Create a new cons, give it CAR and CDR as components, and return it. */) | 2344 | doc: /* Create a new cons, give it CAR and CDR as components, and return it. */) |
| 2339 | (car, cdr) | 2345 | (car, cdr) |
| @@ -4233,18 +4239,6 @@ struct catchtag | |||
| 4233 | struct catchtag *next; | 4239 | struct catchtag *next; |
| 4234 | }; | 4240 | }; |
| 4235 | 4241 | ||
| 4236 | struct backtrace | ||
| 4237 | { | ||
| 4238 | struct backtrace *next; | ||
| 4239 | Lisp_Object *function; | ||
| 4240 | Lisp_Object *args; /* Points to vector of args. */ | ||
| 4241 | int nargs; /* Length of vector. */ | ||
| 4242 | /* If nargs is UNEVALLED, args points to slot holding list of | ||
| 4243 | unevalled args. */ | ||
| 4244 | char evalargs; | ||
| 4245 | }; | ||
| 4246 | |||
| 4247 | |||
| 4248 | 4242 | ||
| 4249 | /*********************************************************************** | 4243 | /*********************************************************************** |
| 4250 | Protection from GC | 4244 | Protection from GC |
| @@ -4279,7 +4273,6 @@ returns nil, because real GC can't be done. */) | |||
| 4279 | register struct specbinding *bind; | 4273 | register struct specbinding *bind; |
| 4280 | struct catchtag *catch; | 4274 | struct catchtag *catch; |
| 4281 | struct handler *handler; | 4275 | struct handler *handler; |
| 4282 | register struct backtrace *backlist; | ||
| 4283 | char stack_top_variable; | 4276 | char stack_top_variable; |
| 4284 | register int i; | 4277 | register int i; |
| 4285 | int message_p; | 4278 | int message_p; |
| @@ -4348,7 +4341,7 @@ returns nil, because real GC can't be done. */) | |||
| 4348 | if (! EQ (nextb->undo_list, Qt)) | 4341 | if (! EQ (nextb->undo_list, Qt)) |
| 4349 | nextb->undo_list | 4342 | nextb->undo_list |
| 4350 | = truncate_undo_list (nextb->undo_list, undo_limit, | 4343 | = truncate_undo_list (nextb->undo_list, undo_limit, |
| 4351 | undo_strong_limit); | 4344 | undo_strong_limit, undo_outer_limit); |
| 4352 | 4345 | ||
| 4353 | /* Shrink buffer gaps, but skip indirect and dead buffers. */ | 4346 | /* Shrink buffer gaps, but skip indirect and dead buffers. */ |
| 4354 | if (nextb->base_buffer == 0 && !NILP (nextb->name)) | 4347 | if (nextb->base_buffer == 0 && !NILP (nextb->name)) |
| @@ -4408,20 +4401,23 @@ returns nil, because real GC can't be done. */) | |||
| 4408 | mark_object (handler->handler); | 4401 | mark_object (handler->handler); |
| 4409 | mark_object (handler->var); | 4402 | mark_object (handler->var); |
| 4410 | } | 4403 | } |
| 4411 | for (backlist = backtrace_list; backlist; backlist = backlist->next) | 4404 | mark_backtrace (); |
| 4412 | { | ||
| 4413 | mark_object (*backlist->function); | ||
| 4414 | |||
| 4415 | if (backlist->nargs == UNEVALLED || backlist->nargs == MANY) | ||
| 4416 | i = 0; | ||
| 4417 | else | ||
| 4418 | i = backlist->nargs - 1; | ||
| 4419 | for (; i >= 0; i--) | ||
| 4420 | mark_object (backlist->args[i]); | ||
| 4421 | } | ||
| 4422 | mark_kboards (); | 4405 | mark_kboards (); |
| 4423 | 4406 | ||
| 4424 | /* Look thru every buffer's undo list | 4407 | #if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES |
| 4408 | mark_stack (); | ||
| 4409 | #endif | ||
| 4410 | |||
| 4411 | #ifdef USE_GTK | ||
| 4412 | { | ||
| 4413 | extern void xg_mark_data (); | ||
| 4414 | xg_mark_data (); | ||
| 4415 | } | ||
| 4416 | #endif | ||
| 4417 | |||
| 4418 | /* Everything is now marked, except for the things that require special | ||
| 4419 | finalization, i.e. the undo_list. | ||
| 4420 | Look thru every buffer's undo list | ||
| 4425 | for elements that update markers that were not marked, | 4421 | for elements that update markers that were not marked, |
| 4426 | and delete them. */ | 4422 | and delete them. */ |
| 4427 | { | 4423 | { |
| @@ -4459,22 +4455,14 @@ returns nil, because real GC can't be done. */) | |||
| 4459 | } | 4455 | } |
| 4460 | } | 4456 | } |
| 4461 | } | 4457 | } |
| 4458 | /* Now that we have stripped the elements that need not be in the | ||
| 4459 | undo_list any more, we can finally mark the list. */ | ||
| 4460 | mark_object (nextb->undo_list); | ||
| 4462 | 4461 | ||
| 4463 | nextb = nextb->next; | 4462 | nextb = nextb->next; |
| 4464 | } | 4463 | } |
| 4465 | } | 4464 | } |
| 4466 | 4465 | ||
| 4467 | #if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES | ||
| 4468 | mark_stack (); | ||
| 4469 | #endif | ||
| 4470 | |||
| 4471 | #ifdef USE_GTK | ||
| 4472 | { | ||
| 4473 | extern void xg_mark_data (); | ||
| 4474 | xg_mark_data (); | ||
| 4475 | } | ||
| 4476 | #endif | ||
| 4477 | |||
| 4478 | gc_sweep (); | 4466 | gc_sweep (); |
| 4479 | 4467 | ||
| 4480 | /* Clear the mark bits that we set in certain root slots. */ | 4468 | /* Clear the mark bits that we set in certain root slots. */ |
| @@ -5043,41 +5031,9 @@ mark_buffer (buf) | |||
| 5043 | 5031 | ||
| 5044 | MARK_INTERVAL_TREE (BUF_INTERVALS (buffer)); | 5032 | MARK_INTERVAL_TREE (BUF_INTERVALS (buffer)); |
| 5045 | 5033 | ||
| 5046 | if (CONSP (buffer->undo_list)) | 5034 | /* For now, we just don't mark the undo_list. It's done later in |
| 5047 | { | 5035 | a special way just before the sweep phase, and after stripping |
| 5048 | Lisp_Object tail; | 5036 | some of its elements that are not needed any more. */ |
| 5049 | tail = buffer->undo_list; | ||
| 5050 | |||
| 5051 | /* We mark the undo list specially because | ||
| 5052 | its pointers to markers should be weak. */ | ||
| 5053 | |||
| 5054 | while (CONSP (tail)) | ||
| 5055 | { | ||
| 5056 | register struct Lisp_Cons *ptr = XCONS (tail); | ||
| 5057 | |||
| 5058 | if (CONS_MARKED_P (ptr)) | ||
| 5059 | break; | ||
| 5060 | CONS_MARK (ptr); | ||
| 5061 | if (GC_CONSP (ptr->car) | ||
| 5062 | && !CONS_MARKED_P (XCONS (ptr->car)) | ||
| 5063 | && GC_MARKERP (XCAR (ptr->car))) | ||
| 5064 | { | ||
| 5065 | CONS_MARK (XCONS (ptr->car)); | ||
| 5066 | mark_object (XCDR (ptr->car)); | ||
| 5067 | } | ||
| 5068 | else | ||
| 5069 | mark_object (ptr->car); | ||
| 5070 | |||
| 5071 | if (CONSP (ptr->cdr)) | ||
| 5072 | tail = ptr->cdr; | ||
| 5073 | else | ||
| 5074 | break; | ||
| 5075 | } | ||
| 5076 | |||
| 5077 | mark_object (XCDR (tail)); | ||
| 5078 | } | ||
| 5079 | else | ||
| 5080 | mark_object (buffer->undo_list); | ||
| 5081 | 5037 | ||
| 5082 | if (buffer->overlays_before) | 5038 | if (buffer->overlays_before) |
| 5083 | { | 5039 | { |
| @@ -5671,12 +5627,20 @@ which includes both saved text and other data. */); | |||
| 5671 | 5627 | ||
| 5672 | DEFVAR_INT ("undo-strong-limit", &undo_strong_limit, | 5628 | DEFVAR_INT ("undo-strong-limit", &undo_strong_limit, |
| 5673 | doc: /* Don't keep more than this much size of undo information. | 5629 | doc: /* Don't keep more than this much size of undo information. |
| 5674 | A command which pushes past this size is itself forgotten. | 5630 | A previous command which pushes the undo list past this size |
| 5675 | This limit is applied when garbage collection happens. | 5631 | is entirely forgotten when GC happens. |
| 5676 | The size is counted as the number of bytes occupied, | 5632 | The size is counted as the number of bytes occupied, |
| 5677 | which includes both saved text and other data. */); | 5633 | which includes both saved text and other data. */); |
| 5678 | undo_strong_limit = 30000; | 5634 | undo_strong_limit = 30000; |
| 5679 | 5635 | ||
| 5636 | DEFVAR_INT ("undo-outer-limit", &undo_outer_limit, | ||
| 5637 | doc: /* Don't keep more than this much size of undo information. | ||
| 5638 | If the current command has produced more than this much undo information, | ||
| 5639 | GC discards it. This is a last-ditch limit to prevent memory overflow. | ||
| 5640 | The size is counted as the number of bytes occupied, | ||
| 5641 | which includes both saved text and other data. */); | ||
| 5642 | undo_outer_limit = 300000; | ||
| 5643 | |||
| 5680 | DEFVAR_BOOL ("garbage-collection-messages", &garbage_collection_messages, | 5644 | DEFVAR_BOOL ("garbage-collection-messages", &garbage_collection_messages, |
| 5681 | doc: /* Non-nil means display messages at start and end of garbage collection. */); | 5645 | doc: /* Non-nil means display messages at start and end of garbage collection. */); |
| 5682 | garbage_collection_messages = 0; | 5646 | garbage_collection_messages = 0; |