fixpool: allocate a new chunk on creation

Allocate the first chunk when the fixpool is created.  This avoid a
undefined behavior reported in issue #413 without requiring an extra
comparison in allocate().

* spot/misc/fixpool.hh, spot/misc/fixpool.cc (new_chunk_): New method
extracted from allocate().  Use it in the constructor as well.
* NEWS: Mention the bug.
This commit is contained in:
Alexandre Duret-Lutz 2020-05-22 15:33:40 +02:00
parent 64aee87d76
commit ce695e67f9
3 changed files with 23 additions and 14 deletions

2
NEWS
View file

@ -34,6 +34,8 @@ New in spot 2.9.0.dev (not yet released)
Bugs fixed:
- Work around undefined behavior reported by clang 10.0.0's UBsan.
- spot::twa_sub_statistics was very slow at computing the number of
transitons, and could overflow. It is now avoiding some costly
loop of BDD operations, and storing the result using at least 64

View file

@ -1,5 +1,5 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2017-2018 Laboratoire de Recherche et
// Copyright (C) 2017-2018, 2020 Laboratoire de Recherche et
// Développement de l'Epita (LRDE)
//
// This file is part of Spot, a model checking library.
@ -106,7 +106,20 @@ namespace spot
return (size + mask) & ~mask;
}
}(size)),
freelist_(nullptr), free_start_(nullptr),
free_end_(nullptr), chunklist_(nullptr)
{}
freelist_(nullptr),
chunklist_(nullptr)
{
new_chunk_();
}
void fixed_size_pool::new_chunk_()
{
const size_t requested = (size_ > 128 ? size_ : 128) * 8192 - 64;
chunk_* c = reinterpret_cast<chunk_*>(::operator new(requested));
c->prev = chunklist_;
chunklist_ = c;
free_start_ = c->data_ + size_;
free_end_ = c->data_ + requested;
}
}

View file

@ -1,5 +1,5 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2011, 2015-2018 Laboratoire de Recherche et
// Copyright (C) 2011, 2015-2018, 2020 Laboratoire de Recherche et
// Développement de l'Epita (LRDE)
//
// This file is part of Spot, a model checking library.
@ -68,15 +68,7 @@ namespace spot
// If all the last chunk has been used, allocate one more.
if (free_start_ + size_ > free_end_)
{
const size_t requested = (size_ > 128 ? size_ : 128) * 8192 - 64;
chunk_* c = reinterpret_cast<chunk_*>(::operator new(requested));
c->prev = chunklist_;
chunklist_ = c;
free_start_ = c->data_ + size_;
free_end_ = c->data_ + requested;
}
new_chunk_();
void* res = free_start_;
free_start_ += size_;
@ -105,6 +97,8 @@ namespace spot
}
private:
void new_chunk_();
const size_t size_;
struct block_ { block_* next; }* freelist_;
char* free_start_;