[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.
This commit is contained in:
Behdad Esfahbod 2023-01-01 18:38:28 -07:00
parent 1119e60296
commit b87360763e
1 changed files with 25 additions and 8 deletions

View File

@ -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. */
}