+2017-06-02 Richard Biener <rguenther@suse.de>
+ Markus Eisenmann <meisenmann.lba@fh-salzburg.ac.at>
+
+ PR libstdc++/80721
+ * libsupc++/eh_alloc.cc (pool::free): Keep list properly
+ sorted and add missing freelist item merging cases.
+
2017-06-01 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
(GLIBCXX_CROSSCONFIG): Handle *-solaris* like *-linux* etc.
allocated_entry *x;
if ((*e)->size - size >= sizeof (free_entry))
{
- // Slit block if it is too large.
+ // Split block if it is too large.
free_entry *f = reinterpret_cast <free_entry *>
(reinterpret_cast <char *> (*e) + size);
std::size_t sz = (*e)->size;
allocated_entry *e = reinterpret_cast <allocated_entry *>
(reinterpret_cast <char *> (data) - offsetof (allocated_entry, data));
std::size_t sz = e->size;
- if (!first_free_entry)
+ if (!first_free_entry
+ || (reinterpret_cast <char *> (e) + sz
+ < reinterpret_cast <char *> (first_free_entry)))
{
- // If the free list is empty just put the entry there.
+ // If the free list is empty or the entry is before the
+ // first element and cannot be merged with it add it as
+ // the first free entry.
free_entry *f = reinterpret_cast <free_entry *> (e);
new (f) free_entry;
f->size = sz;
- f->next = NULL;
+ f->next = first_free_entry;
first_free_entry = f;
}
else if (reinterpret_cast <char *> (e) + sz
> reinterpret_cast <char *> (e) + sz);
fe = &(*fe)->next)
;
+ // If we can merge the next block into us do so and continue
+ // with the cases below.
+ if (reinterpret_cast <char *> (e) + sz
+ == reinterpret_cast <char *> ((*fe)->next))
+ {
+ sz += (*fe)->next->size;
+ (*fe)->next = (*fe)->next->next;
+ }
if (reinterpret_cast <char *> (*fe) + (*fe)->size
== reinterpret_cast <char *> (e))
- /* Merge with the freelist entry. */
+ // Merge with the freelist entry.
(*fe)->size += sz;
else
{