diff options
| author | Paul Eggert | 2021-07-11 00:54:32 -0700 |
|---|---|---|
| committer | Paul Eggert | 2021-07-11 01:30:11 -0700 |
| commit | f6472cc8e2fdcfd7365240783f34e101fe44142b (patch) | |
| tree | f10d8dd8ea9cdd60946d03ee43c1e5ab2b1d697c /src | |
| parent | 2f7afef5ffe023a7a12520201ab70643f826abfd (diff) | |
| download | emacs-f6472cc8e2fdcfd7365240783f34e101fe44142b.tar.gz emacs-f6472cc8e2fdcfd7365240783f34e101fe44142b.zip | |
Make pdumper-marking pickier
Prevent some false-positives in conservative GC marking.
This doesn’t fix any correctness bugs; it’s merely to
reclaim some memory instead of keeping it unnecessarily.
* src/alloc.c (mark_maybe_pointer): New arg SYMBOL_ONLY.
All callers changed. Check that the pointer’s tag, if any,
matches the pdumper-reported type.
Diffstat (limited to 'src')
| -rw-r--r-- | src/alloc.c | 34 |
1 files changed, 25 insertions, 9 deletions
diff --git a/src/alloc.c b/src/alloc.c index 752eaec1352..b3668d21316 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -4740,7 +4740,7 @@ live_small_vector_p (struct mem_node *m, void *p) | |||
| 4740 | marked. */ | 4740 | marked. */ |
| 4741 | 4741 | ||
| 4742 | static void | 4742 | static void |
| 4743 | mark_maybe_pointer (void *p) | 4743 | mark_maybe_pointer (void *p, bool symbol_only) |
| 4744 | { | 4744 | { |
| 4745 | struct mem_node *m; | 4745 | struct mem_node *m; |
| 4746 | 4746 | ||
| @@ -4765,15 +4765,21 @@ mark_maybe_pointer (void *p) | |||
| 4765 | this problem, the pdumper code should grok non-initial | 4765 | this problem, the pdumper code should grok non-initial |
| 4766 | addresses, as the non-pdumper code does. */ | 4766 | addresses, as the non-pdumper code does. */ |
| 4767 | uintptr_t mask = VALMASK; | 4767 | uintptr_t mask = VALMASK; |
| 4768 | p = (void *) ((uintptr_t) p & mask); | 4768 | void *po = (void *) ((uintptr_t) p & mask); |
| 4769 | char *cp = p; | ||
| 4770 | char *cpo = po; | ||
| 4769 | /* Don't use pdumper_object_p_precise here! It doesn't check the | 4771 | /* Don't use pdumper_object_p_precise here! It doesn't check the |
| 4770 | tag bits. OBJ here might be complete garbage, so we need to | 4772 | tag bits. OBJ here might be complete garbage, so we need to |
| 4771 | verify both the pointer and the tag. */ | 4773 | verify both the pointer and the tag. */ |
| 4772 | int type = pdumper_find_object_type (p); | 4774 | int type = pdumper_find_object_type (po); |
| 4773 | if (pdumper_valid_object_type_p (type)) | 4775 | if (pdumper_valid_object_type_p (type) |
| 4774 | mark_object (type == Lisp_Symbol | 4776 | && (!USE_LSB_TAG || p == po || cp - cpo == type)) |
| 4775 | ? make_lisp_symbol (p) | 4777 | { |
| 4776 | : make_lisp_ptr (p, type)); | 4778 | if (type == Lisp_Symbol) |
| 4779 | mark_object (make_lisp_symbol (po)); | ||
| 4780 | else if (!symbol_only) | ||
| 4781 | mark_object (make_lisp_ptr (po, type)); | ||
| 4782 | } | ||
| 4777 | return; | 4783 | return; |
| 4778 | } | 4784 | } |
| 4779 | 4785 | ||
| @@ -4791,6 +4797,8 @@ mark_maybe_pointer (void *p) | |||
| 4791 | 4797 | ||
| 4792 | case MEM_TYPE_CONS: | 4798 | case MEM_TYPE_CONS: |
| 4793 | { | 4799 | { |
| 4800 | if (symbol_only) | ||
| 4801 | return; | ||
| 4794 | struct Lisp_Cons *h = live_cons_holding (m, p); | 4802 | struct Lisp_Cons *h = live_cons_holding (m, p); |
| 4795 | if (!h) | 4803 | if (!h) |
| 4796 | return; | 4804 | return; |
| @@ -4800,6 +4808,8 @@ mark_maybe_pointer (void *p) | |||
| 4800 | 4808 | ||
| 4801 | case MEM_TYPE_STRING: | 4809 | case MEM_TYPE_STRING: |
| 4802 | { | 4810 | { |
| 4811 | if (symbol_only) | ||
| 4812 | return; | ||
| 4803 | struct Lisp_String *h = live_string_holding (m, p); | 4813 | struct Lisp_String *h = live_string_holding (m, p); |
| 4804 | if (!h) | 4814 | if (!h) |
| 4805 | return; | 4815 | return; |
| @@ -4818,6 +4828,8 @@ mark_maybe_pointer (void *p) | |||
| 4818 | 4828 | ||
| 4819 | case MEM_TYPE_FLOAT: | 4829 | case MEM_TYPE_FLOAT: |
| 4820 | { | 4830 | { |
| 4831 | if (symbol_only) | ||
| 4832 | return; | ||
| 4821 | struct Lisp_Float *h = live_float_holding (m, p); | 4833 | struct Lisp_Float *h = live_float_holding (m, p); |
| 4822 | if (!h) | 4834 | if (!h) |
| 4823 | return; | 4835 | return; |
| @@ -4827,6 +4839,8 @@ mark_maybe_pointer (void *p) | |||
| 4827 | 4839 | ||
| 4828 | case MEM_TYPE_VECTORLIKE: | 4840 | case MEM_TYPE_VECTORLIKE: |
| 4829 | { | 4841 | { |
| 4842 | if (symbol_only) | ||
| 4843 | return; | ||
| 4830 | struct Lisp_Vector *h = live_large_vector_holding (m, p); | 4844 | struct Lisp_Vector *h = live_large_vector_holding (m, p); |
| 4831 | if (!h) | 4845 | if (!h) |
| 4832 | return; | 4846 | return; |
| @@ -4836,6 +4850,8 @@ mark_maybe_pointer (void *p) | |||
| 4836 | 4850 | ||
| 4837 | case MEM_TYPE_VECTOR_BLOCK: | 4851 | case MEM_TYPE_VECTOR_BLOCK: |
| 4838 | { | 4852 | { |
| 4853 | if (symbol_only) | ||
| 4854 | return; | ||
| 4839 | struct Lisp_Vector *h = live_small_vector_holding (m, p); | 4855 | struct Lisp_Vector *h = live_small_vector_holding (m, p); |
| 4840 | if (!h) | 4856 | if (!h) |
| 4841 | return; | 4857 | return; |
| @@ -4897,7 +4913,7 @@ mark_memory (void const *start, void const *end) | |||
| 4897 | for (pp = start; (void const *) pp < end; pp += GC_POINTER_ALIGNMENT) | 4913 | for (pp = start; (void const *) pp < end; pp += GC_POINTER_ALIGNMENT) |
| 4898 | { | 4914 | { |
| 4899 | void *p = *(void *const *) pp; | 4915 | void *p = *(void *const *) pp; |
| 4900 | mark_maybe_pointer (p); | 4916 | mark_maybe_pointer (p, false); |
| 4901 | 4917 | ||
| 4902 | /* Unmask any struct Lisp_Symbol pointer that make_lisp_symbol | 4918 | /* Unmask any struct Lisp_Symbol pointer that make_lisp_symbol |
| 4903 | previously disguised by adding the address of 'lispsym'. | 4919 | previously disguised by adding the address of 'lispsym'. |
| @@ -4906,7 +4922,7 @@ mark_memory (void const *start, void const *end) | |||
| 4906 | non-adjacent words and P might be the low-order word's value. */ | 4922 | non-adjacent words and P might be the low-order word's value. */ |
| 4907 | intptr_t ip; | 4923 | intptr_t ip; |
| 4908 | INT_ADD_WRAPV ((intptr_t) p, (intptr_t) lispsym, &ip); | 4924 | INT_ADD_WRAPV ((intptr_t) p, (intptr_t) lispsym, &ip); |
| 4909 | mark_maybe_pointer ((void *) ip); | 4925 | mark_maybe_pointer ((void *) ip, true); |
| 4910 | } | 4926 | } |
| 4911 | } | 4927 | } |
| 4912 | 4928 | ||