|
|
|
@ -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; |
|
|
|
|
|
|
|
|
|
/* Reallocate */ |
|
|
|
|
new_allocated = size; |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
if (likely (size <= (unsigned) allocated)) |
|
|
|
|
return true; |
|
|
|
|
|
|
|
|
|
new_allocated = allocated; |
|
|
|
|
while (size > new_allocated) |
|
|
|
|
new_allocated += (new_allocated >> 1) + 8; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
unsigned int new_allocated = exact ? size : allocated; |
|
|
|
|
while (size > new_allocated) |
|
|
|
|
new_allocated += (new_allocated >> 1) + 8; |
|
|
|
|
|
|
|
|
|
/* Reallocate */ |
|
|
|
|
|
|
|
|
|
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. */ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|