Merge pull request #5570 from harfbuzz/alloc-pool-improvements
[alloc-pool] Implement alignment
diff --git a/src/hb-alloc-pool.hh b/src/hb-alloc-pool.hh
index bf954ca..efa7e52 100644
--- a/src/hb-alloc-pool.hh
+++ b/src/hb-alloc-pool.hh
@@ -42,10 +42,14 @@
{
unsigned ChunkSize = 65536 - 2 * sizeof (void *);
- void *alloc (size_t size)
+ void *alloc (size_t size, unsigned alignment = 2 * sizeof (void *))
{
if (unlikely (chunks.in_error ())) return nullptr;
+ assert (alignment > 0);
+ assert (alignment <= 2 * sizeof (void *));
+ assert ((alignment & (alignment - 1)) == 0); /* power of two */
+
if (size > (ChunkSize) / 4)
{
/* Big chunk, allocate separately. */
@@ -63,8 +67,11 @@
return ret;
}
+ unsigned pad = current_chunk.length & (alignment - 1);
+ if (pad) pad = alignment - pad;
+
// Small chunk, allocate from the last chunk.
- if (current_chunk.length < size)
+ if (current_chunk.length < pad + size)
{
chunks.push ();
if (unlikely (chunks.in_error ())) return nullptr;
@@ -72,6 +79,8 @@
if (unlikely (!chunk.resize (ChunkSize))) return nullptr;
current_chunk = chunk;
}
+ else
+ current_chunk += pad;
assert (current_chunk.length >= size);
void *ret = current_chunk.arrayZ;
@@ -79,6 +88,14 @@
return ret;
}
+ void discard (void *p_, size_t size)
+ {
+ // Reclaim memory if we can.
+ char *p = (char *) p_;
+ if (current_chunk.arrayZ == p + size && current_chunk.backwards_length >= size)
+ current_chunk -= size;
+ }
+
private:
hb_vector_t<hb_vector_t<char>> chunks;
hb_array_t<char> current_chunk;
diff --git a/src/hb-ot-var-common.hh b/src/hb-ot-var-common.hh
index 1881251..a8c8858 100644
--- a/src/hb-ot-var-common.hh
+++ b/src/hb-ot-var-common.hh
@@ -523,7 +523,7 @@
o->tupleIndex = flag;
unsigned total_header_len = 4 + (peak_count + interim_count) * (F2DOT14::static_size);
- compiled_tuple_header.shrink (total_header_len, false);
+ compiled_tuple_header.shrink_back_to_pool (pool, total_header_len);
return true;
}
@@ -600,7 +600,7 @@
if (j != rounded_deltas.length) return false;
encoded_len += compile_deltas (compiled_deltas.as_array ().sub_array (encoded_len), rounded_deltas);
}
- compiled_deltas.shrink (encoded_len, false);
+ compiled_deltas.shrink_back_to_pool (pool, encoded_len);
return true;
}
diff --git a/src/hb-vector.hh b/src/hb-vector.hh
index d24ae0b..dc34f41 100644
--- a/src/hb-vector.hh
+++ b/src/hb-vector.hh
@@ -548,7 +548,7 @@
if (allocator)
{
assert (!length && !allocated);
- arrayZ = (Type *) allocator->alloc (size * sizeof (Type));
+ arrayZ = (Type *) allocator->alloc (size * sizeof (Type), alignof (Type));
if (unlikely (!arrayZ))
{
set_error ();
@@ -574,6 +574,17 @@
return true;
}
+ template <typename allocator_t>
+ void shrink_back_to_pool (allocator_t *allocator, int size)
+ {
+ unsigned orig_length = length;
+
+ shrink (size, false);
+
+ if (allocator && !is_owned ())
+ allocator->discard (arrayZ + length, (orig_length - length) * sizeof (Type));
+ }
+
HB_ALWAYS_INLINE_VECTOR_ALLOCS
bool resize_full (int size_, bool initialize, bool exact)
{