diff options
| author | Dmitry Antipov | 2012-12-03 12:06:02 +0400 |
|---|---|---|
| committer | Dmitry Antipov | 2012-12-03 12:06:02 +0400 |
| commit | 62c2e5ed3a9c991cef2594b44afc74893f6ce26b (patch) | |
| tree | 336fec5e4e929d0505889deefe3f4f484e9fc38a /src | |
| parent | 1c960c45ac19595af7a4a741da7837d2057d977a (diff) | |
| download | emacs-62c2e5ed3a9c991cef2594b44afc74893f6ce26b.tar.gz emacs-62c2e5ed3a9c991cef2594b44afc74893f6ce26b.zip | |
* alloc.c (free_save_value): New function.
(safe_alloca_unwind): Use it.
* lisp.h (free_save_value): New prototype.
* editfns.c (save_excursion_save): Use Lisp_Misc_Save_Value.
Add comment.
(save_excursion_restore): Adjust to match saved data structure.
Use free_save_value to offload some work from GC. Drop obsolete
#if 0 code.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 11 | ||||
| -rw-r--r-- | src/alloc.c | 20 | ||||
| -rw-r--r-- | src/editfns.c | 77 | ||||
| -rw-r--r-- | src/lisp.h | 1 |
4 files changed, 61 insertions, 48 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 0808dad2c93..035ef88c485 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,14 @@ | |||
| 1 | 2012-12-03 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 2 | |||
| 3 | * alloc.c (free_save_value): New function. | ||
| 4 | (safe_alloca_unwind): Use it. | ||
| 5 | * lisp.h (free_save_value): New prototype. | ||
| 6 | * editfns.c (save_excursion_save): Use Lisp_Misc_Save_Value. | ||
| 7 | Add comment. | ||
| 8 | (save_excursion_restore): Adjust to match saved data structure. | ||
| 9 | Use free_save_value to offload some work from GC. Drop obsolete | ||
| 10 | #if 0 code. | ||
| 11 | |||
| 1 | 2012-12-03 Chong Yidong <cyd@gnu.org> | 12 | 2012-12-03 Chong Yidong <cyd@gnu.org> |
| 2 | 13 | ||
| 3 | * fileio.c (Vauto_save_list_file_name): Doc fix. | 14 | * fileio.c (Vauto_save_list_file_name): Doc fix. |
diff --git a/src/alloc.c b/src/alloc.c index e504b3d93ec..0f105f87207 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -826,12 +826,7 @@ xstrdup (const char *s) | |||
| 826 | Lisp_Object | 826 | Lisp_Object |
| 827 | safe_alloca_unwind (Lisp_Object arg) | 827 | safe_alloca_unwind (Lisp_Object arg) |
| 828 | { | 828 | { |
| 829 | register struct Lisp_Save_Value *p = XSAVE_VALUE (arg); | 829 | free_save_value (arg); |
| 830 | |||
| 831 | p->dogc = 0; | ||
| 832 | xfree (p->pointer); | ||
| 833 | p->pointer = 0; | ||
| 834 | free_misc (arg); | ||
| 835 | return Qnil; | 830 | return Qnil; |
| 836 | } | 831 | } |
| 837 | 832 | ||
| @@ -3365,6 +3360,19 @@ make_save_value (void *pointer, ptrdiff_t integer) | |||
| 3365 | return val; | 3360 | return val; |
| 3366 | } | 3361 | } |
| 3367 | 3362 | ||
| 3363 | /* Free a Lisp_Misc_Save_Value object. */ | ||
| 3364 | |||
| 3365 | void | ||
| 3366 | free_save_value (Lisp_Object save) | ||
| 3367 | { | ||
| 3368 | register struct Lisp_Save_Value *p = XSAVE_VALUE (save); | ||
| 3369 | |||
| 3370 | p->dogc = 0; | ||
| 3371 | xfree (p->pointer); | ||
| 3372 | p->pointer = NULL; | ||
| 3373 | free_misc (save); | ||
| 3374 | } | ||
| 3375 | |||
| 3368 | /* Return a Lisp_Misc_Overlay object with specified START, END and PLIST. */ | 3376 | /* Return a Lisp_Misc_Overlay object with specified START, END and PLIST. */ |
| 3369 | 3377 | ||
| 3370 | Lisp_Object | 3378 | Lisp_Object |
diff --git a/src/editfns.c b/src/editfns.c index 8122ffdd0d4..390ce21bbca 100644 --- a/src/editfns.c +++ b/src/editfns.c | |||
| @@ -813,38 +813,43 @@ This function does not move point. */) | |||
| 813 | Qnil, Qt, Qnil); | 813 | Qnil, Qt, Qnil); |
| 814 | } | 814 | } |
| 815 | 815 | ||
| 816 | 816 | /* Save current buffer state for `save-excursion' special form. | |
| 817 | We (ab)use Lisp_Misc_Save_Value to allow explicit free and so | ||
| 818 | offload some work from GC. */ | ||
| 819 | |||
| 817 | Lisp_Object | 820 | Lisp_Object |
| 818 | save_excursion_save (void) | 821 | save_excursion_save (void) |
| 819 | { | 822 | { |
| 820 | bool visible = (XBUFFER (XWINDOW (selected_window)->buffer) | 823 | Lisp_Object save, *data = xmalloc (word_size * 4); |
| 821 | == current_buffer); | 824 | |
| 825 | data[0] = Fpoint_marker (); | ||
| 822 | /* Do not copy the mark if it points to nowhere. */ | 826 | /* Do not copy the mark if it points to nowhere. */ |
| 823 | Lisp_Object mark = (XMARKER (BVAR (current_buffer, mark))->buffer | 827 | data[1] = (XMARKER (BVAR (current_buffer, mark))->buffer |
| 824 | ? Fcopy_marker (BVAR (current_buffer, mark), Qnil) | 828 | ? Fcopy_marker (BVAR (current_buffer, mark), Qnil) |
| 825 | : Qnil); | 829 | : Qnil); |
| 826 | 830 | /* Selected window if current buffer is shown in it, nil otherwise. */ | |
| 827 | return Fcons (Fpoint_marker (), | 831 | data[2] = ((XBUFFER (XWINDOW (selected_window)->buffer) == current_buffer) |
| 828 | Fcons (mark, | 832 | ? selected_window : Qnil); |
| 829 | Fcons (visible ? Qt : Qnil, | 833 | data[3] = BVAR (current_buffer, mark_active); |
| 830 | Fcons (BVAR (current_buffer, mark_active), | 834 | |
| 831 | selected_window)))); | 835 | save = make_save_value (data, 4); |
| 836 | XSAVE_VALUE (save)->dogc = 1; | ||
| 837 | return save; | ||
| 832 | } | 838 | } |
| 833 | 839 | ||
| 840 | /* Restore saved buffer before leaving `save-excursion' special form. */ | ||
| 841 | |||
| 834 | Lisp_Object | 842 | Lisp_Object |
| 835 | save_excursion_restore (Lisp_Object info) | 843 | save_excursion_restore (Lisp_Object info) |
| 836 | { | 844 | { |
| 837 | Lisp_Object tem, tem1, omark, nmark; | 845 | Lisp_Object tem, tem1, omark, nmark, *data = XSAVE_VALUE (info)->pointer; |
| 838 | struct gcpro gcpro1, gcpro2, gcpro3; | 846 | struct gcpro gcpro1, gcpro2, gcpro3; |
| 839 | bool visible_p; | ||
| 840 | 847 | ||
| 841 | tem = Fmarker_buffer (XCAR (info)); | 848 | tem = Fmarker_buffer (data[0]); |
| 842 | /* If buffer being returned to is now deleted, avoid error */ | 849 | /* If we're unwinding to top level, saved buffer may be deleted. This |
| 843 | /* Otherwise could get error here while unwinding to top level | 850 | means that all of its markers are unchained and so tem is nil. */ |
| 844 | and crash */ | ||
| 845 | /* In that case, Fmarker_buffer returns nil now. */ | ||
| 846 | if (NILP (tem)) | 851 | if (NILP (tem)) |
| 847 | return Qnil; | 852 | goto out; |
| 848 | 853 | ||
| 849 | omark = nmark = Qnil; | 854 | omark = nmark = Qnil; |
| 850 | GCPRO3 (info, omark, nmark); | 855 | GCPRO3 (info, omark, nmark); |
| @@ -852,13 +857,12 @@ save_excursion_restore (Lisp_Object info) | |||
| 852 | Fset_buffer (tem); | 857 | Fset_buffer (tem); |
| 853 | 858 | ||
| 854 | /* Point marker. */ | 859 | /* Point marker. */ |
| 855 | tem = XCAR (info); | 860 | tem = data[0]; |
| 856 | Fgoto_char (tem); | 861 | Fgoto_char (tem); |
| 857 | unchain_marker (XMARKER (tem)); | 862 | unchain_marker (XMARKER (tem)); |
| 858 | 863 | ||
| 859 | /* Mark marker. */ | 864 | /* Mark marker. */ |
| 860 | info = XCDR (info); | 865 | tem = data[1]; |
| 861 | tem = XCAR (info); | ||
| 862 | omark = Fmarker_position (BVAR (current_buffer, mark)); | 866 | omark = Fmarker_position (BVAR (current_buffer, mark)); |
| 863 | if (NILP (tem)) | 867 | if (NILP (tem)) |
| 864 | unchain_marker (XMARKER (BVAR (current_buffer, mark))); | 868 | unchain_marker (XMARKER (BVAR (current_buffer, mark))); |
| @@ -869,23 +873,8 @@ save_excursion_restore (Lisp_Object info) | |||
| 869 | unchain_marker (XMARKER (tem)); | 873 | unchain_marker (XMARKER (tem)); |
| 870 | } | 874 | } |
| 871 | 875 | ||
| 872 | /* visible */ | 876 | /* Mark active. */ |
| 873 | info = XCDR (info); | 877 | tem = data[3]; |
| 874 | visible_p = !NILP (XCAR (info)); | ||
| 875 | |||
| 876 | #if 0 /* We used to make the current buffer visible in the selected window | ||
| 877 | if that was true previously. That avoids some anomalies. | ||
| 878 | But it creates others, and it wasn't documented, and it is simpler | ||
| 879 | and cleaner never to alter the window/buffer connections. */ | ||
| 880 | tem1 = Fcar (tem); | ||
| 881 | if (!NILP (tem1) | ||
| 882 | && current_buffer != XBUFFER (XWINDOW (selected_window)->buffer)) | ||
| 883 | Fswitch_to_buffer (Fcurrent_buffer (), Qnil); | ||
| 884 | #endif /* 0 */ | ||
| 885 | |||
| 886 | /* Mark active */ | ||
| 887 | info = XCDR (info); | ||
| 888 | tem = XCAR (info); | ||
| 889 | tem1 = BVAR (current_buffer, mark_active); | 878 | tem1 = BVAR (current_buffer, mark_active); |
| 890 | bset_mark_active (current_buffer, tem); | 879 | bset_mark_active (current_buffer, tem); |
| 891 | 880 | ||
| @@ -909,8 +898,8 @@ save_excursion_restore (Lisp_Object info) | |||
| 909 | /* If buffer was visible in a window, and a different window was | 898 | /* If buffer was visible in a window, and a different window was |
| 910 | selected, and the old selected window is still showing this | 899 | selected, and the old selected window is still showing this |
| 911 | buffer, restore point in that window. */ | 900 | buffer, restore point in that window. */ |
| 912 | tem = XCDR (info); | 901 | tem = data[2]; |
| 913 | if (visible_p | 902 | if (WINDOWP (tem) |
| 914 | && !EQ (tem, selected_window) | 903 | && !EQ (tem, selected_window) |
| 915 | && (tem1 = XWINDOW (tem)->buffer, | 904 | && (tem1 = XWINDOW (tem)->buffer, |
| 916 | (/* Window is live... */ | 905 | (/* Window is live... */ |
| @@ -920,6 +909,10 @@ save_excursion_restore (Lisp_Object info) | |||
| 920 | Fset_window_point (tem, make_number (PT)); | 909 | Fset_window_point (tem, make_number (PT)); |
| 921 | 910 | ||
| 922 | UNGCPRO; | 911 | UNGCPRO; |
| 912 | |||
| 913 | out: | ||
| 914 | |||
| 915 | free_save_value (info); | ||
| 923 | return Qnil; | 916 | return Qnil; |
| 924 | } | 917 | } |
| 925 | 918 | ||
diff --git a/src/lisp.h b/src/lisp.h index 419176d06c8..4dae66eec96 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -2963,6 +2963,7 @@ extern Lisp_Object make_float (double); | |||
| 2963 | extern void display_malloc_warning (void); | 2963 | extern void display_malloc_warning (void); |
| 2964 | extern ptrdiff_t inhibit_garbage_collection (void); | 2964 | extern ptrdiff_t inhibit_garbage_collection (void); |
| 2965 | extern Lisp_Object make_save_value (void *, ptrdiff_t); | 2965 | extern Lisp_Object make_save_value (void *, ptrdiff_t); |
| 2966 | extern void free_save_value (Lisp_Object); | ||
| 2966 | extern Lisp_Object build_overlay (Lisp_Object, Lisp_Object, Lisp_Object); | 2967 | extern Lisp_Object build_overlay (Lisp_Object, Lisp_Object, Lisp_Object); |
| 2967 | extern void free_marker (Lisp_Object); | 2968 | extern void free_marker (Lisp_Object); |
| 2968 | extern void free_cons (struct Lisp_Cons *); | 2969 | extern void free_cons (struct Lisp_Cons *); |