Skip to content

Commit 7d58f23

Browse files
committed
REALLOCATE_BITMAPSETS manual compile-time option
This option forces each bitmapset modification to reallocate bitmapset. This is useful for debugging hangling pointers to bitmapset's. Discussion: https://postgr.es/m/CAMbWs4_wJthNtYBL%2BSsebpgF-5L2r5zFFk6xYbS0A78GKOTFHw%40mail.gmail.com Reviewed-by: Richard Guo, Andres Freund, Ashutosh Bapat, Andrei Lepikhov
1 parent 71a3e8c commit 7d58f23

File tree

2 files changed

+83
-0
lines changed

2 files changed

+83
-0
lines changed

src/backend/nodes/bitmapset.c

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,7 @@ bms_intersect(const Bitmapset *a, const Bitmapset *b)
263263
/* Handle cases where either input is NULL */
264264
if (a == NULL || b == NULL)
265265
return NULL;
266+
266267
/* Identify shorter and longer input; copy the shorter one */
267268
if (a->nwords <= b->nwords)
268269
{
@@ -798,8 +799,15 @@ bms_add_member(Bitmapset *a, int x)
798799
{
799800
int oldnwords = a->nwords;
800801
int i;
802+
#ifdef REALLOCATE_BITMAPSETS
803+
Bitmapset *tmp = a;
801804

805+
a = (Bitmapset *) palloc(BITMAPSET_SIZE(wordnum + 1));
806+
memcpy(a, tmp, BITMAPSET_SIZE(tmp->nwords));
807+
pfree(tmp);
808+
#else
802809
a = (Bitmapset *) repalloc(a, BITMAPSET_SIZE(wordnum + 1));
810+
#endif
803811
a->nwords = wordnum + 1;
804812
/* zero out the enlarged portion */
805813
i = oldnwords;
@@ -808,6 +816,16 @@ bms_add_member(Bitmapset *a, int x)
808816
a->words[i] = 0;
809817
} while (++i < a->nwords);
810818
}
819+
#ifdef REALLOCATE_BITMAPSETS
820+
else
821+
{
822+
Bitmapset *tmp = a;
823+
824+
a = (Bitmapset *) palloc(BITMAPSET_SIZE(tmp->nwords));
825+
memcpy(a, tmp, BITMAPSET_SIZE(tmp->nwords));
826+
pfree(tmp);
827+
}
828+
#endif
811829

812830
a->words[wordnum] |= ((bitmapword) 1 << bitnum);
813831
return a;
@@ -825,6 +843,9 @@ bms_del_member(Bitmapset *a, int x)
825843
{
826844
int wordnum,
827845
bitnum;
846+
#ifdef REALLOCATE_BITMAPSETS
847+
Bitmapset *tmp = a;
848+
#endif
828849

829850
if (x < 0)
830851
elog(ERROR, "negative bitmapset member not allowed");
@@ -836,6 +857,12 @@ bms_del_member(Bitmapset *a, int x)
836857
wordnum = WORDNUM(x);
837858
bitnum = BITNUM(x);
838859

860+
#ifdef REALLOCATE_BITMAPSETS
861+
a = (Bitmapset *) palloc(BITMAPSET_SIZE(tmp->nwords));
862+
memcpy(a, tmp, BITMAPSET_SIZE(tmp->nwords));
863+
pfree(tmp);
864+
#endif
865+
839866
/* member can't exist. Return 'a' unmodified */
840867
if (unlikely(wordnum >= a->nwords))
841868
return a;
@@ -889,6 +916,13 @@ bms_add_members(Bitmapset *a, const Bitmapset *b)
889916
}
890917
else
891918
{
919+
#ifdef REALLOCATE_BITMAPSETS
920+
Bitmapset *tmp = a;
921+
922+
a = (Bitmapset *) palloc(BITMAPSET_SIZE(tmp->nwords));
923+
memcpy(a, tmp, BITMAPSET_SIZE(tmp->nwords));
924+
pfree(tmp);
925+
#endif
892926
result = a;
893927
other = b;
894928
}
@@ -941,9 +975,16 @@ bms_add_range(Bitmapset *a, int lower, int upper)
941975
{
942976
int oldnwords = a->nwords;
943977
int i;
978+
#ifdef REALLOCATE_BITMAPSETS
979+
Bitmapset *tmp = a;
944980

981+
a = (Bitmapset *) palloc(BITMAPSET_SIZE(uwordnum + 1));
982+
memcpy(a, tmp, BITMAPSET_SIZE(tmp->nwords));
983+
pfree(tmp);
984+
#else
945985
/* ensure we have enough words to store the upper bit */
946986
a = (Bitmapset *) repalloc(a, BITMAPSET_SIZE(uwordnum + 1));
987+
#endif
947988
a->nwords = uwordnum + 1;
948989
/* zero out the enlarged portion */
949990
i = oldnwords;
@@ -992,6 +1033,12 @@ bms_int_members(Bitmapset *a, const Bitmapset *b)
9921033
int lastnonzero;
9931034
int shortlen;
9941035
int i;
1036+
#ifdef REALLOCATE_BITMAPSETS
1037+
Bitmapset *tmp = a;
1038+
#endif
1039+
1040+
Assert(a == NULL || IsA(a, Bitmapset));
1041+
Assert(b == NULL || IsA(b, Bitmapset));
9951042

9961043
Assert(a == NULL || IsA(a, Bitmapset));
9971044
Assert(b == NULL || IsA(b, Bitmapset));
@@ -1004,6 +1051,13 @@ bms_int_members(Bitmapset *a, const Bitmapset *b)
10041051
pfree(a);
10051052
return NULL;
10061053
}
1054+
1055+
#ifdef REALLOCATE_BITMAPSETS
1056+
a = (Bitmapset *) palloc(BITMAPSET_SIZE(tmp->nwords));
1057+
memcpy(a, tmp, BITMAPSET_SIZE(tmp->nwords));
1058+
pfree(tmp);
1059+
#endif
1060+
10071061
/* Intersect b into a; we need never copy */
10081062
shortlen = Min(a->nwords, b->nwords);
10091063
lastnonzero = -1;
@@ -1035,6 +1089,9 @@ Bitmapset *
10351089
bms_del_members(Bitmapset *a, const Bitmapset *b)
10361090
{
10371091
int i;
1092+
#ifdef REALLOCATE_BITMAPSETS
1093+
Bitmapset *tmp = a;
1094+
#endif
10381095

10391096
Assert(a == NULL || (IsA(a, Bitmapset) && a->words[a->nwords - 1] != 0));
10401097
Assert(b == NULL || (IsA(b, Bitmapset) && b->words[b->nwords - 1] != 0));
@@ -1044,6 +1101,13 @@ bms_del_members(Bitmapset *a, const Bitmapset *b)
10441101
return NULL;
10451102
if (b == NULL)
10461103
return a;
1104+
1105+
#ifdef REALLOCATE_BITMAPSETS
1106+
a = (Bitmapset *) palloc(BITMAPSET_SIZE(tmp->nwords));
1107+
memcpy(a, tmp, BITMAPSET_SIZE(tmp->nwords));
1108+
pfree(tmp);
1109+
#endif
1110+
10471111
/* Remove b's bits from a; we need never copy */
10481112
if (a->nwords > b->nwords)
10491113
{
@@ -1096,6 +1160,12 @@ bms_join(Bitmapset *a, Bitmapset *b)
10961160
Bitmapset *other;
10971161
int otherlen;
10981162
int i;
1163+
#ifdef REALLOCATE_BITMAPSETS
1164+
Bitmapset *tmp = a;
1165+
#endif
1166+
1167+
Assert(a == NULL || IsA(a, Bitmapset));
1168+
Assert(b == NULL || IsA(b, Bitmapset));
10991169

11001170
Assert(a == NULL || IsA(a, Bitmapset));
11011171
Assert(b == NULL || IsA(b, Bitmapset));
@@ -1105,6 +1175,13 @@ bms_join(Bitmapset *a, Bitmapset *b)
11051175
return b;
11061176
if (b == NULL)
11071177
return a;
1178+
1179+
#ifdef REALLOCATE_BITMAPSETS
1180+
a = (Bitmapset *) palloc(BITMAPSET_SIZE(tmp->nwords));
1181+
memcpy(a, tmp, BITMAPSET_SIZE(tmp->nwords));
1182+
pfree(tmp);
1183+
#endif
1184+
11081185
/* Identify shorter and longer input; use longer one as result */
11091186
if (a->nwords < b->nwords)
11101187
{

src/include/pg_config_manual.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,12 @@
335335
*/
336336
/* #define COPY_PARSE_PLAN_TREES */
337337

338+
/*
339+
* Define this to force Bitmapset reallocation on each modification. Helps
340+
* to find hangling pointers to Bitmapset's.
341+
*/
342+
/* #define REALLOCATE_BITMAPSETS */
343+
338344
/*
339345
* Define this to force all parse and plan trees to be passed through
340346
* outfuncs.c/readfuncs.c, to facilitate catching errors and omissions in

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy