PostgreSQL Source Code: src/backend/utils/mmgr/mcxt.c Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
23
30
31
32static void BogusFree(void *pointer);
33static void *BogusRealloc(void *pointer, Size size, int flags);
36
37
38
39
40#define BOGUS_MCTX(id) \
41 [id].free_p = BogusFree, \
42 [id].realloc = BogusRealloc, \
43 [id].get_chunk_context = BogusGetChunkContext, \
44 [id].get_chunk_space = BogusGetChunkSpace
45
47
57#ifdef MEMORY_CONTEXT_CHECKING
59#endif
60
61
71#ifdef MEMORY_CONTEXT_CHECKING
73#endif
74
75
85#ifdef MEMORY_CONTEXT_CHECKING
87#endif
88
89
99#ifdef MEMORY_CONTEXT_CHECKING
101#endif
102
103
113#ifdef MEMORY_CONTEXT_CHECKING
115#endif
116
117
118
119
120
121
122
123
135};
136
137#undef BOGUS_MCTX
138
139
140
141
142
144
145
146
147
148
156
157
159
163 int max_level, int max_children,
165 bool print_to_stderr);
167 const char *stats_string,
168 bool print_to_stderr);
169
170
171
172
173
174
175#define AssertNotInCriticalSection(context) \
176 Assert(CritSectionCount == 0 || (context)->allowInCritSection)
177
178
179
180
181
182#define MCXT_METHOD(pointer, method) \
183 mcxt_methods[GetMemoryChunkMethodID(pointer)].method
184
185
186
187
188
189
192{
194
195
196
197
198
199
201
202
204
205 header = *((const uint64 *) ((const char *) pointer - sizeof(uint64)));
206
207
209
211}
212
213
214
215
216
217
218
221{
223
224
226
227 header = *((const uint64 *) ((const char *) pointer - sizeof(uint64)));
228
229
231
232 return header;
233}
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
258{
259
262
263
264
265
266
267
268
269
271 {
273 if (curr == top)
274 return NULL;
275 }
277}
278
279
280
281
282
283
284
285static void
287{
288 elog(ERROR, "pfree called with invalid pointer %p (header 0x%016" PRIx64 ")",
290}
291
292static void *
294{
295 elog(ERROR, "repalloc called with invalid pointer %p (header 0x%016" PRIx64 ")",
297 return NULL;
298}
299
302{
303 elog(ERROR, "GetMemoryChunkContext called with invalid pointer %p (header 0x%016" PRIx64 ")",
305 return NULL;
306}
307
310{
311 elog(ERROR, "GetMemoryChunkSpace called with invalid pointer %p (header 0x%016" PRIx64 ")",
313 return 0;
314}
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338void
340{
342
343
344
345
347 "TopMemoryContext",
349
350
351
352
353
355
356
357
358
359
360
361
362
363
364
365
366
367
368
370 "ErrorContext",
371 8 * 1024,
372 8 * 1024,
373 8 * 1024);
375}
376
377
378
379
380
381
382void
384{
386
387
390
391
394}
395
396
397
398
399
400
401void
403{
405
406
408 {
410
411
412
413
414
415
416
417
418
423 }
424}
425
426
427
428
429
430
431
432void
434{
436
438 curr != NULL;
440 {
442 }
443}
444
445
446
447
448
449
450
451
452
453void
455{
457
459
460
461
462
463
464
465
466
467
468 curr = context;
469 for (;;)
470 {
472
473
476
477
478
479
480
481 parent = curr->parent;
483
484 if (curr == context)
485 break;
486 curr = parent;
487 }
488}
489
490
491
492
493
494
495static void
497{
499
501
503
505
506
507
508
509
510
511
513
514
515
516
517
518
520
521
522
523
524
525
526 context->ident = NULL;
527
529
531}
532
533
534
535
536
537
538void
540{
542
543
544
545
546
549}
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567void
570{
572
573
576
577 context->isReset = false;
578}
579
580
581
582
583
584static void
586{
588
589
590
591
592
593
594 while ((cb = context->reset_cbs) != NULL)
595 {
598 }
599}
600
601
602
603
604
605
606
607
608
609
610
611void
613{
615 context->ident = id;
616}
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636void
638{
640 Assert(context != new_parent);
641
642
643 if (new_parent == context->parent)
644 return;
645
646
648 {
650
653 else
654 {
657 }
658
661 }
662
663
664 if (new_parent)
665 {
667 context->parent = new_parent;
673 }
674 else
675 {
676 context->parent = NULL;
679 }
680}
681
682
683
684
685
686
687
688
689
690
691
692
693void
695{
697
699}
700
701
702
703
704
705
708{
709 return MCXT_METHOD(pointer, get_chunk_context) (pointer);
710}
711
712
713
714
715
716
717
718
719
722{
723 return MCXT_METHOD(pointer, get_chunk_space) (pointer);
724}
725
726
727
728
729
732{
734
735 return context->parent;
736}
737
738
739
740
741
742bool
744{
746
747
748
749
750
752 return false;
753
755}
756
757
758
759
760
763{
765
767
768 if (recurse)
769 {
771 curr != NULL;
773 {
774 total += curr->mem_allocated;
775 }
776 }
777
778 return total;
779}
780
781
782
783
784
785void
788{
790
791 memset(consumed, 0, sizeof(*consumed));
792
793
794 context->methods->stats(context, NULL, NULL, consumed, false);
795
796
798 curr != NULL;
800 {
801 curr->methods->stats(curr, NULL, NULL, consumed, false);
802 }
803}
804
805
806
807
808
809
810
811
812
813void
815{
816
818}
819
820
821
822
823
824
825
826
827
828void
830 int max_level, int max_children,
831 bool print_to_stderr)
832{
834
835 memset(&grand_totals, 0, sizeof(grand_totals));
836
838 &grand_totals, print_to_stderr);
839
840 if (print_to_stderr)
842 "Grand total: %zu bytes in %zu blocks; %zu free (%zu chunks); %zu used\n",
846 else
847 {
848
849
850
851
852
853
854
855
856
857
861 errmsg_internal("Grand total: %zu bytes in %zu blocks; %zu free (%zu chunks); %zu used",
865 }
866}
867
868
869
870
871
872
873
874
875static void
877 int max_level, int max_children,
879 bool print_to_stderr)
880{
882 int ichild;
883
885
886
889 &level,
890 totals, print_to_stderr);
891
892
893
894
895
896
897
898
899
901 ichild = 0;
903 {
904 for (; child != NULL && ichild < max_children;
905 child = child->nextchild, ichild++)
906 {
908 max_level, max_children,
909 totals,
910 print_to_stderr);
911 }
912 }
913
914 if (child != NULL)
915 {
916
918
919 memset(&local_totals, 0, sizeof(local_totals));
920
921 ichild = 0;
922 while (child != NULL)
923 {
924 child->methods->stats(child, NULL, NULL, &local_totals, false);
925 ichild++;
927 }
928
929 if (print_to_stderr)
930 {
931 for (int i = 0; i < level; i++)
934 "%d more child contexts containing %zu total in %zu blocks; %zu free (%zu chunks); %zu used\n",
935 ichild,
941 }
942 else
946 errmsg_internal("level: %d; %d more child contexts containing %zu total in %zu blocks; %zu free (%zu chunks); %zu used",
947 level,
948 ichild,
954
955 if (totals)
956 {
961 }
962 }
963}
964
965
966
967
968
969
970
971
972static void
974 const char *stats_string,
975 bool print_to_stderr)
976{
977 int level = *(int *) passthru;
978 const char *name = context->name;
980 char truncated_ident[110];
981 int i;
982
983
984
985
986
987
988 if (ident && strcmp(name, "dynahash") == 0)
989 {
992 }
993
994 truncated_ident[0] = '\0';
995
997 {
998
999
1000
1001
1002
1003
1004 int idlen = strlen(ident);
1005 bool truncated = false;
1006
1007 strcpy(truncated_ident, ": ");
1008 i = strlen(truncated_ident);
1009
1010 if (idlen > 100)
1011 {
1013 truncated = true;
1014 }
1015
1016 while (idlen-- > 0)
1017 {
1018 unsigned char c = *ident++;
1019
1020 if (c < ' ')
1021 c = ' ';
1022 truncated_ident[i++] = c;
1023 }
1024 truncated_ident[i] = '\0';
1025
1026 if (truncated)
1027 strcat(truncated_ident, "...");
1028 }
1029
1030 if (print_to_stderr)
1031 {
1032 for (i = 1; i < level; i++)
1034 fprintf(stderr, "%s: %s%s\n", name, stats_string, truncated_ident);
1035 }
1036 else
1041 level, name, stats_string, truncated_ident)));
1042}
1043
1044
1045
1046
1047
1048
1049
1050#ifdef MEMORY_CONTEXT_CHECKING
1051void
1053{
1055 context->methods->check(context);
1056
1058 curr != NULL;
1060 {
1062 curr->methods->check(curr);
1063 }
1064}
1065#endif
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099void
1104 const char *name)
1105{
1106
1108
1109
1111 Assert(node != parent);
1112
1113
1114 node->type = tag;
1117 node->parent = parent;
1122 node->ident = NULL;
1124
1125
1126 if (parent)
1127 {
1132
1134 }
1135 else
1136 {
1139 }
1140
1142}
1143
1144
1145
1146
1147
1148
1149
1150void *
1152{
1154 {
1158 (errcode(ERRCODE_OUT_OF_MEMORY),
1159 errmsg("out of memory"),
1160 errdetail("Failed on request of size %zu in memory context \"%s\".",
1161 size, context->name)));
1162 }
1163 return NULL;
1164}
1165
1166
1167
1168
1169
1170
1171void
1173{
1174 elog(ERROR, "invalid memory alloc request size %zu", size);
1175}
1176
1177
1178
1179
1180
1181
1182
1183
1184void *
1186{
1187 void *ret;
1188
1191
1192 context->isReset = false;
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204 ret = context->methods->alloc(context, size, 0);
1205
1207
1208 return ret;
1209}
1210
1211
1212
1213
1214
1215
1216
1217
1218void *
1220{
1221 void *ret;
1222
1225
1226 context->isReset = false;
1227
1228 ret = context->methods->alloc(context, size, 0);
1229
1231
1233
1234 return ret;
1235}
1236
1237
1238
1239
1240
1241void *
1243{
1244 void *ret;
1245
1248
1251 elog(ERROR, "invalid memory alloc request size %zu", size);
1252
1253 context->isReset = false;
1254
1255 ret = context->methods->alloc(context, size, flags);
1257 return NULL;
1258
1260
1263
1264 return ret;
1265}
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275void
1277{
1280
1281}
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292void
1294{
1296
1297
1298
1299
1300
1304 errmsg("logging memory contexts of PID %d", MyProcPid)));
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1318}
1319
1320void *
1322{
1323
1324 void *ret;
1326
1329
1330 context->isReset = false;
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342 ret = context->methods->alloc(context, size, 0);
1343
1344 Assert(ret != NULL);
1346
1347 return ret;
1348}
1349
1350void *
1352{
1353
1354 void *ret;
1356
1359
1360 context->isReset = false;
1361
1362 ret = context->methods->alloc(context, size, 0);
1363
1364 Assert(ret != NULL);
1366
1368
1369 return ret;
1370}
1371
1372void *
1374{
1375
1376 void *ret;
1378
1381
1382 context->isReset = false;
1383
1384 ret = context->methods->alloc(context, size, flags);
1386 {
1387
1389 return NULL;
1390 }
1391
1393
1396
1397 return ret;
1398}
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415void *
1417 Size size, Size alignto, int flags)
1418{
1420 Size alloc_size;
1421 void *unaligned;
1422 void *aligned;
1423
1424
1425 Assert(alignto < (128 * 1024 * 1024));
1426
1427
1428 Assert((alignto & (alignto - 1)) == 0);
1429
1430
1431
1432
1433
1434 if (unlikely(alignto <= MAXIMUM_ALIGNOF))
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1455
1456#ifdef MEMORY_CONTEXT_CHECKING
1457
1458 alloc_size += 1;
1459#endif
1460
1461
1463
1464
1465 aligned = (void *) TYPEALIGN(alignto, (char *) unaligned +
1467
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1482
1483
1484 Assert((void *) TYPEALIGN(alignto, aligned) == aligned);
1485
1486#ifdef MEMORY_CONTEXT_CHECKING
1487 alignedchunk->requested_size = size;
1488
1489 set_sentinel(aligned, size);
1490#endif
1491
1492
1494 (char *) alignedchunk - (char *) unaligned);
1495
1496
1498
1499 return aligned;
1500}
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517void *
1519{
1521}
1522
1523
1524
1525
1526
1527void
1529{
1530#ifdef USE_VALGRIND
1533#endif
1534
1536
1537#ifdef USE_VALGRIND
1540#endif
1541}
1542
1543
1544
1545
1546
1547void *
1549{
1550#ifdef USE_VALGRIND
1552#endif
1553#if defined(USE_ASSERT_CHECKING) || defined(USE_VALGRIND)
1555#endif
1556 void *ret;
1557
1559
1560
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1574
1575#ifdef USE_VALGRIND
1578#endif
1579
1580 return ret;
1581}
1582
1583
1584
1585
1586
1587
1588void *
1590{
1591#if defined(USE_ASSERT_CHECKING) || defined(USE_VALGRIND)
1593#endif
1594 void *ret;
1595
1597
1598
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1613 return NULL;
1614
1616
1617 return ret;
1618}
1619
1620
1621
1622
1623
1624
1625void *
1627{
1628 void *ret;
1629
1630
1631 if (unlikely(oldsize > size))
1632 elog(ERROR, "invalid repalloc0 call: oldsize %zu, new size %zu",
1633 oldsize, size);
1634
1635 ret = repalloc(pointer, size);
1636 memset((char *) ret + oldsize, 0, (size - oldsize));
1637 return ret;
1638}
1639
1640
1641
1642
1643
1644
1645
1646void *
1648{
1649 void *ret;
1650
1653
1654 context->isReset = false;
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1667
1669
1670 return ret;
1671}
1672
1673
1674
1675
1676
1677
1678void *
1680{
1681
1683}
1684
1685
1686
1687
1688
1689char *
1691{
1692 char *nstr;
1693 Size len = strlen(string) + 1;
1694
1696
1697 memcpy(nstr, string, len);
1698
1699 return nstr;
1700}
1701
1702char *
1704{
1706}
1707
1708
1709
1710
1711
1712
1713char *
1715{
1716 char *out;
1717
1719
1721 memcpy(out, in, len);
1722 out[len] = '\0';
1723
1724 return out;
1725}
1726
1727
1728
1729
1730char *
1732{
1733 size_t n;
1734
1735 n = strlen(in);
1736 while (n > 0 && in[n - 1] == '\n')
1737 n--;
1739}
MemoryContext AlignedAllocGetChunkContext(void *pointer)
void * AlignedAllocRealloc(void *pointer, Size size, int flags)
Size AlignedAllocGetChunkSpace(void *pointer)
void AlignedAllocFree(void *pointer)
void AllocSetReset(MemoryContext context)
void * AllocSetRealloc(void *pointer, Size size, int flags)
Size AllocSetGetChunkSpace(void *pointer)
MemoryContext AllocSetGetChunkContext(void *pointer)
void AllocSetStats(MemoryContext context, MemoryStatsPrintFunc printfunc, void *passthru, MemoryContextCounters *totals, bool print_to_stderr)
bool AllocSetIsEmpty(MemoryContext context)
void * AllocSetAlloc(MemoryContext context, Size size, int flags)
void AllocSetFree(void *pointer)
void AllocSetDelete(MemoryContext context)
void BumpFree(void *pointer)
void BumpDelete(MemoryContext context)
Size BumpGetChunkSpace(void *pointer)
void BumpStats(MemoryContext context, MemoryStatsPrintFunc printfunc, void *passthru, MemoryContextCounters *totals, bool print_to_stderr)
MemoryContext BumpGetChunkContext(void *pointer)
void BumpReset(MemoryContext context)
bool BumpIsEmpty(MemoryContext context)
void * BumpRealloc(void *pointer, Size size, int flags)
void * BumpAlloc(MemoryContext context, Size size, int flags)
#define TYPEALIGN(ALIGNVAL, LEN)
#define MemSetAligned(start, val, len)
#define fprintf(file, fmt, msg)
int errmsg_internal(const char *fmt,...)
int errhidestmt(bool hide_stmt)
int errdetail(const char *fmt,...)
int errhidecontext(bool hide_ctx)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
#define MCXT_ALLOC_NO_OOM
void * GenerationRealloc(void *pointer, Size size, int flags)
void GenerationReset(MemoryContext context)
void GenerationFree(void *pointer)
MemoryContext GenerationGetChunkContext(void *pointer)
Size GenerationGetChunkSpace(void *pointer)
bool GenerationIsEmpty(MemoryContext context)
void GenerationStats(MemoryContext context, MemoryStatsPrintFunc printfunc, void *passthru, MemoryContextCounters *totals, bool print_to_stderr)
void GenerationDelete(MemoryContext context)
void * GenerationAlloc(MemoryContext context, Size size, int flags)
volatile sig_atomic_t LogMemoryContextPending
volatile sig_atomic_t InterruptPending
volatile uint32 CritSectionCount
Assert(PointerIsAligned(start, uint64))
int pg_mbcliplen(const char *mbstr, int len, int limit)
static void MemoryContextStatsInternal(MemoryContext context, int level, int max_level, int max_children, MemoryContextCounters *totals, bool print_to_stderr)
void * repalloc0(void *pointer, Size oldsize, Size size)
static void MemoryContextCallResetCallbacks(MemoryContext context)
char * MemoryContextStrdup(MemoryContext context, const char *string)
void * MemoryContextAlloc(MemoryContext context, Size size)
MemoryContext MessageContext
bool MemoryContextIsEmpty(MemoryContext context)
void MemoryContextMemConsumed(MemoryContext context, MemoryContextCounters *consumed)
void MemoryContextReset(MemoryContext context)
void MemoryContextCreate(MemoryContext node, NodeTag tag, MemoryContextMethodID method_id, MemoryContext parent, const char *name)
void * MemoryContextAllocZero(MemoryContext context, Size size)
MemoryContext TopTransactionContext
char * pstrdup(const char *in)
void HandleLogMemoryContextInterrupt(void)
void MemoryContextRegisterResetCallback(MemoryContext context, MemoryContextCallback *cb)
static MemoryContextMethodID GetMemoryChunkMethodID(const void *pointer)
void MemoryContextSetParent(MemoryContext context, MemoryContext new_parent)
static void * BogusRealloc(void *pointer, Size size, int flags)
void * repalloc(void *pointer, Size size)
void pfree(void *pointer)
Size GetMemoryChunkSpace(void *pointer)
void * palloc0(Size size)
static Size BogusGetChunkSpace(void *pointer)
void * MemoryContextAllocAligned(MemoryContext context, Size size, Size alignto, int flags)
void MemoryContextDeleteChildren(MemoryContext context)
MemoryContext TopMemoryContext
char * pchomp(const char *in)
#define AssertNotInCriticalSection(context)
MemoryContext CurTransactionContext
MemoryContext CurrentMemoryContext
static MemoryContext MemoryContextTraverseNext(MemoryContext curr, MemoryContext top)
MemoryContext GetMemoryChunkContext(void *pointer)
void * MemoryContextAllocExtended(MemoryContext context, Size size, int flags)
void MemoryContextStatsDetail(MemoryContext context, int max_level, int max_children, bool print_to_stderr)
Size MemoryContextMemAllocated(MemoryContext context, bool recurse)
char * pnstrdup(const char *in, Size len)
void MemoryContextStats(MemoryContext context)
void MemoryContextInit(void)
static void BogusFree(void *pointer)
void * palloc_extended(Size size, int flags)
MemoryContext PostmasterContext
void * MemoryContextAllocationFailure(MemoryContext context, Size size, int flags)
static const MemoryContextMethods mcxt_methods[]
void * repalloc_extended(void *pointer, Size size, int flags)
MemoryContext MemoryContextGetParent(MemoryContext context)
void ProcessLogMemoryContextInterrupt(void)
MemoryContext ErrorContext
static MemoryContext BogusGetChunkContext(void *pointer)
MemoryContext CacheMemoryContext
void MemoryContextSizeFailure(MemoryContext context, Size size, int flags)
void * MemoryContextAllocHuge(MemoryContext context, Size size)
void MemoryContextDelete(MemoryContext context)
void MemoryContextAllowInCriticalSection(MemoryContext context, bool allow)
static void MemoryContextDeleteOnly(MemoryContext context)
void MemoryContextResetChildren(MemoryContext context)
static void MemoryContextStatsPrint(MemoryContext context, void *passthru, const char *stats_string, bool print_to_stderr)
void * repalloc_huge(void *pointer, Size size)
void MemoryContextSetIdentifier(MemoryContext context, const char *id)
void MemoryContextResetOnly(MemoryContext context)
static uint64 GetMemoryChunkHeader(const void *pointer)
MemoryContext PortalContext
void * palloc_aligned(Size size, Size alignto, int flags)
#define MCXT_METHOD(pointer, method)
#define VALGRIND_DESTROY_MEMPOOL(context)
#define VALGRIND_MAKE_MEM_DEFINED(addr, size)
#define VALGRIND_MEMPOOL_CHANGE(context, optr, nptr, size)
#define VALGRIND_CREATE_MEMPOOL(context, redzones, zeroed)
#define VALGRIND_MEMPOOL_ALLOC(context, addr, size)
#define VALGRIND_MEMPOOL_FREE(context, addr)
#define VALGRIND_MAKE_MEM_NOACCESS(addr, size)
#define MemoryContextIsValid(context)
#define AllocSetContextCreate
#define ALLOCSET_DEFAULT_SIZES
#define AllocHugeSizeIsValid(size)
#define AllocSizeIsValid(size)
#define MEMORY_CONTEXT_METHODID_MASK
#define PallocAlignedExtraBytes(alignto)
@ MCTX_15_RESERVED_WIPEDMEM_ID
@ MCTX_1_RESERVED_GLIBC_ID
@ MCTX_0_RESERVED_UNUSEDMEM_ID
@ MCTX_2_RESERVED_GLIBC_ID
@ MCTX_ALIGNED_REDIRECT_ID
struct MemoryChunk MemoryChunk
#define PointerGetMemoryChunk(p)
static void MemoryChunkSetHdrMask(MemoryChunk *chunk, void *block, Size value, MemoryContextMethodID methodid)
size_t strnlen(const char *str, size_t maxlen)
void * SlabAlloc(MemoryContext context, Size size, int flags)
void SlabFree(void *pointer)
void SlabReset(MemoryContext context)
Size SlabGetChunkSpace(void *pointer)
bool SlabIsEmpty(MemoryContext context)
MemoryContext SlabGetChunkContext(void *pointer)
void * SlabRealloc(void *pointer, Size size, int flags)
void SlabStats(MemoryContext context, MemoryStatsPrintFunc printfunc, void *passthru, MemoryContextCounters *totals, bool print_to_stderr)
void SlabDelete(MemoryContext context)
bool stack_is_too_deep(void)
struct MemoryContextCallback * next
MemoryContextCallbackFunction func
MemoryContextCallback * reset_cbs
const MemoryContextMethods * methods
void(* delete_context)(MemoryContext context)
void(* stats)(MemoryContext context, MemoryStatsPrintFunc printfunc, void *passthru, MemoryContextCounters *totals, bool print_to_stderr)
bool(* is_empty)(MemoryContext context)
void *(* alloc)(MemoryContext context, Size size, int flags)
void(* reset)(MemoryContext context)