diff options
| author | Paul Eggert | 2020-09-05 12:13:32 -0700 |
|---|---|---|
| committer | Paul Eggert | 2020-09-05 12:15:14 -0700 |
| commit | 6cf62141c4467314f67c2ef75a4bf94d41ff050f (patch) | |
| tree | 15e690c820576893cb9ca5d3f2dd1455dd3f0520 /src | |
| parent | 940ea1549117f56642fd6830bdbccf8865a932bb (diff) | |
| download | emacs-6cf62141c4467314f67c2ef75a4bf94d41ff050f.tar.gz emacs-6cf62141c4467314f67c2ef75a4bf94d41ff050f.zip | |
Reinstall recent GC-related changes
The report that they broke macOS was a false alarm, as the
previous commit was also broken (Bug#43152#62).
* src/alloc.c (live_string_holding, live_cons_holding)
(live_symbol_holding):
Count only pointers that point to a struct component,
or are a tagged pointer to the start of the struct.
Exception: for non-bool-vector pseudovectors,
count any pointer past the header, since it’s too much
of a pain to write code for every pseudovector.
(live_float_holding, live_vector_pointer):
New functions, which are similar about counting pointers.
(live_float_p, live_large_vector_holding)
(live_small_vector_pointer, mark_maybe_pointer): Use them.
(mark_maybe_object, mark_maybe_objects): Remove,
and remove all callers; mark_maybe_pointer now suffices.
(mark_objects): New function.
* src/alloc.c (mark_vectorlike, mark_face_cache):
* src/eval.c (mark_specpdl):
* src/fringe.c (mark_fringe_data):
* src/keyboard.c (mark_kboards):
Simplify by using mark_objects.
* src/lisp.h (SAFE_ALLOCA_LISP_EXTRA):
Clear any Lisp_Object arrays large enough to not fit into the stack,
so that GC need not worry about whether they contain objects.
Diffstat (limited to 'src')
| -rw-r--r-- | src/alloc.c | 247 | ||||
| -rw-r--r-- | src/eval.c | 5 | ||||
| -rw-r--r-- | src/fringe.c | 6 | ||||
| -rw-r--r-- | src/keyboard.c | 8 | ||||
| -rw-r--r-- | src/lisp.h | 7 |
5 files changed, 129 insertions, 144 deletions
diff --git a/src/alloc.c b/src/alloc.c index b16b2f8b93e..b12922b5858 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -4457,9 +4457,17 @@ live_string_holding (struct mem_node *m, void *p) | |||
| 4457 | must not be on the free-list. */ | 4457 | must not be on the free-list. */ |
| 4458 | if (0 <= offset && offset < sizeof b->strings) | 4458 | if (0 <= offset && offset < sizeof b->strings) |
| 4459 | { | 4459 | { |
| 4460 | struct Lisp_String *s = p = cp -= offset % sizeof b->strings[0]; | 4460 | ptrdiff_t off = offset % sizeof b->strings[0]; |
| 4461 | if (s->u.s.data) | 4461 | if (off == Lisp_String |
| 4462 | return s; | 4462 | || off == 0 |
| 4463 | || off == offsetof (struct Lisp_String, u.s.size_byte) | ||
| 4464 | || off == offsetof (struct Lisp_String, u.s.intervals) | ||
| 4465 | || off == offsetof (struct Lisp_String, u.s.data)) | ||
| 4466 | { | ||
| 4467 | struct Lisp_String *s = p = cp -= off; | ||
| 4468 | if (s->u.s.data) | ||
| 4469 | return s; | ||
| 4470 | } | ||
| 4463 | } | 4471 | } |
| 4464 | return NULL; | 4472 | return NULL; |
| 4465 | } | 4473 | } |
| @@ -4489,9 +4497,15 @@ live_cons_holding (struct mem_node *m, void *p) | |||
| 4489 | && (b != cons_block | 4497 | && (b != cons_block |
| 4490 | || offset / sizeof b->conses[0] < cons_block_index)) | 4498 | || offset / sizeof b->conses[0] < cons_block_index)) |
| 4491 | { | 4499 | { |
| 4492 | struct Lisp_Cons *s = p = cp -= offset % sizeof b->conses[0]; | 4500 | ptrdiff_t off = offset % sizeof b->conses[0]; |
| 4493 | if (!deadp (s->u.s.car)) | 4501 | if (off == Lisp_Cons |
| 4494 | return s; | 4502 | || off == 0 |
| 4503 | || off == offsetof (struct Lisp_Cons, u.s.u.cdr)) | ||
| 4504 | { | ||
| 4505 | struct Lisp_Cons *s = p = cp -= off; | ||
| 4506 | if (!deadp (s->u.s.car)) | ||
| 4507 | return s; | ||
| 4508 | } | ||
| 4495 | } | 4509 | } |
| 4496 | return NULL; | 4510 | return NULL; |
| 4497 | } | 4511 | } |
| @@ -4522,9 +4536,23 @@ live_symbol_holding (struct mem_node *m, void *p) | |||
| 4522 | && (b != symbol_block | 4536 | && (b != symbol_block |
| 4523 | || offset / sizeof b->symbols[0] < symbol_block_index)) | 4537 | || offset / sizeof b->symbols[0] < symbol_block_index)) |
| 4524 | { | 4538 | { |
| 4525 | struct Lisp_Symbol *s = p = cp -= offset % sizeof b->symbols[0]; | 4539 | ptrdiff_t off = offset % sizeof b->symbols[0]; |
| 4526 | if (!deadp (s->u.s.function)) | 4540 | if (off == Lisp_Symbol |
| 4527 | return s; | 4541 | |
| 4542 | /* Plain '|| off == 0' would run afoul of GCC 10.2 | ||
| 4543 | -Wlogical-op, as Lisp_Symbol happens to be zero. */ | ||
| 4544 | || (Lisp_Symbol != 0 && off == 0) | ||
| 4545 | |||
| 4546 | || off == offsetof (struct Lisp_Symbol, u.s.name) | ||
| 4547 | || off == offsetof (struct Lisp_Symbol, u.s.val) | ||
| 4548 | || off == offsetof (struct Lisp_Symbol, u.s.function) | ||
| 4549 | || off == offsetof (struct Lisp_Symbol, u.s.plist) | ||
| 4550 | || off == offsetof (struct Lisp_Symbol, u.s.next)) | ||
| 4551 | { | ||
| 4552 | struct Lisp_Symbol *s = p = cp -= off; | ||
| 4553 | if (!deadp (s->u.s.function)) | ||
| 4554 | return s; | ||
| 4555 | } | ||
| 4528 | } | 4556 | } |
| 4529 | return NULL; | 4557 | return NULL; |
| 4530 | } | 4558 | } |
| @@ -4536,23 +4564,70 @@ live_symbol_p (struct mem_node *m, void *p) | |||
| 4536 | } | 4564 | } |
| 4537 | 4565 | ||
| 4538 | 4566 | ||
| 4539 | /* Return true if P is a pointer to a live Lisp float on | 4567 | /* If P is a (possibly-tagged) pointer to a live Lisp_Float on the |
| 4540 | the heap. M is a pointer to the mem_block for P. */ | 4568 | heap, return the address of the Lisp_Float. Otherwise, return NULL. |
| 4569 | M is a pointer to the mem_block for P. */ | ||
| 4541 | 4570 | ||
| 4542 | static bool | 4571 | static struct Lisp_Float * |
| 4543 | live_float_p (struct mem_node *m, void *p) | 4572 | live_float_holding (struct mem_node *m, void *p) |
| 4544 | { | 4573 | { |
| 4545 | eassert (m->type == MEM_TYPE_FLOAT); | 4574 | eassert (m->type == MEM_TYPE_FLOAT); |
| 4546 | struct float_block *b = m->start; | 4575 | struct float_block *b = m->start; |
| 4547 | char *cp = p; | 4576 | char *cp = p; |
| 4548 | ptrdiff_t offset = cp - (char *) &b->floats[0]; | 4577 | ptrdiff_t offset = cp - (char *) &b->floats[0]; |
| 4549 | 4578 | ||
| 4550 | /* P must point to the start of a Lisp_Float and not be | 4579 | /* P must point to (or be a tagged pointer to) the start of a |
| 4551 | one of the unused cells in the current float block. */ | 4580 | Lisp_Float and not be one of the unused cells in the current |
| 4552 | return (0 <= offset && offset < sizeof b->floats | 4581 | float block. */ |
| 4553 | && offset % sizeof b->floats[0] == 0 | 4582 | if (0 <= offset && offset < sizeof b->floats) |
| 4583 | { | ||
| 4584 | int off = offset % sizeof b->floats[0]; | ||
| 4585 | if ((off == Lisp_Float || off == 0) | ||
| 4554 | && (b != float_block | 4586 | && (b != float_block |
| 4555 | || offset / sizeof b->floats[0] < float_block_index)); | 4587 | || offset / sizeof b->floats[0] < float_block_index)) |
| 4588 | { | ||
| 4589 | p = cp - off; | ||
| 4590 | return p; | ||
| 4591 | } | ||
| 4592 | } | ||
| 4593 | return NULL; | ||
| 4594 | } | ||
| 4595 | |||
| 4596 | static bool | ||
| 4597 | live_float_p (struct mem_node *m, void *p) | ||
| 4598 | { | ||
| 4599 | return live_float_holding (m, p) == p; | ||
| 4600 | } | ||
| 4601 | |||
| 4602 | /* Return VECTOR if P points within it, NULL otherwise. */ | ||
| 4603 | |||
| 4604 | static struct Lisp_Vector * | ||
| 4605 | live_vector_pointer (struct Lisp_Vector *vector, void *p) | ||
| 4606 | { | ||
| 4607 | void *vvector = vector; | ||
| 4608 | char *cvector = vvector; | ||
| 4609 | char *cp = p; | ||
| 4610 | ptrdiff_t offset = cp - cvector; | ||
| 4611 | return ((offset == Lisp_Vectorlike | ||
| 4612 | || offset == 0 | ||
| 4613 | || (sizeof vector->header <= offset | ||
| 4614 | && offset < vector_nbytes (vector) | ||
| 4615 | && (! (vector->header.size & PSEUDOVECTOR_FLAG) | ||
| 4616 | ? (offsetof (struct Lisp_Vector, contents) <= offset | ||
| 4617 | && (((offset - offsetof (struct Lisp_Vector, contents)) | ||
| 4618 | % word_size) | ||
| 4619 | == 0)) | ||
| 4620 | /* For non-bool-vector pseudovectors, treat any pointer | ||
| 4621 | past the header as valid since it's too much of a pain | ||
| 4622 | to write special-case code for every pseudovector. */ | ||
| 4623 | : (! PSEUDOVECTOR_TYPEP (&vector->header, PVEC_BOOL_VECTOR) | ||
| 4624 | || offset == offsetof (struct Lisp_Bool_Vector, size) | ||
| 4625 | || (offsetof (struct Lisp_Bool_Vector, data) <= offset | ||
| 4626 | && (((offset | ||
| 4627 | - offsetof (struct Lisp_Bool_Vector, data)) | ||
| 4628 | % sizeof (bits_word)) | ||
| 4629 | == 0)))))) | ||
| 4630 | ? vector : NULL); | ||
| 4556 | } | 4631 | } |
| 4557 | 4632 | ||
| 4558 | /* If P is a pointer to a live, large vector-like object, return the object. | 4633 | /* If P is a pointer to a live, large vector-like object, return the object. |
| @@ -4563,10 +4638,7 @@ static struct Lisp_Vector * | |||
| 4563 | live_large_vector_holding (struct mem_node *m, void *p) | 4638 | live_large_vector_holding (struct mem_node *m, void *p) |
| 4564 | { | 4639 | { |
| 4565 | eassert (m->type == MEM_TYPE_VECTORLIKE); | 4640 | eassert (m->type == MEM_TYPE_VECTORLIKE); |
| 4566 | struct Lisp_Vector *vp = p; | 4641 | return live_vector_pointer (large_vector_vec (m->start), p); |
| 4567 | struct Lisp_Vector *vector = large_vector_vec (m->start); | ||
| 4568 | struct Lisp_Vector *next = ADVANCE (vector, vector_nbytes (vector)); | ||
| 4569 | return vector <= vp && vp < next ? vector : NULL; | ||
| 4570 | } | 4642 | } |
| 4571 | 4643 | ||
| 4572 | static bool | 4644 | static bool |
| @@ -4596,7 +4668,7 @@ live_small_vector_holding (struct mem_node *m, void *p) | |||
| 4596 | { | 4668 | { |
| 4597 | struct Lisp_Vector *next = ADVANCE (vector, vector_nbytes (vector)); | 4669 | struct Lisp_Vector *next = ADVANCE (vector, vector_nbytes (vector)); |
| 4598 | if (vp < next && !PSEUDOVECTOR_TYPEP (&vector->header, PVEC_FREE)) | 4670 | if (vp < next && !PSEUDOVECTOR_TYPEP (&vector->header, PVEC_FREE)) |
| 4599 | return vector; | 4671 | return live_vector_pointer (vector, vp); |
| 4600 | vector = next; | 4672 | vector = next; |
| 4601 | } | 4673 | } |
| 4602 | return NULL; | 4674 | return NULL; |
| @@ -4608,117 +4680,33 @@ live_small_vector_p (struct mem_node *m, void *p) | |||
| 4608 | return live_small_vector_holding (m, p) == p; | 4680 | return live_small_vector_holding (m, p) == p; |
| 4609 | } | 4681 | } |
| 4610 | 4682 | ||
| 4611 | /* Mark OBJ if we can prove it's a Lisp_Object. */ | 4683 | /* If P points to Lisp data, mark that as live if it isn't already |
| 4684 | marked. */ | ||
| 4612 | 4685 | ||
| 4613 | static void | 4686 | static void |
| 4614 | mark_maybe_object (Lisp_Object obj) | 4687 | mark_maybe_pointer (void *p) |
| 4615 | { | 4688 | { |
| 4689 | struct mem_node *m; | ||
| 4690 | |||
| 4616 | #if USE_VALGRIND | 4691 | #if USE_VALGRIND |
| 4617 | VALGRIND_MAKE_MEM_DEFINED (&obj, sizeof (obj)); | 4692 | VALGRIND_MAKE_MEM_DEFINED (&p, sizeof (p)); |
| 4618 | #endif | 4693 | #endif |
| 4619 | 4694 | ||
| 4620 | int type_tag = XTYPE (obj); | ||
| 4621 | intptr_t pointer_word_tag = LISP_WORD_TAG (type_tag), offset, ipo; | ||
| 4622 | |||
| 4623 | switch (type_tag) | ||
| 4624 | { | ||
| 4625 | case_Lisp_Int: case Lisp_Type_Unused0: | ||
| 4626 | return; | ||
| 4627 | |||
| 4628 | case Lisp_Symbol: | ||
| 4629 | offset = (intptr_t) lispsym; | ||
| 4630 | break; | ||
| 4631 | |||
| 4632 | default: | ||
| 4633 | offset = 0; | ||
| 4634 | break; | ||
| 4635 | } | ||
| 4636 | |||
| 4637 | INT_ADD_WRAPV ((intptr_t) XLP (obj), offset - pointer_word_tag, &ipo); | ||
| 4638 | void *po = (void *) ipo; | ||
| 4639 | |||
| 4640 | /* If the pointer is in the dump image and the dump has a record | 4695 | /* If the pointer is in the dump image and the dump has a record |
| 4641 | of the object starting at the place where the pointer points, we | 4696 | of the object starting at the place where the pointer points, we |
| 4642 | definitely have an object. If the pointer is in the dump image | 4697 | definitely have an object. If the pointer is in the dump image |
| 4643 | and the dump has no idea what the pointer is pointing at, we | 4698 | and the dump has no idea what the pointer is pointing at, we |
| 4644 | definitely _don't_ have an object. */ | 4699 | definitely _don't_ have an object. */ |
| 4645 | if (pdumper_object_p (po)) | 4700 | if (pdumper_object_p (p)) |
| 4646 | { | 4701 | { |
| 4647 | /* Don't use pdumper_object_p_precise here! It doesn't check the | 4702 | /* Don't use pdumper_object_p_precise here! It doesn't check the |
| 4648 | tag bits. OBJ here might be complete garbage, so we need to | 4703 | tag bits. OBJ here might be complete garbage, so we need to |
| 4649 | verify both the pointer and the tag. */ | 4704 | verify both the pointer and the tag. */ |
| 4650 | if (pdumper_find_object_type (po) == type_tag) | ||
| 4651 | mark_object (obj); | ||
| 4652 | return; | ||
| 4653 | } | ||
| 4654 | |||
| 4655 | struct mem_node *m = mem_find (po); | ||
| 4656 | |||
| 4657 | if (m != MEM_NIL) | ||
| 4658 | { | ||
| 4659 | bool mark_p = false; | ||
| 4660 | |||
| 4661 | switch (type_tag) | ||
| 4662 | { | ||
| 4663 | case Lisp_String: | ||
| 4664 | mark_p = m->type == MEM_TYPE_STRING && live_string_p (m, po); | ||
| 4665 | break; | ||
| 4666 | |||
| 4667 | case Lisp_Cons: | ||
| 4668 | mark_p = m->type == MEM_TYPE_CONS && live_cons_p (m, po); | ||
| 4669 | break; | ||
| 4670 | |||
| 4671 | case Lisp_Symbol: | ||
| 4672 | mark_p = m->type == MEM_TYPE_SYMBOL && live_symbol_p (m, po); | ||
| 4673 | break; | ||
| 4674 | |||
| 4675 | case Lisp_Float: | ||
| 4676 | mark_p = m->type == MEM_TYPE_FLOAT && live_float_p (m, po); | ||
| 4677 | break; | ||
| 4678 | |||
| 4679 | case Lisp_Vectorlike: | ||
| 4680 | mark_p = (m->type == MEM_TYPE_VECTOR_BLOCK | ||
| 4681 | ? live_small_vector_p (m, po) | ||
| 4682 | : (m->type == MEM_TYPE_VECTORLIKE | ||
| 4683 | && live_large_vector_p (m, po))); | ||
| 4684 | break; | ||
| 4685 | |||
| 4686 | default: | ||
| 4687 | eassume (false); | ||
| 4688 | } | ||
| 4689 | |||
| 4690 | if (mark_p) | ||
| 4691 | mark_object (obj); | ||
| 4692 | } | ||
| 4693 | } | ||
| 4694 | |||
| 4695 | void | ||
| 4696 | mark_maybe_objects (Lisp_Object const *array, ptrdiff_t nelts) | ||
| 4697 | { | ||
| 4698 | for (Lisp_Object const *lim = array + nelts; array < lim; array++) | ||
| 4699 | mark_maybe_object (*array); | ||
| 4700 | } | ||
| 4701 | |||
| 4702 | /* If P points to Lisp data, mark that as live if it isn't already | ||
| 4703 | marked. */ | ||
| 4704 | |||
| 4705 | static void | ||
| 4706 | mark_maybe_pointer (void *p) | ||
| 4707 | { | ||
| 4708 | struct mem_node *m; | ||
| 4709 | |||
| 4710 | #if USE_VALGRIND | ||
| 4711 | VALGRIND_MAKE_MEM_DEFINED (&p, sizeof (p)); | ||
| 4712 | #endif | ||
| 4713 | |||
| 4714 | if (pdumper_object_p (p)) | ||
| 4715 | { | ||
| 4716 | int type = pdumper_find_object_type (p); | 4705 | int type = pdumper_find_object_type (p); |
| 4717 | if (pdumper_valid_object_type_p (type)) | 4706 | if (pdumper_valid_object_type_p (type)) |
| 4718 | mark_object (type == Lisp_Symbol | 4707 | mark_object (type == Lisp_Symbol |
| 4719 | ? make_lisp_symbol (p) | 4708 | ? make_lisp_symbol (p) |
| 4720 | : make_lisp_ptr (p, type)); | 4709 | : make_lisp_ptr (p, type)); |
| 4721 | /* See mark_maybe_object for why we can confidently return. */ | ||
| 4722 | return; | 4710 | return; |
| 4723 | } | 4711 | } |
| 4724 | 4712 | ||
| @@ -4762,9 +4750,12 @@ mark_maybe_pointer (void *p) | |||
| 4762 | break; | 4750 | break; |
| 4763 | 4751 | ||
| 4764 | case MEM_TYPE_FLOAT: | 4752 | case MEM_TYPE_FLOAT: |
| 4765 | if (! live_float_p (m, p)) | 4753 | { |
| 4766 | return; | 4754 | struct Lisp_Float *h = live_float_holding (m, p); |
| 4767 | obj = make_lisp_ptr (p, Lisp_Float); | 4755 | if (!h) |
| 4756 | return; | ||
| 4757 | obj = make_lisp_ptr (h, Lisp_Float); | ||
| 4758 | } | ||
| 4768 | break; | 4759 | break; |
| 4769 | 4760 | ||
| 4770 | case MEM_TYPE_VECTORLIKE: | 4761 | case MEM_TYPE_VECTORLIKE: |
| @@ -4849,11 +4840,6 @@ mark_memory (void const *start, void const *end) | |||
| 4849 | intptr_t ip; | 4840 | intptr_t ip; |
| 4850 | INT_ADD_WRAPV ((intptr_t) p, (intptr_t) lispsym, &ip); | 4841 | INT_ADD_WRAPV ((intptr_t) p, (intptr_t) lispsym, &ip); |
| 4851 | mark_maybe_pointer ((void *) ip); | 4842 | mark_maybe_pointer ((void *) ip); |
| 4852 | |||
| 4853 | verify (alignof (Lisp_Object) % GC_POINTER_ALIGNMENT == 0); | ||
| 4854 | if (alignof (Lisp_Object) == GC_POINTER_ALIGNMENT | ||
| 4855 | || (uintptr_t) pp % alignof (Lisp_Object) == 0) | ||
| 4856 | mark_maybe_object (*(Lisp_Object const *) pp); | ||
| 4857 | } | 4843 | } |
| 4858 | } | 4844 | } |
| 4859 | 4845 | ||
| @@ -6261,7 +6247,6 @@ mark_vectorlike (union vectorlike_header *header) | |||
| 6261 | { | 6247 | { |
| 6262 | struct Lisp_Vector *ptr = (struct Lisp_Vector *) header; | 6248 | struct Lisp_Vector *ptr = (struct Lisp_Vector *) header; |
| 6263 | ptrdiff_t size = ptr->header.size; | 6249 | ptrdiff_t size = ptr->header.size; |
| 6264 | ptrdiff_t i; | ||
| 6265 | 6250 | ||
| 6266 | eassert (!vector_marked_p (ptr)); | 6251 | eassert (!vector_marked_p (ptr)); |
| 6267 | 6252 | ||
| @@ -6276,8 +6261,7 @@ mark_vectorlike (union vectorlike_header *header) | |||
| 6276 | the number of Lisp_Object fields that we should trace. | 6261 | the number of Lisp_Object fields that we should trace. |
| 6277 | The distinction is used e.g. by Lisp_Process which places extra | 6262 | The distinction is used e.g. by Lisp_Process which places extra |
| 6278 | non-Lisp_Object fields at the end of the structure... */ | 6263 | non-Lisp_Object fields at the end of the structure... */ |
| 6279 | for (i = 0; i < size; i++) /* ...and then mark its elements. */ | 6264 | mark_objects (ptr->contents, size); |
| 6280 | mark_object (ptr->contents[i]); | ||
| 6281 | } | 6265 | } |
| 6282 | 6266 | ||
| 6283 | /* Like mark_vectorlike but optimized for char-tables (and | 6267 | /* Like mark_vectorlike but optimized for char-tables (and |
| @@ -6376,8 +6360,7 @@ mark_face_cache (struct face_cache *c) | |||
| 6376 | { | 6360 | { |
| 6377 | if (c) | 6361 | if (c) |
| 6378 | { | 6362 | { |
| 6379 | int i, j; | 6363 | for (int i = 0; i < c->used; i++) |
| 6380 | for (i = 0; i < c->used; ++i) | ||
| 6381 | { | 6364 | { |
| 6382 | struct face *face = FACE_FROM_ID_OR_NULL (c->f, i); | 6365 | struct face *face = FACE_FROM_ID_OR_NULL (c->f, i); |
| 6383 | 6366 | ||
| @@ -6386,8 +6369,7 @@ mark_face_cache (struct face_cache *c) | |||
| 6386 | if (face->font && !vectorlike_marked_p (&face->font->header)) | 6369 | if (face->font && !vectorlike_marked_p (&face->font->header)) |
| 6387 | mark_vectorlike (&face->font->header); | 6370 | mark_vectorlike (&face->font->header); |
| 6388 | 6371 | ||
| 6389 | for (j = 0; j < LFACE_VECTOR_SIZE; ++j) | 6372 | mark_objects (face->lface, LFACE_VECTOR_SIZE); |
| 6390 | mark_object (face->lface[j]); | ||
| 6391 | } | 6373 | } |
| 6392 | } | 6374 | } |
| 6393 | } | 6375 | } |
| @@ -6500,6 +6482,13 @@ mark_hash_table (struct Lisp_Vector *ptr) | |||
| 6500 | } | 6482 | } |
| 6501 | } | 6483 | } |
| 6502 | 6484 | ||
| 6485 | void | ||
| 6486 | mark_objects (Lisp_Object *obj, ptrdiff_t n) | ||
| 6487 | { | ||
| 6488 | for (ptrdiff_t i = 0; i < n; i++) | ||
| 6489 | mark_object (obj[i]); | ||
| 6490 | } | ||
| 6491 | |||
| 6503 | /* Determine type of generic Lisp_Object and mark it accordingly. | 6492 | /* Determine type of generic Lisp_Object and mark it accordingly. |
| 6504 | 6493 | ||
| 6505 | This function implements a straightforward depth-first marking | 6494 | This function implements a straightforward depth-first marking |
diff --git a/src/eval.c b/src/eval.c index 9daae92e55a..126ee2e9555 100644 --- a/src/eval.c +++ b/src/eval.c | |||
| @@ -3960,7 +3960,7 @@ mark_specpdl (union specbinding *first, union specbinding *ptr) | |||
| 3960 | break; | 3960 | break; |
| 3961 | 3961 | ||
| 3962 | case SPECPDL_UNWIND_ARRAY: | 3962 | case SPECPDL_UNWIND_ARRAY: |
| 3963 | mark_maybe_objects (pdl->unwind_array.array, pdl->unwind_array.nelts); | 3963 | mark_objects (pdl->unwind_array.array, pdl->unwind_array.nelts); |
| 3964 | break; | 3964 | break; |
| 3965 | 3965 | ||
| 3966 | case SPECPDL_UNWIND_EXCURSION: | 3966 | case SPECPDL_UNWIND_EXCURSION: |
| @@ -3974,8 +3974,7 @@ mark_specpdl (union specbinding *first, union specbinding *ptr) | |||
| 3974 | mark_object (backtrace_function (pdl)); | 3974 | mark_object (backtrace_function (pdl)); |
| 3975 | if (nargs == UNEVALLED) | 3975 | if (nargs == UNEVALLED) |
| 3976 | nargs = 1; | 3976 | nargs = 1; |
| 3977 | while (nargs--) | 3977 | mark_objects (backtrace_args (pdl), nargs); |
| 3978 | mark_object (backtrace_args (pdl)[nargs]); | ||
| 3979 | } | 3978 | } |
| 3980 | break; | 3979 | break; |
| 3981 | 3980 | ||
diff --git a/src/fringe.c b/src/fringe.c index c3d64fefc82..75496692d53 100644 --- a/src/fringe.c +++ b/src/fringe.c | |||
| @@ -1733,11 +1733,7 @@ If nil, also continue lines which are exactly as wide as the window. */); | |||
| 1733 | void | 1733 | void |
| 1734 | mark_fringe_data (void) | 1734 | mark_fringe_data (void) |
| 1735 | { | 1735 | { |
| 1736 | int i; | 1736 | mark_objects (fringe_faces, max_fringe_bitmaps); |
| 1737 | |||
| 1738 | for (i = 0; i < max_fringe_bitmaps; i++) | ||
| 1739 | if (!NILP (fringe_faces[i])) | ||
| 1740 | mark_object (fringe_faces[i]); | ||
| 1741 | } | 1737 | } |
| 1742 | 1738 | ||
| 1743 | /* Initialize this module when Emacs starts. */ | 1739 | /* Initialize this module when Emacs starts. */ |
diff --git a/src/keyboard.c b/src/keyboard.c index 5fa58abce1d..590d183c4c6 100644 --- a/src/keyboard.c +++ b/src/keyboard.c | |||
| @@ -12475,13 +12475,11 @@ keys_of_keyboard (void) | |||
| 12475 | void | 12475 | void |
| 12476 | mark_kboards (void) | 12476 | mark_kboards (void) |
| 12477 | { | 12477 | { |
| 12478 | KBOARD *kb; | 12478 | for (KBOARD *kb = all_kboards; kb; kb = kb->next_kboard) |
| 12479 | Lisp_Object *p; | ||
| 12480 | for (kb = all_kboards; kb; kb = kb->next_kboard) | ||
| 12481 | { | 12479 | { |
| 12482 | if (kb->kbd_macro_buffer) | 12480 | if (kb->kbd_macro_buffer) |
| 12483 | for (p = kb->kbd_macro_buffer; p < kb->kbd_macro_ptr; p++) | 12481 | mark_objects (kb->kbd_macro_buffer, |
| 12484 | mark_object (*p); | 12482 | kb->kbd_macro_ptr - kb->kbd_macro_buffer); |
| 12485 | mark_object (KVAR (kb, Voverriding_terminal_local_map)); | 12483 | mark_object (KVAR (kb, Voverriding_terminal_local_map)); |
| 12486 | mark_object (KVAR (kb, Vlast_command)); | 12484 | mark_object (KVAR (kb, Vlast_command)); |
| 12487 | mark_object (KVAR (kb, Vreal_last_command)); | 12485 | mark_object (KVAR (kb, Vreal_last_command)); |
diff --git a/src/lisp.h b/src/lisp.h index bc069ef2774..88e69b9061d 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -3756,12 +3756,12 @@ extern AVOID memory_full (size_t); | |||
| 3756 | extern AVOID buffer_memory_full (ptrdiff_t); | 3756 | extern AVOID buffer_memory_full (ptrdiff_t); |
| 3757 | extern bool survives_gc_p (Lisp_Object); | 3757 | extern bool survives_gc_p (Lisp_Object); |
| 3758 | extern void mark_object (Lisp_Object); | 3758 | extern void mark_object (Lisp_Object); |
| 3759 | extern void mark_objects (Lisp_Object *, ptrdiff_t); | ||
| 3759 | #if defined REL_ALLOC && !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC | 3760 | #if defined REL_ALLOC && !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC |
| 3760 | extern void refill_memory_reserve (void); | 3761 | extern void refill_memory_reserve (void); |
| 3761 | #endif | 3762 | #endif |
| 3762 | extern void alloc_unexec_pre (void); | 3763 | extern void alloc_unexec_pre (void); |
| 3763 | extern void alloc_unexec_post (void); | 3764 | extern void alloc_unexec_post (void); |
| 3764 | extern void mark_maybe_objects (Lisp_Object const *, ptrdiff_t); | ||
| 3765 | extern void mark_stack (char const *, char const *); | 3765 | extern void mark_stack (char const *, char const *); |
| 3766 | extern void flush_stack_call_func1 (void (*func) (void *arg), void *arg); | 3766 | extern void flush_stack_call_func1 (void (*func) (void *arg), void *arg); |
| 3767 | 3767 | ||
| @@ -4873,7 +4873,10 @@ safe_free_unbind_to (ptrdiff_t count, ptrdiff_t sa_count, Lisp_Object val) | |||
| 4873 | (buf) = AVAIL_ALLOCA (alloca_nbytes); \ | 4873 | (buf) = AVAIL_ALLOCA (alloca_nbytes); \ |
| 4874 | else \ | 4874 | else \ |
| 4875 | { \ | 4875 | { \ |
| 4876 | (buf) = xmalloc (alloca_nbytes); \ | 4876 | /* Although only the first nelt words need clearing, \ |
| 4877 | typically EXTRA is 0 or small so just use xzalloc; \ | ||
| 4878 | this is simpler and often faster. */ \ | ||
| 4879 | (buf) = xzalloc (alloca_nbytes); \ | ||
| 4877 | record_unwind_protect_array (buf, nelt); \ | 4880 | record_unwind_protect_array (buf, nelt); \ |
| 4878 | } \ | 4881 | } \ |
| 4879 | } while (false) | 4882 | } while (false) |