diff options
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 57 |
1 files changed, 17 insertions, 40 deletions
diff --git a/src/alloc.c b/src/alloc.c index dc92d67f163..281525b20e5 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -67,7 +67,8 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 67 | # include <malloc.h> | 67 | # include <malloc.h> |
| 68 | #endif | 68 | #endif |
| 69 | 69 | ||
| 70 | #if defined HAVE_VALGRIND_VALGRIND_H && !defined USE_VALGRIND | 70 | #if (defined ENABLE_CHECKING \ |
| 71 | && defined HAVE_VALGRIND_VALGRIND_H && !defined USE_VALGRIND) | ||
| 71 | # define USE_VALGRIND 1 | 72 | # define USE_VALGRIND 1 |
| 72 | #endif | 73 | #endif |
| 73 | 74 | ||
| @@ -4463,7 +4464,7 @@ live_string_holding (struct mem_node *m, void *p) | |||
| 4463 | 4464 | ||
| 4464 | /* P must point into a Lisp_String structure, and it | 4465 | /* P must point into a Lisp_String structure, and it |
| 4465 | must not be on the free-list. */ | 4466 | must not be on the free-list. */ |
| 4466 | if (0 <= offset && offset < STRING_BLOCK_SIZE * sizeof b->strings[0]) | 4467 | if (0 <= offset && offset < sizeof b->strings) |
| 4467 | { | 4468 | { |
| 4468 | cp = ptr_bounds_copy (cp, b); | 4469 | cp = ptr_bounds_copy (cp, b); |
| 4469 | struct Lisp_String *s = p = cp -= offset % sizeof b->strings[0]; | 4470 | struct Lisp_String *s = p = cp -= offset % sizeof b->strings[0]; |
| @@ -4496,7 +4497,7 @@ live_cons_holding (struct mem_node *m, void *p) | |||
| 4496 | /* P must point into a Lisp_Cons, not be | 4497 | /* P must point into a Lisp_Cons, not be |
| 4497 | one of the unused cells in the current cons block, | 4498 | one of the unused cells in the current cons block, |
| 4498 | and not be on the free-list. */ | 4499 | and not be on the free-list. */ |
| 4499 | if (0 <= offset && offset < CONS_BLOCK_SIZE * sizeof b->conses[0] | 4500 | if (0 <= offset && offset < sizeof b->conses |
| 4500 | && (b != cons_block | 4501 | && (b != cons_block |
| 4501 | || offset / sizeof b->conses[0] < cons_block_index)) | 4502 | || offset / sizeof b->conses[0] < cons_block_index)) |
| 4502 | { | 4503 | { |
| @@ -4532,7 +4533,7 @@ live_symbol_holding (struct mem_node *m, void *p) | |||
| 4532 | /* P must point into the Lisp_Symbol, not be | 4533 | /* P must point into the Lisp_Symbol, not be |
| 4533 | one of the unused cells in the current symbol block, | 4534 | one of the unused cells in the current symbol block, |
| 4534 | and not be on the free-list. */ | 4535 | and not be on the free-list. */ |
| 4535 | if (0 <= offset && offset < SYMBOL_BLOCK_SIZE * sizeof b->symbols[0] | 4536 | if (0 <= offset && offset < sizeof b->symbols |
| 4536 | && (b != symbol_block | 4537 | && (b != symbol_block |
| 4537 | || offset / sizeof b->symbols[0] < symbol_block_index)) | 4538 | || offset / sizeof b->symbols[0] < symbol_block_index)) |
| 4538 | { | 4539 | { |
| @@ -4566,9 +4567,8 @@ live_float_p (struct mem_node *m, void *p) | |||
| 4566 | 4567 | ||
| 4567 | /* P must point to the start of a Lisp_Float and not be | 4568 | /* P must point to the start of a Lisp_Float and not be |
| 4568 | one of the unused cells in the current float block. */ | 4569 | one of the unused cells in the current float block. */ |
| 4569 | return (offset >= 0 | 4570 | return (0 <= offset && offset < sizeof b->floats |
| 4570 | && offset % sizeof b->floats[0] == 0 | 4571 | && offset % sizeof b->floats[0] == 0 |
| 4571 | && offset < (FLOAT_BLOCK_SIZE * sizeof b->floats[0]) | ||
| 4572 | && (b != float_block | 4572 | && (b != float_block |
| 4573 | || offset / sizeof b->floats[0] < float_block_index)); | 4573 | || offset / sizeof b->floats[0] < float_block_index)); |
| 4574 | } | 4574 | } |
| @@ -4694,35 +4694,6 @@ mark_maybe_objects (Lisp_Object const *array, ptrdiff_t nelts) | |||
| 4694 | mark_maybe_object (*array); | 4694 | mark_maybe_object (*array); |
| 4695 | } | 4695 | } |
| 4696 | 4696 | ||
| 4697 | /* A lower bound on the alignment of Lisp objects that need marking. | ||
| 4698 | Although 1 is safe, higher values speed up mark_maybe_pointer. | ||
| 4699 | If USE_LSB_TAG, this value is typically GCALIGNMENT; otherwise, | ||
| 4700 | it's determined by the natural alignment of Lisp structs. | ||
| 4701 | All vectorlike objects have alignment at least that of union | ||
| 4702 | vectorlike_header and it's unlikely they all have alignment greater, | ||
| 4703 | so use the union as a safe and likely-accurate standin for | ||
| 4704 | vectorlike objects. */ | ||
| 4705 | |||
| 4706 | enum { GC_OBJECT_ALIGNMENT_MINIMUM | ||
| 4707 | = max (GCALIGNMENT, | ||
| 4708 | min (alignof (union vectorlike_header), | ||
| 4709 | min (min (alignof (struct Lisp_Cons), | ||
| 4710 | alignof (struct Lisp_Float)), | ||
| 4711 | min (alignof (struct Lisp_String), | ||
| 4712 | alignof (struct Lisp_Symbol))))) }; | ||
| 4713 | |||
| 4714 | /* Return true if P might point to Lisp data that can be garbage | ||
| 4715 | collected, and false otherwise (i.e., false if it is easy to see | ||
| 4716 | that P cannot point to Lisp data that can be garbage collected). | ||
| 4717 | Symbols are implemented via offsets not pointers, but the offsets | ||
| 4718 | are also multiples of GC_OBJECT_ALIGNMENT_MINIMUM. */ | ||
| 4719 | |||
| 4720 | static bool | ||
| 4721 | maybe_lisp_pointer (void *p) | ||
| 4722 | { | ||
| 4723 | return (uintptr_t) p % GC_OBJECT_ALIGNMENT_MINIMUM == 0; | ||
| 4724 | } | ||
| 4725 | |||
| 4726 | /* If P points to Lisp data, mark that as live if it isn't already | 4697 | /* If P points to Lisp data, mark that as live if it isn't already |
| 4727 | marked. */ | 4698 | marked. */ |
| 4728 | 4699 | ||
| @@ -4731,13 +4702,10 @@ mark_maybe_pointer (void *p) | |||
| 4731 | { | 4702 | { |
| 4732 | struct mem_node *m; | 4703 | struct mem_node *m; |
| 4733 | 4704 | ||
| 4734 | #ifdef USE_VALGRIND | 4705 | #if USE_VALGRIND |
| 4735 | VALGRIND_MAKE_MEM_DEFINED (&p, sizeof (p)); | 4706 | VALGRIND_MAKE_MEM_DEFINED (&p, sizeof (p)); |
| 4736 | #endif | 4707 | #endif |
| 4737 | 4708 | ||
| 4738 | if (!maybe_lisp_pointer (p)) | ||
| 4739 | return; | ||
| 4740 | |||
| 4741 | if (pdumper_object_p (p)) | 4709 | if (pdumper_object_p (p)) |
| 4742 | { | 4710 | { |
| 4743 | int type = pdumper_find_object_type (p); | 4711 | int type = pdumper_find_object_type (p); |
| @@ -4837,7 +4805,16 @@ mark_memory (void const *start, void const *end) | |||
| 4837 | 4805 | ||
| 4838 | for (pp = start; (void const *) pp < end; pp += GC_POINTER_ALIGNMENT) | 4806 | for (pp = start; (void const *) pp < end; pp += GC_POINTER_ALIGNMENT) |
| 4839 | { | 4807 | { |
| 4840 | mark_maybe_pointer (*(void *const *) pp); | 4808 | char *p = *(char *const *) pp; |
| 4809 | mark_maybe_pointer (p); | ||
| 4810 | |||
| 4811 | /* Unmask any struct Lisp_Symbol pointer that make_lisp_symbol | ||
| 4812 | previously disguised by adding the address of 'lispsym'. | ||
| 4813 | On a host with 32-bit pointers and 64-bit Lisp_Objects, | ||
| 4814 | a Lisp_Object might be split into registers saved into | ||
| 4815 | non-adjacent words and P might be the low-order word's value. */ | ||
| 4816 | p += (intptr_t) lispsym; | ||
| 4817 | mark_maybe_pointer (p); | ||
| 4841 | 4818 | ||
| 4842 | verify (alignof (Lisp_Object) % GC_POINTER_ALIGNMENT == 0); | 4819 | verify (alignof (Lisp_Object) % GC_POINTER_ALIGNMENT == 0); |
| 4843 | if (alignof (Lisp_Object) == GC_POINTER_ALIGNMENT | 4820 | if (alignof (Lisp_Object) == GC_POINTER_ALIGNMENT |