From b87360763ece0494951071793140c1e4336cf19b Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 1 Jan 2023 18:38:28 -0700 Subject: [PATCH] [vector] Support shrinking storage if exact size provided Only do it if requested size is less than quarter of allocated size. This has massive benefit during CFF subset preprocessing. --- src/hb-vector.hh | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/src/hb-vector.hh b/src/hb-vector.hh index bb7af2b82..46efb9705 100644 --- a/src/hb-vector.hh +++ b/src/hb-vector.hh @@ -342,24 +342,39 @@ struct hb_vector_t if (unlikely (in_error ())) return false; - if (likely (size <= (unsigned) allocated)) - return true; + unsigned int new_allocated; + if (exact) + { + /* If exact was specified, we allow shrinking the storage. */ + size = hb_max (size, length); + if (size <= (unsigned) allocated && + size >= (unsigned) allocated >> 2) + return true; + + new_allocated = size; + } + else + { + if (likely (size <= (unsigned) allocated)) + return true; + + new_allocated = allocated; + while (size > new_allocated) + new_allocated += (new_allocated >> 1) + 8; + } + /* Reallocate */ - unsigned int new_allocated = exact ? size : allocated; - while (size > new_allocated) - new_allocated += (new_allocated >> 1) + 8; - Type *new_array = nullptr; bool overflows = (int) in_error () || - (new_allocated < (unsigned) allocated) || + (new_allocated < size) || hb_unsigned_mul_overflows (new_allocated, sizeof (Type)); if (likely (!overflows)) new_array = realloc_vector (new_allocated); - if (unlikely (!new_array)) + if (unlikely (new_allocated && !new_array)) { allocated = -1; return false; @@ -429,6 +444,8 @@ struct hb_vector_t return; shrink_vector (size); + + alloc (size, true); /* To force shrinking memory if needed. */ }