[core] Cut the number of Hash internal structure allocations in half.
From: Mark Glines <mark@glines.org>
---
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
|
b
|
|
| 720 | 720 | HashBucket *bs, *b; |
| 721 | 721 | |
| 722 | 722 | void * const old_mem = hash->bs; |
| | 723 | HashBucket *old_offset = (void*)hash + sizeof(Hash); |
| 723 | 724 | const UINTVAL old_size = hash->mask + 1; |
| 724 | 725 | const UINTVAL new_size = old_size << 1; |
| 725 | 726 | const UINTVAL old_nb = N_BUCKETS(old_size); |
| … |
… |
|
| 737 | 738 | */ |
| 738 | 739 | |
| 739 | 740 | /* resize mem */ |
| 740 | | HashBucket * const new_mem = |
| 741 | | (HashBucket *)mem_sys_realloc(old_mem, HASH_ALLOC_SIZE(new_size)); |
| | 741 | HashBucket *new_mem; |
| | 742 | if(old_offset != old_mem) { |
| | 743 | /* This buffer has been reallocated at least once before. */ |
| | 744 | new_mem = (HashBucket *)mem_sys_realloc(old_mem, HASH_ALLOC_SIZE(new_size)); |
| | 745 | } else { |
| | 746 | /* Allocate a new buffer. */ |
| | 747 | new_mem = (HashBucket *)mem_sys_allocate(HASH_ALLOC_SIZE(new_size)); |
| | 748 | memcpy(new_mem, old_mem, HASH_ALLOC_SIZE(old_size)); |
| | 749 | } |
| 742 | 750 | |
| 743 | 751 | /* |
| 744 | 752 | +---+---+---+---+---+---+-+-+-+-+-+-+-+-+ |
| … |
… |
|
| 954 | 962 | { |
| 955 | 963 | ASSERT_ARGS(parrot_create_hash) |
| 956 | 964 | HashBucket *bp; |
| 957 | | Hash * const hash = mem_allocate_typed(Hash); |
| | 965 | void *alloc = mem_sys_allocate(sizeof(Hash) + HASH_ALLOC_SIZE(INITIAL_BUCKETS)); |
| | 966 | Hash * const hash = alloc; |
| 958 | 967 | size_t i; |
| 959 | 968 | |
| 960 | 969 | PARROT_ASSERT(INITIAL_BUCKETS % 4 == 0); |
| … |
… |
|
| 974 | 983 | * - use the bucket store and bi inside this structure |
| 975 | 984 | * - when reallocate copy this part |
| 976 | 985 | */ |
| 977 | | bp = (HashBucket *)mem_sys_allocate(HASH_ALLOC_SIZE(INITIAL_BUCKETS)); |
| | 986 | bp = (HashBucket *)(alloc + sizeof(Hash)); |
| 978 | 987 | hash->free_list = NULL; |
| 979 | 988 | |
| 980 | 989 | /* fill free_list from hi addresses so that we can use |
| … |
… |
|
| 1015 | 1024 | parrot_hash_destroy(SHIM_INTERP, ARGMOD(Hash *hash)) |
| 1016 | 1025 | { |
| 1017 | 1026 | ASSERT_ARGS(parrot_hash_destroy) |
| 1018 | | mem_sys_free(hash->bs); |
| | 1027 | HashBucket *bp = (void*)hash + sizeof(Hash); |
| | 1028 | if(bp != hash->bs) |
| | 1029 | mem_sys_free(hash->bs); |
| 1019 | 1030 | mem_sys_free(hash); |
| 1020 | 1031 | } |
| 1021 | 1032 | |