From cc0069bf2b0b3d40dda462d441af5d8b07ef1f57 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Mon, 31 Oct 2022 09:17:57 +0100 Subject: [PATCH v2] Add repalloc0 and repalloc0_array These zero out the space added by repalloc. This is a common pattern that is quite hairy to code by hand. Discussion: https://www.postgresql.org/message-id/b66dfc89-9365-cb57-4e1f-b7d31813eeec@enterprisedb.com --- src/backend/executor/nodeHash.c | 8 ++----- src/backend/libpq/be-fsstubs.c | 9 +++----- src/backend/optimizer/util/placeholder.c | 13 ++++------- src/backend/optimizer/util/relnode.c | 29 +++++++----------------- src/backend/parser/parse_param.c | 10 +++----- src/backend/storage/lmgr/lwlock.c | 9 ++------ src/backend/utils/adt/ruleutils.c | 9 ++------ src/backend/utils/cache/typcache.c | 10 ++------ src/backend/utils/mmgr/mcxt.c | 18 +++++++++++++++ src/include/utils/palloc.h | 2 ++ 10 files changed, 46 insertions(+), 71 deletions(-) diff --git a/src/backend/executor/nodeHash.c b/src/backend/executor/nodeHash.c index 6622b202c229..2e6cce4802e5 100644 --- a/src/backend/executor/nodeHash.c +++ b/src/backend/executor/nodeHash.c @@ -940,12 +940,8 @@ ExecHashIncreaseNumBatches(HashJoinTable hashtable) else { /* enlarge arrays and zero out added entries */ - hashtable->innerBatchFile = repalloc_array(hashtable->innerBatchFile, BufFile *, nbatch); - hashtable->outerBatchFile = repalloc_array(hashtable->outerBatchFile, BufFile *, nbatch); - MemSet(hashtable->innerBatchFile + oldnbatch, 0, - (nbatch - oldnbatch) * sizeof(BufFile *)); - MemSet(hashtable->outerBatchFile + oldnbatch, 0, - (nbatch - oldnbatch) * sizeof(BufFile *)); + hashtable->innerBatchFile = repalloc0_array(hashtable->innerBatchFile, BufFile *, oldnbatch, nbatch); + hashtable->outerBatchFile = repalloc0_array(hashtable->outerBatchFile, BufFile *, oldnbatch, nbatch); } MemoryContextSwitchTo(oldcxt); diff --git a/src/backend/libpq/be-fsstubs.c b/src/backend/libpq/be-fsstubs.c index 3e5cada7eb53..106fdcdf817b 100644 --- a/src/backend/libpq/be-fsstubs.c +++ b/src/backend/libpq/be-fsstubs.c @@ -696,19 +696,16 @@ newLOfd(void) newsize = 64; cookies = (LargeObjectDesc **) MemoryContextAllocZero(fscxt, newsize * sizeof(LargeObjectDesc *)); - cookies_size = newsize; } else { /* Double size of array */ i = cookies_size; newsize = cookies_size * 2; - cookies = (LargeObjectDesc **) - repalloc(cookies, newsize * sizeof(LargeObjectDesc *)); - MemSet(cookies + cookies_size, 0, - (newsize - cookies_size) * sizeof(LargeObjectDesc *)); - cookies_size = newsize; + cookies = + repalloc0_array(cookies, LargeObjectDesc *, cookies_size, newsize); } + cookies_size = newsize; return i; } diff --git a/src/backend/optimizer/util/placeholder.c b/src/backend/optimizer/util/placeholder.c index c7bfa293c9ff..c55027377fe7 100644 --- a/src/backend/optimizer/util/placeholder.c +++ b/src/backend/optimizer/util/placeholder.c @@ -133,16 +133,11 @@ find_placeholder_info(PlannerInfo *root, PlaceHolderVar *phv) while (phinfo->phid >= new_size) new_size *= 2; if (root->placeholder_array) - { - root->placeholder_array = (PlaceHolderInfo **) - repalloc(root->placeholder_array, - sizeof(PlaceHolderInfo *) * new_size); - MemSet(root->placeholder_array + root->placeholder_array_size, 0, - sizeof(PlaceHolderInfo *) * (new_size - root->placeholder_array_size)); - } + root->placeholder_array = + repalloc0_array(root->placeholder_array, PlaceHolderInfo *, root->placeholder_array_size, new_size); else - root->placeholder_array = (PlaceHolderInfo **) - palloc0(new_size * sizeof(PlaceHolderInfo *)); + root->placeholder_array = + palloc0_array(PlaceHolderInfo *, new_size); root->placeholder_array_size = new_size; } root->placeholder_array[phinfo->phid] = phinfo; diff --git a/src/backend/optimizer/util/relnode.c b/src/backend/optimizer/util/relnode.c index 1786a3daddc8..d7b4434e7f4a 100644 --- a/src/backend/optimizer/util/relnode.c +++ b/src/backend/optimizer/util/relnode.c @@ -157,31 +157,18 @@ expand_planner_arrays(PlannerInfo *root, int add_size) new_size = root->simple_rel_array_size + add_size; - root->simple_rel_array = (RelOptInfo **) - repalloc(root->simple_rel_array, - sizeof(RelOptInfo *) * new_size); - MemSet(root->simple_rel_array + root->simple_rel_array_size, - 0, sizeof(RelOptInfo *) * add_size); + root->simple_rel_array = + repalloc0_array(root->simple_rel_array, RelOptInfo *, root->simple_rel_array_size, new_size); - root->simple_rte_array = (RangeTblEntry **) - repalloc(root->simple_rte_array, - sizeof(RangeTblEntry *) * new_size); - MemSet(root->simple_rte_array + root->simple_rel_array_size, - 0, sizeof(RangeTblEntry *) * add_size); + root->simple_rte_array = + repalloc0_array(root->simple_rte_array, RangeTblEntry *, root->simple_rel_array_size, new_size); if (root->append_rel_array) - { - root->append_rel_array = (AppendRelInfo **) - repalloc(root->append_rel_array, - sizeof(AppendRelInfo *) * new_size); - MemSet(root->append_rel_array + root->simple_rel_array_size, - 0, sizeof(AppendRelInfo *) * add_size); - } + root->append_rel_array = + repalloc0_array(root->append_rel_array, AppendRelInfo *, root->simple_rel_array_size, new_size); else - { - root->append_rel_array = (AppendRelInfo **) - palloc0(sizeof(AppendRelInfo *) * new_size); - } + root->append_rel_array = + palloc0_array(AppendRelInfo *, new_size); root->simple_rel_array_size = new_size; } diff --git a/src/backend/parser/parse_param.c b/src/backend/parser/parse_param.c index f668abfcb336..e80876aa25e0 100644 --- a/src/backend/parser/parse_param.c +++ b/src/backend/parser/parse_param.c @@ -145,14 +145,10 @@ variable_paramref_hook(ParseState *pstate, ParamRef *pref) { /* Need to enlarge param array */ if (*parstate->paramTypes) - *parstate->paramTypes = (Oid *) repalloc(*parstate->paramTypes, - paramno * sizeof(Oid)); + *parstate->paramTypes = repalloc0_array(*parstate->paramTypes, Oid, + *parstate->numParams, paramno); else - *parstate->paramTypes = (Oid *) palloc(paramno * sizeof(Oid)); - /* Zero out the previously-unreferenced slots */ - MemSet(*parstate->paramTypes + *parstate->numParams, - 0, - (paramno - *parstate->numParams) * sizeof(Oid)); + *parstate->paramTypes = palloc0_array(Oid, paramno); *parstate->numParams = paramno; } diff --git a/src/backend/storage/lmgr/lwlock.c b/src/backend/storage/lmgr/lwlock.c index 0fc0cf6ebbd9..532cd67f4e3c 100644 --- a/src/backend/storage/lmgr/lwlock.c +++ b/src/backend/storage/lmgr/lwlock.c @@ -668,13 +668,8 @@ LWLockRegisterTranche(int tranche_id, const char *tranche_name) MemoryContextAllocZero(TopMemoryContext, newalloc * sizeof(char *)); else - { - LWLockTrancheNames = (const char **) - repalloc(LWLockTrancheNames, newalloc * sizeof(char *)); - memset(LWLockTrancheNames + LWLockTrancheNamesAllocated, - 0, - (newalloc - LWLockTrancheNamesAllocated) * sizeof(char *)); - } + LWLockTrancheNames = + repalloc0_array(LWLockTrancheNames, const char *, LWLockTrancheNamesAllocated, newalloc); LWLockTrancheNamesAllocated = newalloc; } diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 70d723e80cac..c5a49d0be342 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -4855,14 +4855,9 @@ expand_colnames_array_to(deparse_columns *colinfo, int n) if (n > colinfo->num_cols) { if (colinfo->colnames == NULL) - colinfo->colnames = (char **) palloc0(n * sizeof(char *)); + colinfo->colnames = palloc0_array(char *, n); else - { - colinfo->colnames = (char **) repalloc(colinfo->colnames, - n * sizeof(char *)); - memset(colinfo->colnames + colinfo->num_cols, 0, - (n - colinfo->num_cols) * sizeof(char *)); - } + colinfo->colnames = repalloc0_array(colinfo->colnames, char *, colinfo->num_cols, n); colinfo->num_cols = n; } } diff --git a/src/backend/utils/cache/typcache.c b/src/backend/utils/cache/typcache.c index 808f9ebd0d2f..b69366fa29de 100644 --- a/src/backend/utils/cache/typcache.c +++ b/src/backend/utils/cache/typcache.c @@ -1714,14 +1714,8 @@ ensure_record_cache_typmod_slot_exists(int32 typmod) { int32 newlen = pg_nextpower2_32(typmod + 1); - RecordCacheArray = (TupleDesc *) repalloc(RecordCacheArray, - newlen * sizeof(TupleDesc)); - memset(RecordCacheArray + RecordCacheArrayLen, 0, - (newlen - RecordCacheArrayLen) * sizeof(TupleDesc)); - RecordIdentifierArray = (uint64 *) repalloc(RecordIdentifierArray, - newlen * sizeof(uint64)); - memset(RecordIdentifierArray + RecordCacheArrayLen, 0, - (newlen - RecordCacheArrayLen) * sizeof(uint64)); + RecordCacheArray = repalloc0_array(RecordCacheArray, TupleDesc, RecordCacheArrayLen, newlen); + RecordIdentifierArray = repalloc0_array(RecordIdentifierArray, uint64, RecordCacheArrayLen, newlen); RecordCacheArrayLen = newlen; } } diff --git a/src/backend/utils/mmgr/mcxt.c b/src/backend/utils/mmgr/mcxt.c index f526ca82c15d..9595a148d1ba 100644 --- a/src/backend/utils/mmgr/mcxt.c +++ b/src/backend/utils/mmgr/mcxt.c @@ -1395,6 +1395,24 @@ repalloc_extended(void *pointer, Size size, int flags) return ret; } +/* + * repalloc0 + * Adjust the size of a previously allocated chunk and zero out the added + * space. + */ +void * +repalloc0(void *pointer, Size oldsize, Size size) +{ + void *ret; + + /* catch wrong argument order */ + Assert(size >= oldsize); + + ret = repalloc(pointer, size); + memset((char *) ret + oldsize, 0, (size - oldsize)); + return ret; +} + /* * MemoryContextAllocHuge * Allocate (possibly-expansive) space within the specified context. diff --git a/src/include/utils/palloc.h b/src/include/utils/palloc.h index 8eee0e293857..72d4e70dc649 100644 --- a/src/include/utils/palloc.h +++ b/src/include/utils/palloc.h @@ -80,6 +80,7 @@ extern void *palloc_extended(Size size, int flags); extern pg_nodiscard void *repalloc(void *pointer, Size size); extern pg_nodiscard void *repalloc_extended(void *pointer, Size size, int flags); +extern pg_nodiscard void *repalloc0(void *pointer, Size oldsize, Size size); extern void pfree(void *pointer); /* @@ -103,6 +104,7 @@ extern void pfree(void *pointer); * objects of type "type" */ #define repalloc_array(pointer, type, count) ((type *) repalloc(pointer, sizeof(type) * (count))) +#define repalloc0_array(pointer, type, oldcount, count) ((type *) repalloc0(pointer, sizeof(type) * (oldcount), sizeof(type) * (count))) /* * The result of palloc() is always word-aligned, so we can skip testing -- 2.37.3