re PR libstdc++/80721 (Sorting/Merging of free EH-emergency buffer may wrong or uncomplete)
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. Co-Authored-By: Markus Eisenmann <meisenmann.lba@fh-salzburg.ac.at> From-SVN: r248816
This commit is contained in:
parent
74b4885d94
commit
1c26adb74d
|
@ -1,3 +1,10 @@
|
||||||
|
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>
|
2017-06-01 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
|
||||||
|
|
||||||
(GLIBCXX_CROSSCONFIG): Handle *-solaris* like *-linux* etc.
|
(GLIBCXX_CROSSCONFIG): Handle *-solaris* like *-linux* etc.
|
||||||
|
|
|
@ -162,7 +162,7 @@ namespace
|
||||||
allocated_entry *x;
|
allocated_entry *x;
|
||||||
if ((*e)->size - size >= sizeof (free_entry))
|
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 *>
|
free_entry *f = reinterpret_cast <free_entry *>
|
||||||
(reinterpret_cast <char *> (*e) + size);
|
(reinterpret_cast <char *> (*e) + size);
|
||||||
std::size_t sz = (*e)->size;
|
std::size_t sz = (*e)->size;
|
||||||
|
@ -194,13 +194,17 @@ namespace
|
||||||
allocated_entry *e = reinterpret_cast <allocated_entry *>
|
allocated_entry *e = reinterpret_cast <allocated_entry *>
|
||||||
(reinterpret_cast <char *> (data) - offsetof (allocated_entry, data));
|
(reinterpret_cast <char *> (data) - offsetof (allocated_entry, data));
|
||||||
std::size_t sz = e->size;
|
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);
|
free_entry *f = reinterpret_cast <free_entry *> (e);
|
||||||
new (f) free_entry;
|
new (f) free_entry;
|
||||||
f->size = sz;
|
f->size = sz;
|
||||||
f->next = NULL;
|
f->next = first_free_entry;
|
||||||
first_free_entry = f;
|
first_free_entry = f;
|
||||||
}
|
}
|
||||||
else if (reinterpret_cast <char *> (e) + sz
|
else if (reinterpret_cast <char *> (e) + sz
|
||||||
|
@ -224,9 +228,17 @@ namespace
|
||||||
> reinterpret_cast <char *> (e) + sz);
|
> reinterpret_cast <char *> (e) + sz);
|
||||||
fe = &(*fe)->next)
|
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
|
if (reinterpret_cast <char *> (*fe) + (*fe)->size
|
||||||
== reinterpret_cast <char *> (e))
|
== reinterpret_cast <char *> (e))
|
||||||
/* Merge with the freelist entry. */
|
// Merge with the freelist entry.
|
||||||
(*fe)->size += sz;
|
(*fe)->size += sz;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue