aboutsummaryrefslogtreecommitdiffstats
path: root/src/ralloc.c
diff options
context:
space:
mode:
authorTom Tromey2012-09-04 10:10:06 -0600
committerTom Tromey2012-09-04 10:10:06 -0600
commitbf69f522a9e135f9aa483cedd53e71e915f2bf75 (patch)
tree3f73c47fb863ef87f420de1d30858da821072bd9 /src/ralloc.c
parent303324a9232dbc89369faceb6b3530740d0fc1bd (diff)
parent6ec9a5a7b5efb129807f567709ca858211ed7840 (diff)
downloademacs-bf69f522a9e135f9aa483cedd53e71e915f2bf75.tar.gz
emacs-bf69f522a9e135f9aa483cedd53e71e915f2bf75.zip
merge from trunk
Diffstat (limited to 'src/ralloc.c')
-rw-r--r--src/ralloc.c45
1 files changed, 32 insertions, 13 deletions
diff --git a/src/ralloc.c b/src/ralloc.c
index c40258693f5..3877e21d4f6 100644
--- a/src/ralloc.c
+++ b/src/ralloc.c
@@ -670,6 +670,7 @@ static void
670free_bloc (bloc_ptr bloc) 670free_bloc (bloc_ptr bloc)
671{ 671{
672 heap_ptr heap = bloc->heap; 672 heap_ptr heap = bloc->heap;
673 heap_ptr h;
673 674
674 if (r_alloc_freeze_level) 675 if (r_alloc_freeze_level)
675 { 676 {
@@ -699,20 +700,38 @@ free_bloc (bloc_ptr bloc)
699 bloc->prev->next = bloc->next; 700 bloc->prev->next = bloc->next;
700 } 701 }
701 702
702 /* Update the records of which blocs are in HEAP. */ 703 /* Sometimes, 'heap' obtained from bloc->heap above is not really a
703 if (heap->first_bloc == bloc) 704 'heap' structure. It can even be beyond the current break point,
705 which will cause crashes when we dereference it below (see
706 bug#12242). Evidently, the reason is bloc allocations done while
707 use_relocatable_buffers was non-positive, because additional
708 memory we get then is not recorded in the heaps we manage. If
709 bloc->heap records such a "heap", we cannot (and don't need to)
710 update its records. So we validate the 'heap' value by making
711 sure it is one of the heaps we manage via the heaps linked list,
712 and don't touch a 'heap' that isn't found there. This avoids
713 accessing memory we know nothing about. */
714 for (h = first_heap; h != NIL_HEAP; h = h->next)
715 if (heap == h)
716 break;
717
718 if (h)
704 { 719 {
705 if (bloc->next != 0 && bloc->next->heap == heap) 720 /* Update the records of which blocs are in HEAP. */
706 heap->first_bloc = bloc->next; 721 if (heap->first_bloc == bloc)
707 else 722 {
708 heap->first_bloc = heap->last_bloc = NIL_BLOC; 723 if (bloc->next != 0 && bloc->next->heap == heap)
709 } 724 heap->first_bloc = bloc->next;
710 if (heap->last_bloc == bloc) 725 else
711 { 726 heap->first_bloc = heap->last_bloc = NIL_BLOC;
712 if (bloc->prev != 0 && bloc->prev->heap == heap) 727 }
713 heap->last_bloc = bloc->prev; 728 if (heap->last_bloc == bloc)
714 else 729 {
715 heap->first_bloc = heap->last_bloc = NIL_BLOC; 730 if (bloc->prev != 0 && bloc->prev->heap == heap)
731 heap->last_bloc = bloc->prev;
732 else
733 heap->first_bloc = heap->last_bloc = NIL_BLOC;
734 }
716 } 735 }
717 736
718 relinquish (); 737 relinquish ();