From 7cbba2ea4d213f18215dab823f4e71d24a559bcc Mon Sep 17 00:00:00 2001 From: lateralusX Date: Fri, 3 Mar 2023 12:16:15 +0100 Subject: [PATCH 01/10] dn_vector_t opt + erase fix. --- src/native/containers/dn-vector.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/native/containers/dn-vector.c b/src/native/containers/dn-vector.c index 280d695a549264..7d075aca5ace77 100644 --- a/src/native/containers/dn-vector.c +++ b/src/native/containers/dn-vector.c @@ -86,11 +86,10 @@ _dn_vector_insert_range ( dn_vector_t *vector = position->_internal._vector; uint64_t new_capacity = (uint64_t)vector->size + (uint64_t)element_count; - if (DN_UNLIKELY (new_capacity > (uint64_t)(UINT32_MAX))) - return false; - - if (DN_UNLIKELY (!ensure_capacity (vector, (uint32_t)new_capacity))) - return false; + if (DN_UNLIKELY (new_capacity > (uint64_t)(vector->_internal._capacity))) { + if (DN_UNLIKELY (!ensure_capacity (vector, (uint32_t)new_capacity))) + return false; + } uint64_t insert_offset = (uint64_t)position->it + (uint64_t)element_count; uint64_t size_to_move = (uint64_t)vector->size - (uint64_t)position->it; @@ -125,11 +124,10 @@ _dn_vector_append_range ( DN_ASSERT (vector && elements && element_count != 0); uint64_t new_capacity = (uint64_t)vector->size + (uint64_t)element_count; - if (DN_UNLIKELY (new_capacity > (uint64_t)(UINT32_MAX))) - return false; - - if (DN_UNLIKELY (!ensure_capacity (vector, (uint32_t)new_capacity))) - return false; + if (DN_UNLIKELY (new_capacity > (uint64_t)(vector->_internal._capacity))) { + if (DN_UNLIKELY (!ensure_capacity (vector, (uint32_t)new_capacity))) + return false; + } /* ensure_capacity already verified element_offset and element_length won't overflow. */ memmove (element_offset (vector, vector->size), elements, element_length (vector, element_count)); @@ -152,7 +150,7 @@ _dn_vector_erase ( DN_ASSERT (vector && vector->size != 0); uint64_t insert_offset = (uint64_t)position->it + 1; - int64_t size_to_move = (int64_t)vector->size - (int64_t)position->it; + int64_t size_to_move = (int64_t)vector->size - (int64_t)position->it - 1; if (DN_UNLIKELY (insert_offset > vector->_internal._capacity || size_to_move < 0)) return false; From 7ac55a63454d7373ae224c89983af141097e7669 Mon Sep 17 00:00:00 2001 From: lateralusX Date: Mon, 6 Mar 2023 17:28:09 +0100 Subject: [PATCH 02/10] Fix dn_umap find to use hash code. --- src/native/containers/dn-umap.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/native/containers/dn-umap.c b/src/native/containers/dn-umap.c index 0a862742a16c44..a34ea25bb48b28 100644 --- a/src/native/containers/dn-umap.c +++ b/src/native/containers/dn-umap.c @@ -515,7 +515,7 @@ dn_umap_extract_key ( dn_umap_it_t dn_umap_custom_find ( dn_umap_t *map, - const void *data, + const void *key, dn_umap_equal_func_t equal_func) { DN_ASSERT (map); @@ -523,13 +523,14 @@ dn_umap_custom_find ( dn_umap_it_t found = dn_umap_end (map); equal_func = equal_func ? equal_func : map->_internal._key_equal_func; - for (uint32_t i = 0; i < map->_internal._bucket_count; i++) { - for (dn_umap_node_t *node = map->_internal._buckets [i]; node; node = node->next) - if (equal_func (node->key, data)) { - found._internal._index = i; - found._internal._node = node; - return found; - } + uint32_t hashcode = map->_internal._hash_func (key) % map->_internal._bucket_count; + + for (dn_umap_node_t *node = map->_internal._buckets [hashcode]; node; node = node->next) { + if (equal_func (node->key, key)) { + found._internal._index = hashcode; + found._internal._node = node; + return found; + } } return found; From f75102c1aa12a5358d0d9f38d11da62bea623895 Mon Sep 17 00:00:00 2001 From: lateralusX Date: Mon, 6 Mar 2023 17:36:26 +0100 Subject: [PATCH 03/10] Default dn_vector_t to not initialize memory. --- .../mono/eventpipe/test/dn-vector-ptr-tests.c | 28 ++++++++ .../mono/eventpipe/test/dn-vector-tests.c | 66 +++++++++++-------- src/native/containers/dn-vector-types.h | 2 +- src/native/containers/dn-vector.c | 10 +-- 4 files changed, 71 insertions(+), 35 deletions(-) diff --git a/src/mono/mono/eventpipe/test/dn-vector-ptr-tests.c b/src/mono/mono/eventpipe/test/dn-vector-ptr-tests.c index e766268bd0277f..b145b294589653 100644 --- a/src/mono/mono/eventpipe/test/dn-vector-ptr-tests.c +++ b/src/mono/mono/eventpipe/test/dn-vector-ptr-tests.c @@ -230,6 +230,33 @@ RESULT test_vector_ptr_resize (void) { dn_vector_ptr_t *vector= dn_vector_ptr_alloc (); + uint32_t grow_length = 50; + + dn_vector_ptr_push_back (vector, (char *)test_vector_ptr_items [0]); + dn_vector_ptr_push_back (vector, (char *)test_vector_ptr_items [1]); + dn_vector_ptr_resize (vector, grow_length); + + if (vector->size != grow_length) { + return FAILED ("vector size should be 50, it is %d", vector->size); + } else if (*dn_vector_ptr_index (vector, 0) != test_vector_ptr_items [0]) { + return FAILED ("item 0 was overwritten, should be %s", test_vector_ptr_items [0]); + } else if (*dn_vector_ptr_index (vector, 1) != test_vector_ptr_items [1]) { + return FAILED ("item 1 was overwritten, should be %s", test_vector_ptr_items [1]); + } + + dn_vector_ptr_free (vector); + + return OK; +} + +static +RESULT +test_vector_ptr_resize_2 (void) +{ + dn_vector_ptr_custom_alloc_params_t params = {0,}; + params.attributes = DN_VECTOR_ATTRIBUTE_MEMORY_INIT; + + dn_vector_ptr_t *vector= dn_vector_ptr_custom_alloc (¶ms); uint32_t i, grow_length = 50; dn_vector_ptr_push_back (vector, (char *)test_vector_ptr_items [0]); @@ -941,6 +968,7 @@ static Test dn_vector_ptr_tests [] = { {"test_vector_ptr_for_iterate", test_vector_ptr_for_iterate}, {"test_vector_ptr_foreach_iterate", test_vector_ptr_foreach_iterate}, {"test_vector_ptr_resize", test_vector_ptr_resize}, + {"test_vector_ptr_resize_2", test_vector_ptr_resize_2}, {"test_vector_ptr_erase", test_vector_ptr_erase}, {"test_vector_ptr_erase_fast", test_vector_ptr_erase_fast}, {"test_vector_ptr_capacity", test_vector_ptr_capacity}, diff --git a/src/mono/mono/eventpipe/test/dn-vector-tests.c b/src/mono/mono/eventpipe/test/dn-vector-tests.c index 2c15be39fc904a..2d8427147334ef 100644 --- a/src/mono/mono/eventpipe/test/dn-vector-tests.c +++ b/src/mono/mono/eventpipe/test/dn-vector-tests.c @@ -52,7 +52,6 @@ test_vector_alloc (void) dn_vector_custom_alloc_params_t params = {0,}; params.capacity = 32; - params.attributes = DN_VECTOR_ATTRIBUTE_DISABLE_MEMORY_INIT; vector = dn_vector_custom_alloc_t (¶ms, int32_t); if (vector->size != 0) @@ -98,6 +97,7 @@ test_vector_alloc_capacity (void) dn_vector_t *vector = NULL; dn_vector_custom_alloc_params_t params = {0, }; + params.attributes = DN_VECTOR_ATTRIBUTE_MEMORY_INIT; params.capacity = PREALLOC_SIZE; vector = dn_vector_custom_alloc_t (¶ms, int32_t); @@ -133,6 +133,7 @@ test_vector_init_capacity (void) { dn_vector_t vector; dn_vector_custom_init_params_t params = {0, }; + params.attributes = DN_VECTOR_ATTRIBUTE_MEMORY_INIT; params.capacity = PREALLOC_SIZE; if (!dn_vector_custom_init_t (&vector, ¶ms, int32_t)) @@ -777,27 +778,28 @@ test_vector_erase_3 (void) if (vector->size != 0) return FAILED ("vector size didn't match"); + int32_t value = INT32_MAX; for (int32_t i = 0; i < 10; ++i) - dn_vector_push_back (vector, i); + dn_vector_push_back (vector, value); dn_vector_erase (dn_vector_begin (vector)); - if (((uint32_t *)vector->data) [9] != 0) - return FAILED ("erase didn't zero memory."); + if (((uint32_t *)vector->data) [9] == 0) + return FAILED ("erase initialized memory, but shouldn't."); dn_vector_free (vector); dn_vector_custom_alloc_params_t params = {0, }; - params.attributes = DN_VECTOR_ATTRIBUTE_DISABLE_MEMORY_INIT; + params.attributes = DN_VECTOR_ATTRIBUTE_MEMORY_INIT; vector = dn_vector_custom_alloc_t (¶ms, int32_t); for (int32_t i = 0; i < 10; ++i) - dn_vector_push_back (vector, i); + dn_vector_push_back (vector, value); dn_vector_erase (dn_vector_begin (vector)); - if (((uint32_t *)vector->data) [9] == 0) - return FAILED ("resize zeroed memory, but shouldn't."); + if (((uint32_t *)vector->data) [9] != 0) + return FAILED ("erase didn't initialize memory, but should"); dn_vector_free (vector); @@ -865,27 +867,29 @@ test_vector_erase_fast_3 (void) if (vector->size != 0) return FAILED ("vector size didn't match"); + int32_t value = INT32_MAX; + for (int32_t i = 0; i < 10; ++i) - dn_vector_push_back (vector, i); + dn_vector_push_back (vector, value); dn_vector_erase_fast (dn_vector_begin (vector)); - if (((uint32_t *)vector->data) [9] != 0) - return FAILED ("erase didn't zero memory."); + if (((uint32_t *)vector->data) [9] == 0) + return FAILED ("erase initialized memory, but shouldn't."); dn_vector_free (vector); dn_vector_custom_alloc_params_t params = {0, }; - params.attributes = DN_VECTOR_ATTRIBUTE_DISABLE_MEMORY_INIT; + params.attributes = DN_VECTOR_ATTRIBUTE_MEMORY_INIT; vector = dn_vector_custom_alloc_t (¶ms, int32_t); for (int32_t i = 0; i < 10; ++i) - dn_vector_push_back (vector, i); + dn_vector_push_back (vector, value); dn_vector_erase_fast (dn_vector_begin (vector)); - if (((uint32_t *)vector->data) [9] == 0) - return FAILED ("resize zeroed memory, but shouldn't."); + if (((uint32_t *)vector->data) [9] != 0) + return FAILED ("erase didn't initialize memory, but should"); dn_vector_free (vector); @@ -996,30 +1000,32 @@ test_vector_resize_3 (void) if (vector->size != 0) return FAILED ("vector size didn't match #1"); + int32_t value = INT32_MAX; + for (int32_t i = 0; i < 10; ++i) - dn_vector_push_back (vector, i); + dn_vector_push_back (vector, value); dn_vector_resize (vector, 5); for (uint32_t i = 5; i < 10; ++i) { - if (((uint32_t *)vector->data) [i] != 0) - return FAILED ("resize didn't zero memory."); + if (((uint32_t *)vector->data) [i] == 0) + return FAILED ("resize initialized memory, but shouldn't."); } dn_vector_free (vector); dn_vector_custom_alloc_params_t params = {0, }; - params.attributes = DN_VECTOR_ATTRIBUTE_DISABLE_MEMORY_INIT; + params.attributes = DN_VECTOR_ATTRIBUTE_MEMORY_INIT; vector = dn_vector_custom_alloc_t (¶ms, int32_t); for (int32_t i = 0; i < 10; ++i) - dn_vector_push_back (vector, i); + dn_vector_push_back (vector, value); dn_vector_resize (vector, 5); for (uint32_t i = 5; i < 10; ++i) { - if (((uint32_t *)vector->data) [i] != i) - return FAILED ("resize zeroed memory, but shouldn't."); + if (((uint32_t *)vector->data) [i] != 0) + return FAILED ("resize didn't initialize memory, but should"); } dn_vector_free (vector); @@ -1077,30 +1083,32 @@ test_vector_clear_3 (void) if (vector->size != 0) return FAILED ("vector size didn't match #1"); + int32_t value = INT32_MAX; + for (int32_t i = 0; i < 10; ++i) - dn_vector_push_back (vector, i); + dn_vector_push_back (vector, value); dn_vector_clear (vector); for (int32_t i = 0; i < 10; ++i) { - if (((uint32_t *)vector->data) [i] != 0) - return FAILED ("clear didn't zero memory."); + if (((uint32_t *)vector->data) [i] == 0) + return FAILED ("clear initialized memory, but shouldn't."); } dn_vector_free (vector); dn_vector_custom_alloc_params_t params = {0, }; - params.attributes = DN_VECTOR_ATTRIBUTE_DISABLE_MEMORY_INIT; + params.attributes = DN_VECTOR_ATTRIBUTE_MEMORY_INIT; vector = dn_vector_custom_alloc_t (¶ms, int32_t); for (int32_t i = 0; i < 10; ++i) - dn_vector_push_back (vector, i); + dn_vector_push_back (vector, value); dn_vector_clear (vector); for (int32_t i = 0; i < 10; ++i) { - if (((uint32_t *)vector->data) [i] != i) - return FAILED ("clear zeroed memory, but shouldn't."); + if (((uint32_t *)vector->data) [i] != 0) + return FAILED ("clear didn't initialize memory, but should."); } dn_vector_free (vector); diff --git a/src/native/containers/dn-vector-types.h b/src/native/containers/dn-vector-types.h index d67f28c55717eb..8592c4dd077c47 100644 --- a/src/native/containers/dn-vector-types.h +++ b/src/native/containers/dn-vector-types.h @@ -47,7 +47,7 @@ struct _ ## name ## _custom_params_t { \ DN_DEFINE_VECTOR_T_STRUCT (dn_vector, uint8_t); typedef enum { - DN_VECTOR_ATTRIBUTE_DISABLE_MEMORY_INIT = 0x1 + DN_VECTOR_ATTRIBUTE_MEMORY_INIT = 0x1 } dn_vector_attribute; #endif /* __DN_VECTOR_TYPES_H__ */ diff --git a/src/native/containers/dn-vector.c b/src/native/containers/dn-vector.c index 7d075aca5ace77..fbd3e9b09d4b0b 100644 --- a/src/native/containers/dn-vector.c +++ b/src/native/containers/dn-vector.c @@ -62,7 +62,7 @@ ensure_capacity ( vector->data = data; - if (vector->data && !check_attribute (vector, DN_VECTOR_ATTRIBUTE_DISABLE_MEMORY_INIT)) { + if (vector->data && check_attribute (vector, DN_VECTOR_ATTRIBUTE_MEMORY_INIT)) { // Checks already verified that element_offset won't overflow. // new_capacity > vector capacity, so new_capacity - vector capacity won't underflow. // dn_safe_size_t_multiply already verified element_length won't overflow. @@ -164,7 +164,7 @@ _dn_vector_erase ( vector->size --; - if (!check_attribute (vector, DN_VECTOR_ATTRIBUTE_DISABLE_MEMORY_INIT)) + if (check_attribute (vector, DN_VECTOR_ATTRIBUTE_MEMORY_INIT)) memset (element_offset(vector, vector->size), 0, element_length (vector, 1)); return true; @@ -191,7 +191,7 @@ _dn_vector_erase_fast ( vector->size --; - if (!check_attribute (vector, DN_VECTOR_ATTRIBUTE_DISABLE_MEMORY_INIT)) + if (check_attribute (vector, DN_VECTOR_ATTRIBUTE_MEMORY_INIT)) memset (element_offset(vector, vector->size), 0, element_length (vector, 1)); return true; @@ -344,7 +344,7 @@ dn_vector_custom_resize ( dispose_func (element_offset (vector, i)); } - if (!check_attribute (vector, DN_VECTOR_ATTRIBUTE_DISABLE_MEMORY_INIT)) + if (check_attribute (vector, DN_VECTOR_ATTRIBUTE_MEMORY_INIT)) memset (element_offset(vector, size), 0, element_length (vector, vector->size - size)); } @@ -365,7 +365,7 @@ dn_vector_custom_pop_back ( if (dispose_func) dispose_func (element_offset (vector, vector->size)); - if (!check_attribute (vector, DN_VECTOR_ATTRIBUTE_DISABLE_MEMORY_INIT)) + if (check_attribute (vector, DN_VECTOR_ATTRIBUTE_MEMORY_INIT)) memset (element_offset (vector, vector->size), 0, vector->_internal._element_size); } From 31dcbe663db12f8429a53959f9782428eb9f2d00 Mon Sep 17 00:00:00 2001 From: lateralusX Date: Mon, 6 Mar 2023 17:36:52 +0100 Subject: [PATCH 04/10] mono_valloc returns zeroed initialized memory. --- src/mono/mono/eventpipe/ep-rt-mono.h | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/mono/mono/eventpipe/ep-rt-mono.h b/src/mono/mono/eventpipe/ep-rt-mono.h index 1169b918aa9536..e72f3dff507d27 100644 --- a/src/mono/mono/eventpipe/ep-rt-mono.h +++ b/src/mono/mono/eventpipe/ep-rt-mono.h @@ -1062,11 +1062,7 @@ inline uint8_t * ep_rt_valloc0 (size_t buffer_size) { - uint8_t *buffer = (uint8_t *)mono_valloc (NULL, buffer_size, MONO_MMAP_READ | MONO_MMAP_WRITE, MONO_MEM_ACCOUNT_PROFILER); - - if (buffer) - memset (buffer, 0, buffer_size); - return buffer; + return (uint8_t *)mono_valloc (NULL, buffer_size, MONO_MMAP_READ | MONO_MMAP_WRITE, MONO_MEM_ACCOUNT_PROFILER); } static From 4b5feb546f92e0929478d2d2bd5f69a01d6c5bad Mon Sep 17 00:00:00 2001 From: lateralusX Date: Tue, 7 Mar 2023 10:08:49 +0100 Subject: [PATCH 05/10] Small dn_umap perf optimizations. --- src/native/containers/dn-umap.c | 109 ++++++++++++++++++-------------- 1 file changed, 61 insertions(+), 48 deletions(-) diff --git a/src/native/containers/dn-umap.c b/src/native/containers/dn-umap.c index a34ea25bb48b28..6935a30c57de13 100644 --- a/src/native/containers/dn-umap.c +++ b/src/native/containers/dn-umap.c @@ -129,7 +129,7 @@ umap_do_rehash ( for (uint32_t i = 0; i < current_bucket_count; i++){ dn_umap_node_t *node, *next_node; for (node = buckets [i]; node; node = next_node){ - uint32_t hashcode = map->_internal._hash_func (node->key) % map->_internal._bucket_count; + uint32_t hashcode = (map->_internal._hash_func (node->key)) % map->_internal._bucket_count; next_node = node->next; node->next = map->_internal._buckets [hashcode]; @@ -144,13 +144,12 @@ static void umap_rehash (dn_umap_t *map) { uint32_t diff; - if (map->_internal._last_rehash > map->_internal._node_count) diff = map->_internal._last_rehash - map->_internal._node_count; else diff = map->_internal._node_count - map->_internal._last_rehash; - if (!((double)diff * 0.75 > (double)map->_internal._bucket_count * 2)) + if (!(diff * 0.75 > map->_internal._bucket_count * 2)) return; umap_do_rehash (map, umap_spaced_primes_closest (map->_internal._node_count)); @@ -202,45 +201,57 @@ umap_erase_node ( umap_sanity_check (map); } -static dn_umap_result_t +static inline void +umap_insert_set_result ( + dn_umap_result_t *insert_result, + dn_umap_t *map, + dn_umap_node_t *node, + uint32_t index, + bool result) +{ + insert_result->it._internal._map = map; + insert_result->it._internal._node = node; + insert_result->it._internal._index = index; + insert_result->result = result; + return; +} + +static void umap_insert ( dn_umap_t *map, void *key, void *value, - bool assign) + bool assign, + dn_umap_result_t *result) { umap_sanity_check (map); - dn_umap_result_t result = { { map, NULL, 0 }, false }; - dn_umap_equal_func_t equal_func = map->_internal._key_equal_func; + if (map->_internal._node_count == dn_umap_max_size (map)) { + umap_insert_set_result (result, map, NULL, 0, false); + return; + } - if (map->_internal._node_count == dn_umap_max_size (map)) - return result; + umap_rehash (map); - if (map->_internal._node_count >= map->_internal._threshold) - umap_rehash (map); + dn_umap_equal_func_t equal_func = map->_internal._key_equal_func; + uint32_t hashcode = (map->_internal._hash_func (key)) % map->_internal._bucket_count; - uint32_t hashcode = map->_internal._hash_func (key) % map->_internal._bucket_count; for (dn_umap_node_t *node = map->_internal._buckets [hashcode]; node; node = node->next) { if (equal_func (node->key, key)) { - if (!assign) { - result.it._internal._node = node; - result.it._internal._index = hashcode; - return result; - } + if (assign) { + if (map->_internal._value_dispose_func) + map->_internal._value_dispose_func (node->value); - if (map->_internal._value_dispose_func) - map->_internal._value_dispose_func (node->value); + node->value = value; - node->value = value; + umap_sanity_check (map); - umap_sanity_check (map); - - result.it._internal._index = hashcode; - result.it._internal._node = node; - result.result = true; - - return result; + umap_insert_set_result (result, map, node, hashcode, true); + return; + } else { + umap_insert_set_result (result, map, node, hashcode, false); + return; + } } } @@ -254,12 +265,12 @@ umap_insert ( umap_sanity_check (map); - result.it._internal._index = hashcode; - result.it._internal._node = node; - result.result = true; + umap_insert_set_result (result, map, node, hashcode, true); + return; } - return result; + umap_insert_set_result (result, map, NULL, 0, false); + return; } static bool @@ -295,12 +306,11 @@ dn_umap_begin (dn_umap_t *map) { DN_ASSERT (map); - dn_umap_it_t it = dn_umap_end (map); uint32_t index = 0; while (true) { if (index >= map->_internal._bucket_count) - return it; + return dn_umap_end (map); if (map->_internal._buckets [index]) break; @@ -308,9 +318,7 @@ dn_umap_begin (dn_umap_t *map) index ++; } - it._internal._node = map->_internal._buckets [index]; - it._internal._index = index; - + dn_umap_it_t it = { map, map->_internal._buckets [index], index }; return it; } @@ -422,7 +430,10 @@ dn_umap_insert ( void *value) { DN_ASSERT (map); - return umap_insert (map, key, value, false); + + dn_umap_result_t result; + umap_insert (map, key, value, false, &result); + return result; } dn_umap_result_t @@ -432,7 +443,10 @@ dn_umap_insert_or_assign ( void *value) { DN_ASSERT (map); - return umap_insert (map, key, value, true); + + dn_umap_result_t result; + umap_insert (map, key, value, true, &result); + return result; } dn_umap_it_t @@ -459,11 +473,11 @@ dn_umap_erase_key ( umap_sanity_check (map); dn_umap_equal_func_t equal_func = map->_internal._key_equal_func; - uint32_t hashcode = map->_internal._hash_func (key) % map->_internal._bucket_count; + uint32_t hashcode = (map->_internal._hash_func (key)) % map->_internal._bucket_count; dn_umap_node_t *prev_node = NULL; for (dn_umap_node_t *node = map->_internal._buckets [hashcode]; node; node = node->next){ - if (equal_func (node->key, key)){ + if (equal_func (node->key, key)) { umap_erase_node (map, hashcode, node, prev_node); return 1; } @@ -484,11 +498,11 @@ dn_umap_extract_key ( DN_ASSERT (map); dn_umap_equal_func_t equal_func = map->_internal._key_equal_func; - uint32_t hashcode = map->_internal._hash_func (key) % map->_internal._bucket_count; + uint32_t hashcode = (map->_internal._hash_func (key)) % map->_internal._bucket_count; dn_umap_node_t *prev_node = NULL; for (dn_umap_node_t *node = map->_internal._buckets [hashcode]; node; node = node->next){ - if (equal_func (node->key, key)){ + if (equal_func (node->key, key)) { if (!prev_node) map->_internal._buckets [hashcode] = node->next; else @@ -520,20 +534,19 @@ dn_umap_custom_find ( { DN_ASSERT (map); - dn_umap_it_t found = dn_umap_end (map); - equal_func = equal_func ? equal_func : map->_internal._key_equal_func; + if (!equal_func) + equal_func = map->_internal._key_equal_func; - uint32_t hashcode = map->_internal._hash_func (key) % map->_internal._bucket_count; + uint32_t hashcode = (map->_internal._hash_func (key)) % map->_internal._bucket_count; for (dn_umap_node_t *node = map->_internal._buckets [hashcode]; node; node = node->next) { if (equal_func (node->key, key)) { - found._internal._index = hashcode; - found._internal._node = node; + dn_umap_it_t found = { map, node, hashcode }; return found; } } - return found; + return dn_umap_end (map); } void From f4e6f55a01591e4be4de8f1320d225510b33109a Mon Sep 17 00:00:00 2001 From: lateralusX Date: Thu, 9 Mar 2023 11:38:05 +0100 Subject: [PATCH 06/10] Drop g_asserts in Windows implementation of mono_vfree. --- src/mono/mono/utils/mono-mmap-windows.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/src/mono/mono/utils/mono-mmap-windows.c b/src/mono/mono/utils/mono-mmap-windows.c index 7f04666b4a4230..6ef8a4e882f1a3 100644 --- a/src/mono/mono/utils/mono-mmap-windows.c +++ b/src/mono/mono/utils/mono-mmap-windows.c @@ -123,19 +123,11 @@ mono_valloc_aligned (size_t length, size_t alignment, int flags, MonoMemAccountT int mono_vfree (void *addr, size_t length, MonoMemAccountType type) { + int res; MEMORY_BASIC_INFORMATION mbi; - SIZE_T query_result = VirtualQuery (addr, &mbi, sizeof (mbi)); - BOOL res; - - g_assert (query_result); - - res = VirtualFree (mbi.AllocationBase, 0, MEM_RELEASE); - - g_assert (res); - + res = (VirtualQuery (addr, &mbi, sizeof (mbi)) != 0 && VirtualFree (mbi.AllocationBase, 0, MEM_RELEASE) != 0) ? 0 : -1; mono_account_mem (type, -(ssize_t)length); - - return 0; + return res; } #if HAVE_API_SUPPORT_WIN32_FILE_MAPPING || HAVE_API_SUPPORT_WIN32_FILE_MAPPING_FROM_APP From a6a444e813112e7c78d555e98b74a19844a33e2f Mon Sep 17 00:00:00 2001 From: lateralusX Date: Thu, 9 Mar 2023 11:38:50 +0100 Subject: [PATCH 07/10] Drop byte->items calc in dn_vector_t. --- .../mono/eventpipe/test/dn-vector-ptr-tests.c | 26 ++++--------- src/native/containers/dn-vector-priv.h | 5 --- src/native/containers/dn-vector-t.h | 5 --- src/native/containers/dn-vector.c | 39 +++++-------------- src/native/containers/dn-vector.h | 3 -- src/native/eventpipe/ds-ipc.c | 2 +- src/native/eventpipe/ep-buffer-manager.c | 8 ++-- src/native/eventpipe/ep-session.c | 2 +- 8 files changed, 24 insertions(+), 66 deletions(-) diff --git a/src/mono/mono/eventpipe/test/dn-vector-ptr-tests.c b/src/mono/mono/eventpipe/test/dn-vector-ptr-tests.c index b145b294589653..1f4fcbcd3d12eb 100644 --- a/src/mono/mono/eventpipe/test/dn-vector-ptr-tests.c +++ b/src/mono/mono/eventpipe/test/dn-vector-ptr-tests.c @@ -610,7 +610,7 @@ test_vector_ptr_default_local_alloc (void) dn_vector_ptr_custom_alloc_params_t params = {0, }; params.allocator = (dn_allocator_t *)&allocator; - uint32_t init_capacity = dn_vector_ptr_buffer_capacity (dn_vector_ptr_default_local_allocator_byte_size); + uint32_t init_capacity = dn_vector_ptr_default_local_allocator_capacity_size; dn_vector_ptr_t *vector = dn_vector_ptr_custom_alloc (¶ms); if (!vector) return FAILED ("failed vector custom alloc"); @@ -694,11 +694,9 @@ test_vector_ptr_local_alloc_capacity (void) dn_allocator_fixed_or_malloc_init (&allocator, buffer, dn_vector_ptr_default_local_allocator_byte_size); memset (buffer, 0, dn_vector_ptr_default_local_allocator_byte_size); - uint32_t init_capacity = dn_vector_ptr_buffer_capacity (dn_vector_ptr_default_local_allocator_byte_size); - dn_vector_ptr_custom_alloc_params_t params = {0, }; params.allocator = (dn_allocator_t *)&allocator; - params.capacity = init_capacity; + params.capacity = dn_vector_ptr_default_local_allocator_capacity_size; dn_vector_ptr_t *vector = dn_vector_ptr_custom_alloc (¶ms); if (!vector) @@ -739,11 +737,9 @@ test_vector_ptr_fixed_alloc_capacity (void) dn_allocator_fixed_init (&allocator, buffer, dn_vector_ptr_default_local_allocator_byte_size); memset (buffer, 0, dn_vector_ptr_default_local_allocator_byte_size); - uint32_t init_capacity = dn_vector_ptr_buffer_capacity (dn_vector_ptr_default_local_allocator_byte_size); - dn_vector_ptr_custom_alloc_params_t params = {0, }; params.allocator = (dn_allocator_t *)&allocator; - params.capacity = init_capacity; + params.capacity = dn_vector_ptr_default_local_allocator_capacity_size; dn_vector_ptr_t *vector = dn_vector_ptr_custom_alloc (¶ms); if (!vector) @@ -781,11 +777,9 @@ test_vector_ptr_fixed_or_malloc_alloc_capacity (void) dn_allocator_fixed_or_malloc_init (&allocator, buffer, dn_vector_ptr_default_local_allocator_byte_size); memset (buffer, 0, dn_vector_ptr_default_local_allocator_byte_size); - uint32_t init_capacity = dn_vector_ptr_buffer_capacity (dn_vector_ptr_default_local_allocator_byte_size); - dn_vector_ptr_custom_alloc_params_t params = {0, }; params.allocator = (dn_allocator_t *)&allocator; - params.capacity = init_capacity; + params.capacity = dn_vector_ptr_default_local_allocator_capacity_size; dn_vector_ptr_t *vector = dn_vector_ptr_custom_alloc (¶ms); if (!vector) @@ -805,10 +799,10 @@ test_vector_ptr_fixed_or_malloc_alloc_capacity (void) if (!dn_vector_ptr_push_back (vector, (char *)test_vector_ptr_items [0])) return FAILED ("failed vector push_back using custom alloc #2"); - if (dn_vector_ptr_capacity (vector) <= init_capacity) + if (dn_vector_ptr_capacity (vector) <= dn_vector_ptr_default_local_allocator_capacity_size) return FAILED ("unexpected vector capacity #1"); - init_capacity = dn_vector_ptr_capacity (vector); + uint32_t init_capacity = dn_vector_ptr_capacity (vector); // Make room for on more item. dn_vector_ptr_pop_back (vector); @@ -842,11 +836,9 @@ test_vector_ptr_fixed_reset_alloc_capacity (void) dn_allocator_fixed_init (&allocator, buffer, dn_vector_ptr_default_local_allocator_byte_size); memset (buffer, 0, dn_vector_ptr_default_local_allocator_byte_size); - uint32_t init_capacity = dn_vector_ptr_buffer_capacity (dn_vector_ptr_default_local_allocator_byte_size); - dn_vector_ptr_custom_alloc_params_t params = {0, }; params.allocator = (dn_allocator_t *)&allocator; - params.capacity = init_capacity; + params.capacity = dn_vector_ptr_default_local_allocator_capacity_size; dn_vector_ptr_t *vector = dn_vector_ptr_custom_alloc (¶ms); if (!vector) @@ -893,11 +885,9 @@ test_vector_ptr_fixed_or_malloc_reset_alloc_capacity (void) dn_allocator_fixed_or_malloc_init (&allocator, buffer, dn_vector_ptr_default_local_allocator_byte_size); memset (buffer, 0, dn_vector_ptr_default_local_allocator_byte_size); - uint32_t init_capacity = dn_vector_ptr_buffer_capacity (dn_vector_ptr_default_local_allocator_byte_size); - dn_vector_ptr_custom_alloc_params_t params = {0, }; params.allocator = (dn_allocator_t *)&allocator; - params.capacity = init_capacity; + params.capacity = dn_vector_ptr_default_local_allocator_capacity_size; dn_vector_ptr_t *vector = dn_vector_ptr_custom_alloc (¶ms); if (!vector) diff --git a/src/native/containers/dn-vector-priv.h b/src/native/containers/dn-vector-priv.h index df6bb25c1b040f..8165a3767ba63e 100644 --- a/src/native/containers/dn-vector-priv.h +++ b/src/native/containers/dn-vector-priv.h @@ -30,11 +30,6 @@ _dn_vector_erase_fast ( dn_vector_it_t *position, dn_vector_dispose_func_t dispose_func); -uint32_t -_dn_vector_buffer_capacity ( - size_t buffer_size, - uint32_t element_size); - dn_vector_it_t _dn_vector_custom_find ( dn_vector_t *vector, diff --git a/src/native/containers/dn-vector-t.h b/src/native/containers/dn-vector-t.h index 91ee8ce91985e9..6305016e239589 100644 --- a/src/native/containers/dn-vector-t.h +++ b/src/native/containers/dn-vector-t.h @@ -255,11 +255,6 @@ DN_DEFINE_VECTOR_T_SYMBOL_NAME(name, pop_back) (DN_DEFINE_VECTOR_T_NAME(name) *v { \ dn_vector_pop_back ((dn_vector_t*)vector); \ } \ -static inline uint32_t \ -DN_DEFINE_VECTOR_T_SYMBOL_NAME(name, buffer_capacity) (size_t buffer_byte_size) \ -{ \ - return dn_vector_buffer_capacity_t (buffer_byte_size, type); \ -} \ static inline void \ DN_DEFINE_VECTOR_T_SYMBOL_NAME(name, for_each) (const DN_DEFINE_VECTOR_T_NAME(name) *vector, dn_vector_for_each_func_t for_each_func, void *user_data) \ { \ diff --git a/src/native/containers/dn-vector.c b/src/native/containers/dn-vector.c index fbd3e9b09d4b0b..4dca0c6e38ac7c 100644 --- a/src/native/containers/dn-vector.c +++ b/src/native/containers/dn-vector.c @@ -25,7 +25,7 @@ #include "dn-vector.h" -#define INITIAL_CAPACITY 16 +#define INITIAL_CAPACITY 64 #define CALC_NEW_CAPACITY(capacity) ((capacity + (capacity >> 1) + 63) & ~63) #define element_offset(p,i) \ @@ -37,16 +37,15 @@ #define check_attribute(vector, value) ((vector->_internal._attributes & (uint32_t)value) == value) static bool -ensure_capacity ( +vector_ensure_capacity ( dn_vector_t *vector, - uint32_t capacity) + uint32_t capacity, + bool init) { - uint64_t new_capacity; - if (capacity != 0 && capacity <= (uint64_t)(vector->_internal._capacity)) return true; - new_capacity = CALC_NEW_CAPACITY (capacity); + uint64_t new_capacity = init ? capacity : CALC_NEW_CAPACITY (capacity); if (DN_UNLIKELY (new_capacity > (uint64_t)(UINT32_MAX))) return false; @@ -87,7 +86,7 @@ _dn_vector_insert_range ( uint64_t new_capacity = (uint64_t)vector->size + (uint64_t)element_count; if (DN_UNLIKELY (new_capacity > (uint64_t)(vector->_internal._capacity))) { - if (DN_UNLIKELY (!ensure_capacity (vector, (uint32_t)new_capacity))) + if (DN_UNLIKELY (!vector_ensure_capacity (vector, (uint32_t)new_capacity, false))) return false; } @@ -125,7 +124,7 @@ _dn_vector_append_range ( uint64_t new_capacity = (uint64_t)vector->size + (uint64_t)element_count; if (DN_UNLIKELY (new_capacity > (uint64_t)(vector->_internal._capacity))) { - if (DN_UNLIKELY (!ensure_capacity (vector, (uint32_t)new_capacity))) + if (DN_UNLIKELY (!vector_ensure_capacity (vector, (uint32_t)new_capacity, false))) return false; } @@ -197,24 +196,6 @@ _dn_vector_erase_fast ( return true; } -uint32_t -_dn_vector_buffer_capacity ( - size_t buffer_byte_size, - uint32_t element_size) -{ - // Estimate maximum array capacity for buffer size. - size_t max_capacity = (buffer_byte_size - DN_ALLOCATOR_ALIGN_SIZE (sizeof (dn_vector_t), DN_ALLOCATOR_MEM_ALIGN8) - 32 /* padding */) / element_size; - if (DN_UNLIKELY (max_capacity > buffer_byte_size || max_capacity > (size_t)UINT32_MAX)) - return 0; - - // Adjust to heuristics in ensure_capacity. - uint32_t capacity = 1; - while(CALC_NEW_CAPACITY (capacity) <= (uint32_t)max_capacity) - capacity <<= 1; - - return (uint32_t)(capacity >> 1); -} - dn_vector_it_t _dn_vector_custom_find ( dn_vector_t *vector, @@ -274,7 +255,7 @@ dn_vector_custom_init ( capacity = params->capacity; } - if (DN_UNLIKELY (!ensure_capacity (vector, capacity))) { + if (DN_UNLIKELY (!vector_ensure_capacity (vector, capacity, true))) { dn_vector_dispose (vector); return false; } @@ -313,7 +294,7 @@ dn_vector_reserve ( uint32_t capacity) { DN_ASSERT (vector); - return ensure_capacity (vector, capacity); + return vector_ensure_capacity (vector, capacity, false); } uint32_t @@ -335,7 +316,7 @@ dn_vector_custom_resize ( return true; if (size > vector->_internal._capacity) - if (DN_UNLIKELY (!ensure_capacity (vector, size))) + if (DN_UNLIKELY (!vector_ensure_capacity (vector, size, false))) return false; if (size < vector->size) { diff --git a/src/native/containers/dn-vector.h b/src/native/containers/dn-vector.h index f08c5dbce94b00..462dc54867d69a 100644 --- a/src/native/containers/dn-vector.h +++ b/src/native/containers/dn-vector.h @@ -296,9 +296,6 @@ dn_vector_pop_back (dn_vector_t *vector) dn_vector_custom_pop_back (vector, NULL); } -#define dn_vector_buffer_capacity_t(buffer_byte_size, type) \ - _dn_vector_buffer_capacity ((buffer_byte_size), sizeof (type)) - void dn_vector_for_each ( const dn_vector_t *vector, diff --git a/src/native/eventpipe/ds-ipc.c b/src/native/eventpipe/ds-ipc.c index 5ba83d35f9302a..cfe1a2aa23425c 100644 --- a/src/native/eventpipe/ds-ipc.c +++ b/src/native/eventpipe/ds-ipc.c @@ -265,7 +265,7 @@ ds_ipc_stream_factory_configure (ds_ipc_error_callback_func callback) dn_vector_ptr_custom_alloc_params_t params = {0, }; params.allocator = (dn_allocator_t *)&allocator; - params.capacity = dn_vector_ptr_buffer_capacity (dn_vector_ptr_default_local_allocator_byte_size); + params.capacity = dn_vector_ptr_default_local_allocator_capacity_size; dn_vector_ptr_t *port_configs = dn_vector_ptr_custom_alloc (¶ms); dn_vector_ptr_t *port_config_parts = dn_vector_ptr_custom_alloc (¶ms); diff --git a/src/native/eventpipe/ep-buffer-manager.c b/src/native/eventpipe/ep-buffer-manager.c index 1c9a1ef460ba92..1d7fb46d00ff3e 100644 --- a/src/native/eventpipe/ep-buffer-manager.c +++ b/src/native/eventpipe/ep-buffer-manager.c @@ -596,7 +596,7 @@ buffer_manager_move_next_event_any_thread ( dn_vector_ptr_custom_init_params_t params = {0, }; params.allocator = (dn_allocator_t *)&allocator; - params.capacity = dn_vector_ptr_buffer_capacity (dn_vector_ptr_default_local_allocator_byte_size); + params.capacity = dn_vector_ptr_default_local_allocator_capacity_size; ep_raise_error_if_nok (dn_vector_ptr_custom_init (&buffer_array, ¶ms)); ep_raise_error_if_nok (dn_vector_ptr_custom_init (&buffer_list_array, ¶ms)); @@ -1061,7 +1061,7 @@ ep_buffer_manager_suspend_write_event ( dn_vector_ptr_custom_init_params_t params = {0, }; params.allocator = (dn_allocator_t *)&allocator; - params.capacity = dn_vector_ptr_buffer_capacity (dn_vector_ptr_default_local_allocator_byte_size); + params.capacity = dn_vector_ptr_default_local_allocator_capacity_size; dn_vector_ptr_t thread_vector; ep_raise_error_if_nok (dn_vector_ptr_custom_init (&thread_vector, ¶ms)); @@ -1205,7 +1205,7 @@ ep_buffer_manager_write_all_buffers_to_file_v4 ( dn_vector_ptr_custom_init_params_t params = {0, }; params.allocator = (dn_allocator_t *)&allocator; - params.capacity = dn_vector_ptr_buffer_capacity (dn_vector_ptr_default_local_allocator_byte_size); + params.capacity = dn_vector_ptr_default_local_allocator_capacity_size; dn_vector_ptr_t session_states_to_delete; ep_raise_error_if_nok (dn_vector_ptr_custom_init (&session_states_to_delete, ¶ms)); @@ -1383,7 +1383,7 @@ ep_buffer_manager_deallocate_buffers (EventPipeBufferManager *buffer_manager) dn_vector_ptr_custom_init_params_t params = {0, }; params.allocator = (dn_allocator_t *)&allocator; - params.capacity = dn_vector_ptr_buffer_capacity (dn_vector_ptr_default_local_allocator_byte_size); + params.capacity = dn_vector_ptr_default_local_allocator_capacity_size; dn_vector_ptr_t thread_session_states_to_remove; ep_raise_error_if_nok (dn_vector_ptr_custom_init (&thread_session_states_to_remove, ¶ms)); diff --git a/src/native/eventpipe/ep-session.c b/src/native/eventpipe/ep-session.c index e2f1227e819edd..58ae8df627753b 100644 --- a/src/native/eventpipe/ep-session.c +++ b/src/native/eventpipe/ep-session.c @@ -336,7 +336,7 @@ ep_session_suspend_write_event (EventPipeSession *session) dn_vector_ptr_custom_init_params_t params = {0, }; params.allocator = (dn_allocator_t *)&allocator; - params.capacity = dn_vector_ptr_buffer_capacity (dn_vector_ptr_default_local_allocator_byte_size); + params.capacity = dn_vector_ptr_default_local_allocator_capacity_size; dn_vector_ptr_t threads; From b9daae27131f99504310c84bfdb5e239a92882f1 Mon Sep 17 00:00:00 2001 From: lateralusX Date: Thu, 9 Mar 2023 18:45:40 +0100 Subject: [PATCH 08/10] Optimize dn_vector_ptr_t push/pop/erase_fast to not use memmove/memset. --- src/mono/mono/eventpipe/ep-rt-mono.h | 7 +- .../mono/eventpipe/test/dn-vector-ptr-tests.c | 197 ++++++++++++++++-- src/native/containers/dn-vector-priv.h | 6 + src/native/containers/dn-vector-t.h | 44 +++- src/native/containers/dn-vector.c | 24 +-- 5 files changed, 244 insertions(+), 34 deletions(-) diff --git a/src/mono/mono/eventpipe/ep-rt-mono.h b/src/mono/mono/eventpipe/ep-rt-mono.h index e72f3dff507d27..51c189d60ae6ed 100644 --- a/src/mono/mono/eventpipe/ep-rt-mono.h +++ b/src/mono/mono/eventpipe/ep-rt-mono.h @@ -1062,7 +1062,12 @@ inline uint8_t * ep_rt_valloc0 (size_t buffer_size) { - return (uint8_t *)mono_valloc (NULL, buffer_size, MONO_MMAP_READ | MONO_MMAP_WRITE, MONO_MEM_ACCOUNT_PROFILER); + uint8_t *buffer = (uint8_t *)mono_valloc (NULL, buffer_size, MONO_MMAP_READ | MONO_MMAP_WRITE, MONO_MEM_ACCOUNT_PROFILER); +#ifdef EP_CHECKED_BUILD + for (size_t i = 0; i < buffer_size; i++) + EP_ASSERT (buffer [i] == 0); +#endif + return buffer; } static diff --git a/src/mono/mono/eventpipe/test/dn-vector-ptr-tests.c b/src/mono/mono/eventpipe/test/dn-vector-ptr-tests.c index 1f4fcbcd3d12eb..613cada7d2d400 100644 --- a/src/mono/mono/eventpipe/test/dn-vector-ptr-tests.c +++ b/src/mono/mono/eventpipe/test/dn-vector-ptr-tests.c @@ -27,6 +27,18 @@ static const char *test_vector_ptr_items [] = { NULL }; +static void *test_vector_ptr_last_disposed_value = 0; +static int32_t test_vector_ptr_dispose_call_count = 0; + +static +void +DN_CALLBACK_CALLTYPE +test_vector_ptr_dispose_call_func(void *data) +{ + test_vector_ptr_last_disposed_value = *((void **)data); + test_vector_ptr_dispose_call_count++; +} + static int32_t test_vector_ptr_foreach_iterate_index = 0; static char *test_vector_ptr_foreach_iterate_error = NULL; @@ -91,10 +103,11 @@ test_vector_ptr_setup (void) static dn_vector_ptr_t * -vector_ptr_alloc_and_fill (uint32_t *item_count) +vector_ptr_alloc_and_fill (dn_vector_ptr_t *vector, uint32_t *item_count) { - dn_vector_ptr_t *vector = dn_vector_ptr_alloc (); int32_t i; + if (!vector) + vector = dn_vector_ptr_alloc (); for(i = 0; test_vector_ptr_items [i] != NULL; i++) { dn_vector_ptr_push_back (vector, (char *)test_vector_ptr_items [i]); @@ -121,7 +134,7 @@ test_vector_ptr_alloc (void) dn_vector_ptr_t *vector; uint32_t i; - vector = vector_ptr_alloc_and_fill (&i); + vector = vector_ptr_alloc_and_fill (NULL, &i); if (dn_vector_ptr_capacity (vector) != vector_ptr_guess_capacity (vector->size)) { return FAILED ("capacity should be %d, but it is %d", @@ -192,7 +205,7 @@ static RESULT test_vector_ptr_for_iterate (void) { - dn_vector_ptr_t *vector = vector_ptr_alloc_and_fill (NULL); + dn_vector_ptr_t *vector = vector_ptr_alloc_and_fill (NULL, NULL); uint32_t i = 0; DN_VECTOR_PTR_FOREACH_BEGIN (char *, item, vector) { @@ -213,7 +226,7 @@ static RESULT test_vector_ptr_foreach_iterate (void) { - dn_vector_ptr_t *vector = vector_ptr_alloc_and_fill (NULL); + dn_vector_ptr_t *vector = vector_ptr_alloc_and_fill (NULL, NULL); test_vector_ptr_foreach_iterate_index = 0; test_vector_ptr_foreach_iterate_error = NULL; @@ -284,12 +297,118 @@ test_vector_ptr_resize_2 (void) static RESULT -test_vector_ptr_erase (void) +test_vector_ptr_push_back (void) { - dn_vector_ptr_t *vector; - uint32_t i; + int32_t v; + dn_vector_ptr_t *vector = dn_vector_ptr_alloc (); + if (vector->size != 0) + return FAILED ("vector size didn't match"); + + v = 27; + + dn_vector_ptr_push_back (vector, INT32_TO_POINTER (v)); + + if (1 != vector->size) + return FAILED ("vector push_back failed"); + + if (v != POINTER_TO_INT32 (*dn_vector_ptr_index (vector, 0))) + return FAILED ("dn_vector_index failed"); + + dn_vector_ptr_free (vector); + + return OK; +} + +static +RESULT +test_vector_ptr_push_back_2 (void) +{ + dn_vector_ptr_t *vector = dn_vector_ptr_alloc (); + if (vector->size != 0) + return FAILED ("vector size didn't match"); + + for (int32_t i = 0; i < 10; ++i) + dn_vector_ptr_push_back (vector, INT32_TO_POINTER (i)); + + for (uint32_t i = 0; i < vector->size; ++i) { + if (i != POINTER_TO_INT32 (*dn_vector_ptr_index (vector, i))) + return FAILED ("vector push_back failed"); + } + + dn_vector_ptr_free (vector); + + return OK; +} + +static +RESULT +test_vector_ptr_pop_back (void) +{ + dn_vector_ptr_t *vector = dn_vector_ptr_alloc (); + if (vector->size != 0) + return FAILED ("vector size didn't match"); + + for (int32_t i = 0; i < 10; ++i) + dn_vector_ptr_push_back (vector, INT32_TO_POINTER (i)); + + if (POINTER_TO_INT32 (*dn_vector_ptr_back (vector)) != 9) + return FAILED ("vector back failed"); + + dn_vector_ptr_pop_back (vector); + + if (POINTER_TO_INT32 (*dn_vector_ptr_back (vector)) != 8) + return FAILED ("vector pop_back failed"); + + dn_vector_ptr_pop_back (vector); + + if (POINTER_TO_INT32 (*dn_vector_ptr_back (vector)) != 7) + return FAILED ("vector pop_back failed"); + + dn_vector_ptr_free (vector); + + return OK; +} + +static +RESULT +test_vector_ptr_pop_back_2 (void) +{ + dn_vector_ptr_t *vector = dn_vector_ptr_alloc (); + if (vector->size != 0) + return FAILED ("vector size didn't match"); + + for (int32_t i = 0; i < 10; ++i) + dn_vector_ptr_push_back (vector, INT32_TO_POINTER (i)); + + if (POINTER_TO_INT32 (*dn_vector_ptr_back (vector)) != 9) + return FAILED ("vector back failed"); + + test_vector_ptr_last_disposed_value = 0; + dn_vector_ptr_custom_pop_back (vector, test_vector_ptr_dispose_call_func); + if (POINTER_TO_INT32 (test_vector_ptr_last_disposed_value) != 9) + return FAILED ("vector custom_pop_back failed, wrong disposed value #1"); - vector = vector_ptr_alloc_and_fill (&i); + if (POINTER_TO_INT32 (*dn_vector_ptr_back (vector)) != 8) + return FAILED ("vector pop_back failed"); + + test_vector_ptr_last_disposed_value = 0; + dn_vector_ptr_custom_pop_back (vector, test_vector_ptr_dispose_call_func); + if (POINTER_TO_INT32 (test_vector_ptr_last_disposed_value) != 8) + return FAILED ("vector custom_pop_back failed, wrong disposed value #2"); + + if (POINTER_TO_INT32 (*dn_vector_ptr_back (vector)) != 7) + return FAILED ("vector pop_back failed"); + + dn_vector_ptr_free (vector); + + return OK; +} + +static +RESULT +test_vector_ptr_erase (void) +{ + dn_vector_ptr_t * vector = vector_ptr_alloc_and_fill (NULL, NULL); dn_vector_ptr_erase (dn_vector_ptr_begin (vector)); if (*dn_vector_ptr_index (vector, 0) != test_vector_ptr_items [1]) { @@ -313,10 +432,7 @@ static RESULT test_vector_ptr_erase_fast (void) { - dn_vector_ptr_t *vector; - uint32_t i; - - vector = vector_ptr_alloc_and_fill (&i); + dn_vector_ptr_t *vector = vector_ptr_alloc_and_fill (NULL, NULL); dn_vector_ptr_erase_fast (dn_vector_ptr_begin (vector)); if (*dn_vector_ptr_index (vector, 0) != test_vector_ptr_items [vector->size]) { @@ -335,12 +451,59 @@ test_vector_ptr_erase_fast (void) return OK; } +static +RESULT +test_vector_ptr_erase_fast_2 (void) +{ + dn_vector_ptr_t *vector = vector_ptr_alloc_and_fill (NULL, NULL); + + test_vector_ptr_last_disposed_value = NULL; + dn_vector_ptr_custom_erase_fast (dn_vector_ptr_it_next_n (dn_vector_ptr_begin (vector), 3), test_vector_ptr_dispose_call_func); + if (test_vector_ptr_last_disposed_value != test_vector_ptr_items [3]) + return FAILED ("custom erase failed to dispose correct value"); + + dn_vector_ptr_free (vector); + + return OK; +} + +static +RESULT +test_vector_ptr_erase_fast_3 (void) +{ + dn_vector_ptr_t vector; + dn_vector_ptr_init (&vector); + vector_ptr_alloc_and_fill (&vector, NULL); + + dn_vector_ptr_erase_fast (dn_vector_ptr_begin (&vector)); + + if (vector.data [dn_vector_ptr_size (&vector)] == NULL) + return FAILED ("erase initialized memory, but shouldn't."); + + dn_vector_ptr_dispose (&vector); + + dn_vector_ptr_custom_alloc_params_t params = {0, }; + params.attributes = DN_VECTOR_ATTRIBUTE_MEMORY_INIT; + + dn_vector_ptr_custom_init (&vector, ¶ms); + vector_ptr_alloc_and_fill (&vector, NULL); + + dn_vector_ptr_erase_fast (dn_vector_ptr_begin (&vector)); + + if (vector.data [dn_vector_ptr_size (&vector)] != NULL) + return FAILED ("erase didn't initialize memory, but should"); + + dn_vector_ptr_dispose (&vector); + + return OK; +} + static RESULT test_vector_ptr_capacity (void) { uint32_t size; - dn_vector_ptr_t *vector = vector_ptr_alloc_and_fill (&size); + dn_vector_ptr_t *vector = vector_ptr_alloc_and_fill (NULL, &size); if (dn_vector_ptr_capacity (vector) < size) return FAILED ("invalid vector capacity #1"); @@ -959,8 +1122,14 @@ static Test dn_vector_ptr_tests [] = { {"test_vector_ptr_foreach_iterate", test_vector_ptr_foreach_iterate}, {"test_vector_ptr_resize", test_vector_ptr_resize}, {"test_vector_ptr_resize_2", test_vector_ptr_resize_2}, + {"test_vector_ptr_push_back", test_vector_ptr_push_back}, + {"test_vector_ptr_push_back_2", test_vector_ptr_push_back_2}, + {"test_vector_ptr_pop_back", test_vector_ptr_pop_back}, + {"test_vector_ptr_pop_back_2", test_vector_ptr_pop_back_2}, {"test_vector_ptr_erase", test_vector_ptr_erase}, {"test_vector_ptr_erase_fast", test_vector_ptr_erase_fast}, + {"test_vector_ptr_erase_fast_2", test_vector_ptr_erase_fast_2}, + {"test_vector_ptr_erase_fast_3", test_vector_ptr_erase_fast_3}, {"test_vector_ptr_capacity", test_vector_ptr_capacity}, {"test_vector_ptr_custom_free", test_vector_ptr_custom_free}, {"test_vector_ptr_clear", test_vector_ptr_clear}, diff --git a/src/native/containers/dn-vector-priv.h b/src/native/containers/dn-vector-priv.h index 8165a3767ba63e..9b373aa08e5b98 100644 --- a/src/native/containers/dn-vector-priv.h +++ b/src/native/containers/dn-vector-priv.h @@ -8,6 +8,12 @@ #include "dn-allocator.h" #include "dn-vector-types.h" +bool +_dn_vector_ensure_capacity ( + dn_vector_t *vector, + uint32_t capacity, + bool calc_capacity); + bool _dn_vector_insert_range ( dn_vector_it_t *position, diff --git a/src/native/containers/dn-vector-t.h b/src/native/containers/dn-vector-t.h index 6305016e239589..2985ba2736abde 100644 --- a/src/native/containers/dn-vector-t.h +++ b/src/native/containers/dn-vector-t.h @@ -209,15 +209,30 @@ DN_DEFINE_VECTOR_T_SYMBOL_NAME(name, erase) (DN_DEFINE_VECTOR_IT_T_NAME(name) po static inline DN_DEFINE_VECTOR_RESULT_T_NAME(name) \ DN_DEFINE_VECTOR_T_SYMBOL_NAME(name, custom_erase_fast) (DN_DEFINE_VECTOR_IT_T_NAME(name) position, dn_vector_dispose_func_t dispose_func) \ { \ - DN_DEFINE_VECTOR_RESULT_T_NAME(name) result; \ - result.result = _dn_vector_erase_fast ((dn_vector_it_t *)&position, dispose_func); \ - result.it = position; \ + DN_ASSERT (!dn_vector_it_end (position)); \ + DN_DEFINE_VECTOR_T_NAME(name) *vector = position._internal._vector; \ + DN_ASSERT (vector && vector->size != 0); \ + vector->size --; \ + if (dispose_func) \ + dispose_func (vector->data + position.it); \ + vector->data [position.it] = vector->data [vector->size]; \ + if ((vector->_internal._attributes & (uint32_t)DN_VECTOR_ATTRIBUTE_MEMORY_INIT) == DN_VECTOR_ATTRIBUTE_MEMORY_INIT) \ + vector->data [vector->size] = 0; \ + DN_DEFINE_VECTOR_RESULT_T_NAME(name) result = { true, position }; \ return result; \ } \ static inline DN_DEFINE_VECTOR_RESULT_T_NAME(name) \ DN_DEFINE_VECTOR_T_SYMBOL_NAME(name, erase_fast) (DN_DEFINE_VECTOR_IT_T_NAME(name) position) \ { \ - return DN_DEFINE_VECTOR_T_SYMBOL_NAME(name, custom_erase_fast) (position, NULL); \ + DN_ASSERT (!dn_vector_it_end (position)); \ + DN_DEFINE_VECTOR_T_NAME(name) *vector = position._internal._vector; \ + DN_ASSERT (vector && vector->size != 0); \ + vector->size --; \ + vector->data [position.it] = vector->data [vector->size]; \ + if ((vector->_internal._attributes & (uint32_t)DN_VECTOR_ATTRIBUTE_MEMORY_INIT) == DN_VECTOR_ATTRIBUTE_MEMORY_INIT) \ + vector->data [vector->size] = 0; \ + DN_DEFINE_VECTOR_RESULT_T_NAME(name) result = { true, position }; \ + return result; \ } \ static inline bool \ DN_DEFINE_VECTOR_T_SYMBOL_NAME(name, custom_resize) (DN_DEFINE_VECTOR_T_NAME(name) *vector, uint32_t size, dn_vector_dispose_func_t dispose_func) \ @@ -243,17 +258,32 @@ static inline bool \ DN_DEFINE_VECTOR_T_SYMBOL_NAME(name, push_back) (DN_DEFINE_VECTOR_T_NAME(name) *vector, type element) \ { \ DN_ASSERT (vector); \ - return dn_vector_push_back ((dn_vector_t *)vector, element); \ + uint64_t new_capacity = (uint64_t)vector->size + (uint64_t)1; \ + if (DN_UNLIKELY (new_capacity > (uint64_t)(vector->_internal._capacity))) { \ + if (DN_UNLIKELY (!_dn_vector_ensure_capacity ((dn_vector_t *)vector, (uint32_t)new_capacity, true))) \ + return false; \ + } \ + vector->data [vector->size] = element; \ + vector->size ++; \ + return true; \ } \ static inline void \ DN_DEFINE_VECTOR_T_SYMBOL_NAME(name, custom_pop_back) (DN_DEFINE_VECTOR_T_NAME(name) *vector, dn_vector_dispose_func_t dispose_func) \ { \ - dn_vector_custom_pop_back ((dn_vector_t*)vector, dispose_func); \ + DN_ASSERT (vector && vector->size != 0); \ + vector->size--; \ + if (dispose_func) \ + dispose_func (vector->data + vector->size); \ + if (((vector->_internal._attributes & (uint32_t)DN_VECTOR_ATTRIBUTE_MEMORY_INIT) == DN_VECTOR_ATTRIBUTE_MEMORY_INIT)) \ + vector->data [vector->size] = 0; \ } \ static inline void \ DN_DEFINE_VECTOR_T_SYMBOL_NAME(name, pop_back) (DN_DEFINE_VECTOR_T_NAME(name) *vector) \ { \ - dn_vector_pop_back ((dn_vector_t*)vector); \ + DN_ASSERT (vector && vector->size != 0); \ + vector->size --; \ + if (((vector->_internal._attributes & (uint32_t)DN_VECTOR_ATTRIBUTE_MEMORY_INIT) == DN_VECTOR_ATTRIBUTE_MEMORY_INIT)) \ + vector->data [vector->size] = 0; \ } \ static inline void \ DN_DEFINE_VECTOR_T_SYMBOL_NAME(name, for_each) (const DN_DEFINE_VECTOR_T_NAME(name) *vector, dn_vector_for_each_func_t for_each_func, void *user_data) \ diff --git a/src/native/containers/dn-vector.c b/src/native/containers/dn-vector.c index 4dca0c6e38ac7c..a70eda7bdb901b 100644 --- a/src/native/containers/dn-vector.c +++ b/src/native/containers/dn-vector.c @@ -36,16 +36,16 @@ #define check_attribute(vector, value) ((vector->_internal._attributes & (uint32_t)value) == value) -static bool -vector_ensure_capacity ( +bool +_dn_vector_ensure_capacity ( dn_vector_t *vector, uint32_t capacity, - bool init) + bool calc_capacity) { if (capacity != 0 && capacity <= (uint64_t)(vector->_internal._capacity)) return true; - uint64_t new_capacity = init ? capacity : CALC_NEW_CAPACITY (capacity); + uint64_t new_capacity = calc_capacity ? CALC_NEW_CAPACITY (capacity) : capacity; if (DN_UNLIKELY (new_capacity > (uint64_t)(UINT32_MAX))) return false; @@ -86,7 +86,7 @@ _dn_vector_insert_range ( uint64_t new_capacity = (uint64_t)vector->size + (uint64_t)element_count; if (DN_UNLIKELY (new_capacity > (uint64_t)(vector->_internal._capacity))) { - if (DN_UNLIKELY (!vector_ensure_capacity (vector, (uint32_t)new_capacity, false))) + if (DN_UNLIKELY (!_dn_vector_ensure_capacity (vector, (uint32_t)new_capacity, true))) return false; } @@ -124,7 +124,7 @@ _dn_vector_append_range ( uint64_t new_capacity = (uint64_t)vector->size + (uint64_t)element_count; if (DN_UNLIKELY (new_capacity > (uint64_t)(vector->_internal._capacity))) { - if (DN_UNLIKELY (!vector_ensure_capacity (vector, (uint32_t)new_capacity, false))) + if (DN_UNLIKELY (!_dn_vector_ensure_capacity (vector, (uint32_t)new_capacity, true))) return false; } @@ -183,12 +183,12 @@ _dn_vector_erase_fast ( if (dispose_func) dispose_func (element_offset (vector, position->it)); + vector->size --; + /* element_offset won't overflow since position is smaller than current capacity */ /* element_offset won't overflow since vector->size - 1 is smaller than current capacity */ /* vector->size - 1 won't underflow since vector->size > 0 */ - memmove (element_offset (vector, position->it), element_offset (vector, vector->size - 1), element_length (vector, 1)); - - vector->size --; + memmove (element_offset (vector, position->it), element_offset (vector, vector->size), element_length (vector, 1)); if (check_attribute (vector, DN_VECTOR_ATTRIBUTE_MEMORY_INIT)) memset (element_offset(vector, vector->size), 0, element_length (vector, 1)); @@ -255,7 +255,7 @@ dn_vector_custom_init ( capacity = params->capacity; } - if (DN_UNLIKELY (!vector_ensure_capacity (vector, capacity, true))) { + if (DN_UNLIKELY (!_dn_vector_ensure_capacity (vector, capacity, false))) { dn_vector_dispose (vector); return false; } @@ -294,7 +294,7 @@ dn_vector_reserve ( uint32_t capacity) { DN_ASSERT (vector); - return vector_ensure_capacity (vector, capacity, false); + return _dn_vector_ensure_capacity (vector, capacity, true); } uint32_t @@ -316,7 +316,7 @@ dn_vector_custom_resize ( return true; if (size > vector->_internal._capacity) - if (DN_UNLIKELY (!vector_ensure_capacity (vector, size, false))) + if (DN_UNLIKELY (!_dn_vector_ensure_capacity (vector, size, true))) return false; if (size < vector->size) { From 24959eb970e46fbf94df50e3280531c4a99b014c Mon Sep 17 00:00:00 2001 From: lateralusX Date: Fri, 10 Mar 2023 10:02:37 +0100 Subject: [PATCH 09/10] Fix build error in EventPipe native tests. --- .../mono/eventpipe/test/ep-provider-callback-dataqueue-tests.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mono/mono/eventpipe/test/ep-provider-callback-dataqueue-tests.c b/src/mono/mono/eventpipe/test/ep-provider-callback-dataqueue-tests.c index 32acf62243719a..1b4597e3674321 100644 --- a/src/mono/mono/eventpipe/test/ep-provider-callback-dataqueue-tests.c +++ b/src/mono/mono/eventpipe/test/ep-provider-callback-dataqueue-tests.c @@ -55,7 +55,8 @@ test_provider_callback_data_queue (void) NULL, 1, EP_EVENT_LEVEL_LOGALWAYS, - true); + true, + 0); ep_provider_callback_data_queue_enqueue (provider_callback_data_queue, provider_enqueue_callback_data); ep_provider_callback_data_fini (provider_enqueue_callback_data); } From 0ea33beae1d22d1273b001555fc42d68dc51da8d Mon Sep 17 00:00:00 2001 From: lateralusX Date: Fri, 10 Mar 2023 12:54:00 +0100 Subject: [PATCH 10/10] Fix debug/checked build. --- src/native/containers/dn-vector-t.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/native/containers/dn-vector-t.h b/src/native/containers/dn-vector-t.h index 2985ba2736abde..375e15d0b131ff 100644 --- a/src/native/containers/dn-vector-t.h +++ b/src/native/containers/dn-vector-t.h @@ -209,9 +209,9 @@ DN_DEFINE_VECTOR_T_SYMBOL_NAME(name, erase) (DN_DEFINE_VECTOR_IT_T_NAME(name) po static inline DN_DEFINE_VECTOR_RESULT_T_NAME(name) \ DN_DEFINE_VECTOR_T_SYMBOL_NAME(name, custom_erase_fast) (DN_DEFINE_VECTOR_IT_T_NAME(name) position, dn_vector_dispose_func_t dispose_func) \ { \ - DN_ASSERT (!dn_vector_it_end (position)); \ DN_DEFINE_VECTOR_T_NAME(name) *vector = position._internal._vector; \ DN_ASSERT (vector && vector->size != 0); \ + DN_ASSERT (position.it != position._internal._vector->size); \ vector->size --; \ if (dispose_func) \ dispose_func (vector->data + position.it); \ @@ -224,9 +224,9 @@ DN_DEFINE_VECTOR_T_SYMBOL_NAME(name, custom_erase_fast) (DN_DEFINE_VECTOR_IT_T_N static inline DN_DEFINE_VECTOR_RESULT_T_NAME(name) \ DN_DEFINE_VECTOR_T_SYMBOL_NAME(name, erase_fast) (DN_DEFINE_VECTOR_IT_T_NAME(name) position) \ { \ - DN_ASSERT (!dn_vector_it_end (position)); \ DN_DEFINE_VECTOR_T_NAME(name) *vector = position._internal._vector; \ DN_ASSERT (vector && vector->size != 0); \ + DN_ASSERT (position.it != position._internal._vector->size); \ vector->size --; \ vector->data [position.it] = vector->data [vector->size]; \ if ((vector->_internal._attributes & (uint32_t)DN_VECTOR_ATTRIBUTE_MEMORY_INIT) == DN_VECTOR_ATTRIBUTE_MEMORY_INIT) \