diff options
| author | Eli Zaretskii | 2014-05-24 15:02:25 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2014-05-24 15:02:25 +0300 |
| commit | c94e3311ecf51bf3c6017ab4028debcae2a5dd6e (patch) | |
| tree | 3ffd9fdea9c001a76fd1166f4d158b32cf662ab3 /src/alloc.c | |
| parent | a235163a6908136abd3f4574caf6e8b9a0c7dcf9 (diff) | |
| download | emacs-c94e3311ecf51bf3c6017ab4028debcae2a5dd6e.tar.gz emacs-c94e3311ecf51bf3c6017ab4028debcae2a5dd6e.zip | |
Avoid marking too deep portions of stack in mark_stack.
src/alloc.c (garbage_collect_1): New function, with all of the guts
of Fgarbage_collect.
(mark_stack): Accept an argument END and don't mark Lisp objects
on the stack beyond the address given by END. Calculation of END
was moved to Fgarbage_collect.
(Fgarbage_collect): Calculate the end address of the stack portion
that needs to be examined by mark_stack, and pass that address to
garbage_collect_1, which will pass it to mark_stack. See
http://lists.gnu.org/archive/html/emacs-devel/2014-05/msg00270.html
for more details about the underlying problems. In particular,
this avoids dumping Emacs with the large hash-table whose value is
held in purify-flag for most of the time loadup.el runs.
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 160 |
1 files changed, 88 insertions, 72 deletions
diff --git a/src/alloc.c b/src/alloc.c index 1dc33b72520..d221cc7e967 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -4876,61 +4876,8 @@ dump_zombies (void) | |||
| 4876 | from the stack start. */ | 4876 | from the stack start. */ |
| 4877 | 4877 | ||
| 4878 | static void | 4878 | static void |
| 4879 | mark_stack (void) | 4879 | mark_stack (void *end) |
| 4880 | { | 4880 | { |
| 4881 | void *end; | ||
| 4882 | |||
| 4883 | #ifdef HAVE___BUILTIN_UNWIND_INIT | ||
| 4884 | /* Force callee-saved registers and register windows onto the stack. | ||
| 4885 | This is the preferred method if available, obviating the need for | ||
| 4886 | machine dependent methods. */ | ||
| 4887 | __builtin_unwind_init (); | ||
| 4888 | end = &end; | ||
| 4889 | #else /* not HAVE___BUILTIN_UNWIND_INIT */ | ||
| 4890 | #ifndef GC_SAVE_REGISTERS_ON_STACK | ||
| 4891 | /* jmp_buf may not be aligned enough on darwin-ppc64 */ | ||
| 4892 | union aligned_jmpbuf { | ||
| 4893 | Lisp_Object o; | ||
| 4894 | sys_jmp_buf j; | ||
| 4895 | } j; | ||
| 4896 | volatile bool stack_grows_down_p = (char *) &j > (char *) stack_base; | ||
| 4897 | #endif | ||
| 4898 | /* This trick flushes the register windows so that all the state of | ||
| 4899 | the process is contained in the stack. */ | ||
| 4900 | /* Fixme: Code in the Boehm GC suggests flushing (with `flushrs') is | ||
| 4901 | needed on ia64 too. See mach_dep.c, where it also says inline | ||
| 4902 | assembler doesn't work with relevant proprietary compilers. */ | ||
| 4903 | #ifdef __sparc__ | ||
| 4904 | #if defined (__sparc64__) && defined (__FreeBSD__) | ||
| 4905 | /* FreeBSD does not have a ta 3 handler. */ | ||
| 4906 | asm ("flushw"); | ||
| 4907 | #else | ||
| 4908 | asm ("ta 3"); | ||
| 4909 | #endif | ||
| 4910 | #endif | ||
| 4911 | |||
| 4912 | /* Save registers that we need to see on the stack. We need to see | ||
| 4913 | registers used to hold register variables and registers used to | ||
| 4914 | pass parameters. */ | ||
| 4915 | #ifdef GC_SAVE_REGISTERS_ON_STACK | ||
| 4916 | GC_SAVE_REGISTERS_ON_STACK (end); | ||
| 4917 | #else /* not GC_SAVE_REGISTERS_ON_STACK */ | ||
| 4918 | |||
| 4919 | #ifndef GC_SETJMP_WORKS /* If it hasn't been checked yet that | ||
| 4920 | setjmp will definitely work, test it | ||
| 4921 | and print a message with the result | ||
| 4922 | of the test. */ | ||
| 4923 | if (!setjmp_tested_p) | ||
| 4924 | { | ||
| 4925 | setjmp_tested_p = 1; | ||
| 4926 | test_setjmp (); | ||
| 4927 | } | ||
| 4928 | #endif /* GC_SETJMP_WORKS */ | ||
| 4929 | |||
| 4930 | sys_setjmp (j.j); | ||
| 4931 | end = stack_grows_down_p ? (char *) &j + sizeof j : (char *) &j; | ||
| 4932 | #endif /* not GC_SAVE_REGISTERS_ON_STACK */ | ||
| 4933 | #endif /* not HAVE___BUILTIN_UNWIND_INIT */ | ||
| 4934 | 4881 | ||
| 4935 | /* This assumes that the stack is a contiguous region in memory. If | 4882 | /* This assumes that the stack is a contiguous region in memory. If |
| 4936 | that's not the case, something has to be done here to iterate | 4883 | that's not the case, something has to be done here to iterate |
| @@ -5538,22 +5485,15 @@ mark_pinned_symbols (void) | |||
| 5538 | } | 5485 | } |
| 5539 | } | 5486 | } |
| 5540 | 5487 | ||
| 5541 | DEFUN ("garbage-collect", Fgarbage_collect, Sgarbage_collect, 0, 0, "", | 5488 | /* Subroutine of Fgarbage_collect that does most of the work. It is a |
| 5542 | doc: /* Reclaim storage for Lisp objects no longer needed. | 5489 | separate function so that we could limit mark_stack in searching |
| 5543 | Garbage collection happens automatically if you cons more than | 5490 | the stack frames below this function, thus avoiding the rare cases |
| 5544 | `gc-cons-threshold' bytes of Lisp data since previous garbage collection. | 5491 | where mark_stack finds values that look like live Lisp objects on |
| 5545 | `garbage-collect' normally returns a list with info on amount of space in use, | 5492 | portions of stack that couldn't possibly contain such live objects. |
| 5546 | where each entry has the form (NAME SIZE USED FREE), where: | 5493 | For more details of this, see the discussion at |
| 5547 | - NAME is a symbol describing the kind of objects this entry represents, | 5494 | http://lists.gnu.org/archive/html/emacs-devel/2014-05/msg00270.html. */ |
| 5548 | - SIZE is the number of bytes used by each one, | 5495 | static Lisp_Object |
| 5549 | - USED is the number of those objects that were found live in the heap, | 5496 | garbage_collect_1 (void *end) |
| 5550 | - FREE is the number of those objects that are not live but that Emacs | ||
| 5551 | keeps around for future allocations (maybe because it does not know how | ||
| 5552 | to return them to the OS). | ||
| 5553 | However, if there was overflow in pure space, `garbage-collect' | ||
| 5554 | returns nil, because real GC can't be done. | ||
| 5555 | See Info node `(elisp)Garbage Collection'. */) | ||
| 5556 | (void) | ||
| 5557 | { | 5497 | { |
| 5558 | struct buffer *nextb; | 5498 | struct buffer *nextb; |
| 5559 | char stack_top_variable; | 5499 | char stack_top_variable; |
| @@ -5651,7 +5591,7 @@ See Info node `(elisp)Garbage Collection'. */) | |||
| 5651 | 5591 | ||
| 5652 | #if (GC_MARK_STACK == GC_MAKE_GCPROS_NOOPS \ | 5592 | #if (GC_MARK_STACK == GC_MAKE_GCPROS_NOOPS \ |
| 5653 | || GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS) | 5593 | || GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS) |
| 5654 | mark_stack (); | 5594 | mark_stack (end); |
| 5655 | #else | 5595 | #else |
| 5656 | { | 5596 | { |
| 5657 | register struct gcpro *tail; | 5597 | register struct gcpro *tail; |
| @@ -5674,7 +5614,7 @@ See Info node `(elisp)Garbage Collection'. */) | |||
| 5674 | #endif | 5614 | #endif |
| 5675 | 5615 | ||
| 5676 | #if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES | 5616 | #if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES |
| 5677 | mark_stack (); | 5617 | mark_stack (end); |
| 5678 | #endif | 5618 | #endif |
| 5679 | 5619 | ||
| 5680 | /* Everything is now marked, except for the data in font caches | 5620 | /* Everything is now marked, except for the data in font caches |
| @@ -5834,6 +5774,82 @@ See Info node `(elisp)Garbage Collection'. */) | |||
| 5834 | return retval; | 5774 | return retval; |
| 5835 | } | 5775 | } |
| 5836 | 5776 | ||
| 5777 | DEFUN ("garbage-collect", Fgarbage_collect, Sgarbage_collect, 0, 0, "", | ||
| 5778 | doc: /* Reclaim storage for Lisp objects no longer needed. | ||
| 5779 | Garbage collection happens automatically if you cons more than | ||
| 5780 | `gc-cons-threshold' bytes of Lisp data since previous garbage collection. | ||
| 5781 | `garbage-collect' normally returns a list with info on amount of space in use, | ||
| 5782 | where each entry has the form (NAME SIZE USED FREE), where: | ||
| 5783 | - NAME is a symbol describing the kind of objects this entry represents, | ||
| 5784 | - SIZE is the number of bytes used by each one, | ||
| 5785 | - USED is the number of those objects that were found live in the heap, | ||
| 5786 | - FREE is the number of those objects that are not live but that Emacs | ||
| 5787 | keeps around for future allocations (maybe because it does not know how | ||
| 5788 | to return them to the OS). | ||
| 5789 | However, if there was overflow in pure space, `garbage-collect' | ||
| 5790 | returns nil, because real GC can't be done. | ||
| 5791 | See Info node `(elisp)Garbage Collection'. */) | ||
| 5792 | (void) | ||
| 5793 | { | ||
| 5794 | #if (GC_MARK_STACK == GC_MAKE_GCPROS_NOOPS \ | ||
| 5795 | || GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS \ | ||
| 5796 | || GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES) | ||
| 5797 | void *end; | ||
| 5798 | |||
| 5799 | #ifdef HAVE___BUILTIN_UNWIND_INIT | ||
| 5800 | /* Force callee-saved registers and register windows onto the stack. | ||
| 5801 | This is the preferred method if available, obviating the need for | ||
| 5802 | machine dependent methods. */ | ||
| 5803 | __builtin_unwind_init (); | ||
| 5804 | end = &end; | ||
| 5805 | #else /* not HAVE___BUILTIN_UNWIND_INIT */ | ||
| 5806 | #ifndef GC_SAVE_REGISTERS_ON_STACK | ||
| 5807 | /* jmp_buf may not be aligned enough on darwin-ppc64 */ | ||
| 5808 | union aligned_jmpbuf { | ||
| 5809 | Lisp_Object o; | ||
| 5810 | sys_jmp_buf j; | ||
| 5811 | } j; | ||
| 5812 | volatile bool stack_grows_down_p = (char *) &j > (char *) stack_base; | ||
| 5813 | #endif | ||
| 5814 | /* This trick flushes the register windows so that all the state of | ||
| 5815 | the process is contained in the stack. */ | ||
| 5816 | /* Fixme: Code in the Boehm GC suggests flushing (with `flushrs') is | ||
| 5817 | needed on ia64 too. See mach_dep.c, where it also says inline | ||
| 5818 | assembler doesn't work with relevant proprietary compilers. */ | ||
| 5819 | #ifdef __sparc__ | ||
| 5820 | #if defined (__sparc64__) && defined (__FreeBSD__) | ||
| 5821 | /* FreeBSD does not have a ta 3 handler. */ | ||
| 5822 | asm ("flushw"); | ||
| 5823 | #else | ||
| 5824 | asm ("ta 3"); | ||
| 5825 | #endif | ||
| 5826 | #endif | ||
| 5827 | |||
| 5828 | /* Save registers that we need to see on the stack. We need to see | ||
| 5829 | registers used to hold register variables and registers used to | ||
| 5830 | pass parameters. */ | ||
| 5831 | #ifdef GC_SAVE_REGISTERS_ON_STACK | ||
| 5832 | GC_SAVE_REGISTERS_ON_STACK (end); | ||
| 5833 | #else /* not GC_SAVE_REGISTERS_ON_STACK */ | ||
| 5834 | |||
| 5835 | #ifndef GC_SETJMP_WORKS /* If it hasn't been checked yet that | ||
| 5836 | setjmp will definitely work, test it | ||
| 5837 | and print a message with the result | ||
| 5838 | of the test. */ | ||
| 5839 | if (!setjmp_tested_p) | ||
| 5840 | { | ||
| 5841 | setjmp_tested_p = 1; | ||
| 5842 | test_setjmp (); | ||
| 5843 | } | ||
| 5844 | #endif /* GC_SETJMP_WORKS */ | ||
| 5845 | |||
| 5846 | sys_setjmp (j.j); | ||
| 5847 | end = stack_grows_down_p ? (char *) &j + sizeof j : (char *) &j; | ||
| 5848 | #endif /* not GC_SAVE_REGISTERS_ON_STACK */ | ||
| 5849 | #endif /* not HAVE___BUILTIN_UNWIND_INIT */ | ||
| 5850 | #endif /* GC_MARK_STACK */ | ||
| 5851 | return garbage_collect_1 (end); | ||
| 5852 | } | ||
| 5837 | 5853 | ||
| 5838 | /* Mark Lisp objects in glyph matrix MATRIX. Currently the | 5854 | /* Mark Lisp objects in glyph matrix MATRIX. Currently the |
| 5839 | only interesting objects referenced from glyphs are strings. */ | 5855 | only interesting objects referenced from glyphs are strings. */ |