[core] Cut the number of Hash internal structure allocations in half. From: Mark Glines --- src/hash.c | 21 ++++++++++++++++----- 1 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/hash.c b/src/hash.c index 0bd7054..6392d6b 100644 --- a/src/hash.c +++ b/src/hash.c @@ -720,6 +720,7 @@ expand_hash(PARROT_INTERP, ARGMOD(Hash *hash)) HashBucket *bs, *b; void * const old_mem = hash->bs; + HashBucket *old_offset = (void*)hash + sizeof(Hash); const UINTVAL old_size = hash->mask + 1; const UINTVAL new_size = old_size << 1; const UINTVAL old_nb = N_BUCKETS(old_size); @@ -737,8 +738,15 @@ expand_hash(PARROT_INTERP, ARGMOD(Hash *hash)) */ /* resize mem */ - HashBucket * const new_mem = - (HashBucket *)mem_sys_realloc(old_mem, HASH_ALLOC_SIZE(new_size)); + HashBucket *new_mem; + if(old_offset != old_mem) { + /* This buffer has been reallocated at least once before. */ + new_mem = (HashBucket *)mem_sys_realloc(old_mem, HASH_ALLOC_SIZE(new_size)); + } else { + /* Allocate a new buffer. */ + new_mem = (HashBucket *)mem_sys_allocate(HASH_ALLOC_SIZE(new_size)); + memcpy(new_mem, old_mem, HASH_ALLOC_SIZE(old_size)); + } /* +---+---+---+---+---+---+-+-+-+-+-+-+-+-+ @@ -954,7 +962,8 @@ parrot_create_hash(PARROT_INTERP, PARROT_DATA_TYPE val_type, Hash_key_type hkey_ { ASSERT_ARGS(parrot_create_hash) HashBucket *bp; - Hash * const hash = mem_allocate_typed(Hash); + void *alloc = mem_sys_allocate(sizeof(Hash) + HASH_ALLOC_SIZE(INITIAL_BUCKETS)); + Hash * const hash = alloc; size_t i; PARROT_ASSERT(INITIAL_BUCKETS % 4 == 0); @@ -974,7 +983,7 @@ parrot_create_hash(PARROT_INTERP, PARROT_DATA_TYPE val_type, Hash_key_type hkey_ * - use the bucket store and bi inside this structure * - when reallocate copy this part */ - bp = (HashBucket *)mem_sys_allocate(HASH_ALLOC_SIZE(INITIAL_BUCKETS)); + bp = (HashBucket *)(alloc + sizeof(Hash)); hash->free_list = NULL; /* fill free_list from hi addresses so that we can use @@ -1015,7 +1024,9 @@ void parrot_hash_destroy(SHIM_INTERP, ARGMOD(Hash *hash)) { ASSERT_ARGS(parrot_hash_destroy) - mem_sys_free(hash->bs); + HashBucket *bp = (void*)hash + sizeof(Hash); + if(bp != hash->bs) + mem_sys_free(hash->bs); mem_sys_free(hash); }