From 645935f79661f9e3cad69f23067ef885f2051564 Mon Sep 17 00:00:00 2001 From: Alexandre Duret-Lutz Date: Fri, 22 May 2020 15:33:40 +0200 Subject: [PATCH] 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. --- NEWS | 2 ++ spot/misc/fixpool.cc | 21 +++++++++++++++++---- spot/misc/fixpool.hh | 14 ++++---------- 3 files changed, 23 insertions(+), 14 deletions(-) diff --git a/NEWS b/NEWS index 4cbfe8128..93dfdd42e 100644 --- a/NEWS +++ b/NEWS @@ -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 diff --git a/spot/misc/fixpool.cc b/spot/misc/fixpool.cc index 30e0e45c3..06dbd55d8 100644 --- a/spot/misc/fixpool.cc +++ b/spot/misc/fixpool.cc @@ -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(::operator new(requested)); + c->prev = chunklist_; + chunklist_ = c; + + free_start_ = c->data_ + size_; + free_end_ = c->data_ + requested; + } } diff --git a/spot/misc/fixpool.hh b/spot/misc/fixpool.hh index 4d79a192f..4d2068205 100644 --- a/spot/misc/fixpool.hh +++ b/spot/misc/fixpool.hh @@ -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(::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_;