From fef1ce084af6dc3a0051025c12e04a1eaa5eb1b0 Mon Sep 17 00:00:00 2001 From: Ivan Maidanski Date: Wed, 26 Apr 2023 09:27:50 +0300 Subject: New API for more optimal usage of GC_calloc_explicitly_typed If the client needs to allocate many typed object arrays of same layout and amount of elements, then "calloc" descriptor could be created once (by GC_calloc_prepare_explicitly_typed) followed by multiple allocations (by GC_calloc_do_explicitly_typed) referring to the same descriptor. * include/gc/gc_typed.h (GC_CALLOC_TYPED_DESCR_WORDS): New macro. * include/gc/gc_typed.h (GC_calloc_typed_descr_s): New struct type. * include/gc/gc_typed.h (GC_calloc_prepare_explicitly_typed, GC_calloc_do_explicitly_typed): New function declaration. * tests/gctest.c [!NO_TYPED_TEST && !GC_DEBUG] (typed_test): Define ctd_l local variable; call GC_calloc_prepare_explicitly_typed() before loop; call GC_calloc_do_explicitly_typed() instead of GC_CALLOC_EXPLICITLY_TYPED(1001). * typd_mlc.c (GC_calloc_typed_descr_s.alloc_lb): Change type from size_t to word. * typd_mlc.c (GC_calloc_typed_descr_s.descr_type): Change type from int to signed_word. * typd_mlc.c (GC_calloc_prepare_explicitly_typed, GC_calloc_do_explicitly_typed): Change from STATIC to GC_API; add ctd_sz argument; check ctd_sz in assertion; add casts for alloc_lb field. * typd_mlc.c (GC_calloc_prepare_explicitly_typed): Add static assertion about size of GC_calloc_typed_descr_s and GC_CALLOC_TYPED_DESCR_WORDS; change return type from void to it. * typd_mlc.c (GC_calloc_explicitly_typed): Pass sizeof(ctd) to GC_calloc_prepare_explicitly_typed(), GC_calloc_do_explicitly_typed(). --- tests/gctest.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'tests') diff --git a/tests/gctest.c b/tests/gctest.c index 9c5fe9d2..126f5c1c 100644 --- a/tests/gctest.c +++ b/tests/gctest.c @@ -1331,6 +1331,9 @@ void typed_test(void) GC_descr d4 = GC_make_descriptor(bm_huge, 320); GC_word * x = (GC_word *)GC_MALLOC_EXPLICITLY_TYPED( 320 * sizeof(GC_word) + 123, d4); +# ifndef GC_DEBUG + struct GC_calloc_typed_descr_s ctd_l; +# endif int i; AO_fetch_and_add1(&collectable_count); @@ -1345,6 +1348,13 @@ void typed_test(void) d1 = GC_make_descriptor(bm3, 2); GC_set_bit(bm2, 1); d2 = GC_make_descriptor(bm2, 2); +# ifndef GC_DEBUG + if (GC_calloc_prepare_explicitly_typed(&ctd_l, sizeof(ctd_l), 1001, + 3 * sizeof(GC_word), d2) != 1) { + GC_printf("Out of memory in calloc typed prepare\n"); + exit(1); + } +# endif old = 0; for (i = 0; i < 4000; i++) { if ((i & 0xff) != 0) { @@ -1386,9 +1396,12 @@ void typed_test(void) newP = (GC_word *)GC_CALLOC_EXPLICITLY_TYPED(7, 3 * sizeof(GC_word), d2); } else { - newP = (GC_word *)GC_CALLOC_EXPLICITLY_TYPED(1001, - 3 * sizeof(GC_word), - d2); +# ifdef GC_DEBUG + newP = (GC_word *)GC_CALLOC_EXPLICITLY_TYPED(1001, + 3 * sizeof(GC_word), d2); +# else + newP = GC_calloc_do_explicitly_typed(&ctd_l, sizeof(ctd_l)); +# endif if (newP != NULL && (newP[0] != 0 || newP[1] != 0)) { GC_printf("Bad initialization by GC_calloc_explicitly_typed\n"); FAIL; -- cgit v1.2.1