1 /*------------------------------------------------------------------------- 2 * 3 * mcxt.c 4 * POSTGRES memory context management code. 5 * 6 * This module handles context management operations that are independent 7 * of the particular kind of context being operated on. It calls 8 * context-type-specific operations via the function pointers in a 9 * context's MemoryContextMethods struct. 10 * 11 * 12 * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group 13 * Portions Copyright (c) 1994, Regents of the University of California 14 * 15 * 16 * IDENTIFICATION 17 * src/backend/utils/mmgr/mcxt.c 18 * 19 *------------------------------------------------------------------------- 20 */ 21 22 #include "postgres.h" 23 24 #include "mb/pg_wchar.h" 25 #include "miscadmin.h" 26 #include "utils/memdebug.h" 27 #include "utils/memutils.h" 28 29 30 /***************************************************************************** 31 * GLOBAL MEMORY * 32 *****************************************************************************/ 33 34 /* 35 * CurrentMemoryContext 36 * Default memory context for allocations. 37 */ 38 MemoryContext CurrentMemoryContext = NULL; 39 40 /* 41 * Standard top-level contexts. For a description of the purpose of each 42 * of these contexts, refer to src/backend/utils/mmgr/README 43 */ 44 MemoryContext TopMemoryContext = NULL; 45 MemoryContext ErrorContext = NULL; 46 MemoryContext PostmasterContext = NULL; 47 MemoryContext CacheMemoryContext = NULL; 48 MemoryContext MessageContext = NULL; 49 MemoryContext TopTransactionContext = NULL; 50 MemoryContext CurTransactionContext = NULL; 51 52 /* This is a transient link to the active portal's memory context: */ 53 MemoryContext PortalContext = NULL; 54 55 static void MemoryContextCallResetCallbacks(MemoryContext context); 56 static void MemoryContextStatsInternal(MemoryContext context, int level, 57 bool print, int max_children, 58 MemoryContextCounters *totals); 59 static void MemoryContextStatsPrint(MemoryContext context, void *passthru, 60 const char *stats_string); 61 62 /* 63 * You should not do memory allocations within a critical section, because 64 * an out-of-memory error will be escalated to a PANIC. To enforce that 65 * rule, the allocation functions Assert that. 66 */ 67 #define AssertNotInCriticalSection(context) \ 68 Assert(CritSectionCount == 0 || (context)->allowInCritSection) 69 70 /***************************************************************************** 71 * EXPORTED ROUTINES * 72 *****************************************************************************/ 73 74 75 /* 76 * MemoryContextInit 77 * Start up the memory-context subsystem. 78 * 79 * This must be called before creating contexts or allocating memory in 80 * contexts. TopMemoryContext and ErrorContext are initialized here; 81 * other contexts must be created afterwards. 82 * 83 * In normal multi-backend operation, this is called once during 84 * postmaster startup, and not at all by individual backend startup 85 * (since the backends inherit an already-initialized context subsystem 86 * by virtue of being forked off the postmaster). But in an EXEC_BACKEND 87 * build, each process must do this for itself. 88 * 89 * In a standalone backend this must be called during backend startup. 90 */ 91 void 92 MemoryContextInit(void) 93 { 94 AssertState(TopMemoryContext == NULL); 95 96 /* 97 * First, initialize TopMemoryContext, which is the parent of all others. 98 */ 99 TopMemoryContext = AllocSetContextCreate((MemoryContext) NULL, 100 "TopMemoryContext", 101 ALLOCSET_DEFAULT_SIZES); 102 103 /* 104 * Not having any other place to point CurrentMemoryContext, make it point 105 * to TopMemoryContext. Caller should change this soon! 106 */ 107 CurrentMemoryContext = TopMemoryContext; 108 109 /* 110 * Initialize ErrorContext as an AllocSetContext with slow growth rate --- 111 * we don't really expect much to be allocated in it. More to the point, 112 * require it to contain at least 8K at all times. This is the only case 113 * where retained memory in a context is *essential* --- we want to be 114 * sure ErrorContext still has some memory even if we've run out 115 * elsewhere! Also, allow allocations in ErrorContext within a critical 116 * section. Otherwise a PANIC will cause an assertion failure in the error 117 * reporting code, before printing out the real cause of the failure. 118 * 119 * This should be the last step in this function, as elog.c assumes memory 120 * management works once ErrorContext is non-null. 121 */ 122 ErrorContext = AllocSetContextCreate(TopMemoryContext, 123 "ErrorContext", 124 8 * 1024, 125 8 * 1024, 126 8 * 1024); 127 MemoryContextAllowInCriticalSection(ErrorContext, true); 128 } 129 130 /* 131 * MemoryContextReset 132 * Release all space allocated within a context and delete all its 133 * descendant contexts (but not the named context itself). 134 */ 135 void 136 MemoryContextReset(MemoryContext context) 137 { 138 AssertArg(MemoryContextIsValid(context)); 139 140 /* save a function call in common case where there are no children */ 141 if (context->firstchild != NULL) 142 MemoryContextDeleteChildren(context); 143 144 /* save a function call if no pallocs since startup or last reset */ 145 if (!context->isReset) 146 MemoryContextResetOnly(context); 147 } 148 149 /* 150 * MemoryContextResetOnly 151 * Release all space allocated within a context. 152 * Nothing is done to the context's descendant contexts. 153 */ 154 void 155 MemoryContextResetOnly(MemoryContext context) 156 { 157 AssertArg(MemoryContextIsValid(context)); 158 159 /* Nothing to do if no pallocs since startup or last reset */ 160 if (!context->isReset) 161 { 162 MemoryContextCallResetCallbacks(context); 163 164 /* 165 * If context->ident points into the context's memory, it will become 166 * a dangling pointer. We could prevent that by setting it to NULL 167 * here, but that would break valid coding patterns that keep the 168 * ident elsewhere, e.g. in a parent context. Another idea is to use 169 * MemoryContextContains(), but we don't require ident strings to be 170 * in separately-palloc'd chunks, so that risks false positives. So 171 * for now we assume the programmer got it right. 172 */ 173 174 context->methods->reset(context); 175 context->isReset = true; 176 VALGRIND_DESTROY_MEMPOOL(context); 177 VALGRIND_CREATE_MEMPOOL(context, 0, false); 178 } 179 } 180 181 /* 182 * MemoryContextResetChildren 183 * Release all space allocated within a context's descendants, 184 * but don't delete the contexts themselves. The named context 185 * itself is not touched. 186 */ 187 void 188 MemoryContextResetChildren(MemoryContext context) 189 { 190 MemoryContext child; 191 192 AssertArg(MemoryContextIsValid(context)); 193 194 for (child = context->firstchild; child != NULL; child = child->nextchild) 195 { 196 MemoryContextResetChildren(child); 197 MemoryContextResetOnly(child); 198 } 199 } 200 201 /* 202 * MemoryContextDelete 203 * Delete a context and its descendants, and release all space 204 * allocated therein. 205 * 206 * The type-specific delete routine removes all storage for the context, 207 * but we have to recurse to handle the children. 208 * We must also delink the context from its parent, if it has one. 209 */ 210 void 211 MemoryContextDelete(MemoryContext context) 212 { 213 AssertArg(MemoryContextIsValid(context)); 214 /* We had better not be deleting TopMemoryContext ... */ 215 Assert(context != TopMemoryContext); 216 /* And not CurrentMemoryContext, either */ 217 Assert(context != CurrentMemoryContext); 218 219 /* save a function call in common case where there are no children */ 220 if (context->firstchild != NULL) 221 MemoryContextDeleteChildren(context); 222 223 /* 224 * It's not entirely clear whether 'tis better to do this before or after 225 * delinking the context; but an error in a callback will likely result in 226 * leaking the whole context (if it's not a root context) if we do it 227 * after, so let's do it before. 228 */ 229 MemoryContextCallResetCallbacks(context); 230 231 /* 232 * We delink the context from its parent before deleting it, so that if 233 * there's an error we won't have deleted/busted contexts still attached 234 * to the context tree. Better a leak than a crash. 235 */ 236 MemoryContextSetParent(context, NULL); 237 238 /* 239 * Also reset the context's ident pointer, in case it points into the 240 * context. This would only matter if someone tries to get stats on the 241 * (already unlinked) context, which is unlikely, but let's be safe. 242 */ 243 context->ident = NULL; 244 245 context->methods->delete_context(context); 246 247 VALGRIND_DESTROY_MEMPOOL(context); 248 } 249 250 /* 251 * MemoryContextDeleteChildren 252 * Delete all the descendants of the named context and release all 253 * space allocated therein. The named context itself is not touched. 254 */ 255 void 256 MemoryContextDeleteChildren(MemoryContext context) 257 { 258 AssertArg(MemoryContextIsValid(context)); 259 260 /* 261 * MemoryContextDelete will delink the child from me, so just iterate as 262 * long as there is a child. 263 */ 264 while (context->firstchild != NULL) 265 MemoryContextDelete(context->firstchild); 266 } 267 268 /* 269 * MemoryContextRegisterResetCallback 270 * Register a function to be called before next context reset/delete. 271 * Such callbacks will be called in reverse order of registration. 272 * 273 * The caller is responsible for allocating a MemoryContextCallback struct 274 * to hold the info about this callback request, and for filling in the 275 * "func" and "arg" fields in the struct to show what function to call with 276 * what argument. Typically the callback struct should be allocated within 277 * the specified context, since that means it will automatically be freed 278 * when no longer needed. 279 * 280 * There is no API for deregistering a callback once registered. If you 281 * want it to not do anything anymore, adjust the state pointed to by its 282 * "arg" to indicate that. 283 */ 284 void 285 MemoryContextRegisterResetCallback(MemoryContext context, 286 MemoryContextCallback *cb) 287 { 288 AssertArg(MemoryContextIsValid(context)); 289 290 /* Push onto head so this will be called before older registrants. */ 291 cb->next = context->reset_cbs; 292 context->reset_cbs = cb; 293 /* Mark the context as non-reset (it probably is already). */ 294 context->isReset = false; 295 } 296 297 /* 298 * MemoryContextCallResetCallbacks 299 * Internal function to call all registered callbacks for context. 300 */ 301 static void 302 MemoryContextCallResetCallbacks(MemoryContext context) 303 { 304 MemoryContextCallback *cb; 305 306 /* 307 * We pop each callback from the list before calling. That way, if an 308 * error occurs inside the callback, we won't try to call it a second time 309 * in the likely event that we reset or delete the context later. 310 */ 311 while ((cb = context->reset_cbs) != NULL) 312 { 313 context->reset_cbs = cb->next; 314 cb->func(cb->arg); 315 } 316 } 317 318 /* 319 * MemoryContextSetIdentifier 320 * Set the identifier string for a memory context. 321 * 322 * An identifier can be provided to help distinguish among different contexts 323 * of the same kind in memory context stats dumps. The identifier string 324 * must live at least as long as the context it is for; typically it is 325 * allocated inside that context, so that it automatically goes away on 326 * context deletion. Pass id = NULL to forget any old identifier. 327 */ 328 void 329 MemoryContextSetIdentifier(MemoryContext context, const char *id) 330 { 331 AssertArg(MemoryContextIsValid(context)); 332 context->ident = id; 333 } 334 335 /* 336 * MemoryContextSetParent 337 * Change a context to belong to a new parent (or no parent). 338 * 339 * We provide this as an API function because it is sometimes useful to 340 * change a context's lifespan after creation. For example, a context 341 * might be created underneath a transient context, filled with data, 342 * and then reparented underneath CacheMemoryContext to make it long-lived. 343 * In this way no special effort is needed to get rid of the context in case 344 * a failure occurs before its contents are completely set up. 345 * 346 * Callers often assume that this function cannot fail, so don't put any 347 * elog(ERROR) calls in it. 348 * 349 * A possible caller error is to reparent a context under itself, creating 350 * a loop in the context graph. We assert here that context != new_parent, 351 * but checking for multi-level loops seems more trouble than it's worth. 352 */ 353 void 354 MemoryContextSetParent(MemoryContext context, MemoryContext new_parent) 355 { 356 AssertArg(MemoryContextIsValid(context)); 357 AssertArg(context != new_parent); 358 359 /* Fast path if it's got correct parent already */ 360 if (new_parent == context->parent) 361 return; 362 363 /* Delink from existing parent, if any */ 364 if (context->parent) 365 { 366 MemoryContext parent = context->parent; 367 368 if (context->prevchild != NULL) 369 context->prevchild->nextchild = context->nextchild; 370 else 371 { 372 Assert(parent->firstchild == context); 373 parent->firstchild = context->nextchild; 374 } 375 376 if (context->nextchild != NULL) 377 context->nextchild->prevchild = context->prevchild; 378 } 379 380 /* And relink */ 381 if (new_parent) 382 { 383 AssertArg(MemoryContextIsValid(new_parent)); 384 context->parent = new_parent; 385 context->prevchild = NULL; 386 context->nextchild = new_parent->firstchild; 387 if (new_parent->firstchild != NULL) 388 new_parent->firstchild->prevchild = context; 389 new_parent->firstchild = context; 390 } 391 else 392 { 393 context->parent = NULL; 394 context->prevchild = NULL; 395 context->nextchild = NULL; 396 } 397 } 398 399 /* 400 * MemoryContextAllowInCriticalSection 401 * Allow/disallow allocations in this memory context within a critical 402 * section. 403 * 404 * Normally, memory allocations are not allowed within a critical section, 405 * because a failure would lead to PANIC. There are a few exceptions to 406 * that, like allocations related to debugging code that is not supposed to 407 * be enabled in production. This function can be used to exempt specific 408 * memory contexts from the assertion in palloc(). 409 */ 410 void 411 MemoryContextAllowInCriticalSection(MemoryContext context, bool allow) 412 { 413 AssertArg(MemoryContextIsValid(context)); 414 415 context->allowInCritSection = allow; 416 } 417 418 /* 419 * GetMemoryChunkSpace 420 * Given a currently-allocated chunk, determine the total space 421 * it occupies (including all memory-allocation overhead). 422 * 423 * This is useful for measuring the total space occupied by a set of 424 * allocated chunks. 425 */ 426 Size 427 GetMemoryChunkSpace(void *pointer) 428 { 429 MemoryContext context = GetMemoryChunkContext(pointer); 430 431 return context->methods->get_chunk_space(context, pointer); 432 } 433 434 /* 435 * MemoryContextGetParent 436 * Get the parent context (if any) of the specified context 437 */ 438 MemoryContext 439 MemoryContextGetParent(MemoryContext context) 440 { 441 AssertArg(MemoryContextIsValid(context)); 442 443 return context->parent; 444 } 445 446 /* 447 * MemoryContextIsEmpty 448 * Is a memory context empty of any allocated space? 449 */ 450 bool 451 MemoryContextIsEmpty(MemoryContext context) 452 { 453 AssertArg(MemoryContextIsValid(context)); 454 455 /* 456 * For now, we consider a memory context nonempty if it has any children; 457 * perhaps this should be changed later. 458 */ 459 if (context->firstchild != NULL) 460 return false; 461 /* Otherwise use the type-specific inquiry */ 462 return context->methods->is_empty(context); 463 } 464 465 /* 466 * Find the memory allocated to blocks for this memory context. If recurse is 467 * true, also include children. 468 */ 469 Size 470 MemoryContextMemAllocated(MemoryContext context, bool recurse) 471 { 472 Size total = context->mem_allocated; 473 474 AssertArg(MemoryContextIsValid(context)); 475 476 if (recurse) 477 { 478 MemoryContext child = context->firstchild; 479 480 for (child = context->firstchild; 481 child != NULL; 482 child = child->nextchild) 483 total += MemoryContextMemAllocated(child, true); 484 } 485 486 return total; 487 } 488 489 /* 490 * MemoryContextStats 491 * Print statistics about the named context and all its descendants. 492 * 493 * This is just a debugging utility, so it's not very fancy. However, we do 494 * make some effort to summarize when the output would otherwise be very long. 495 * The statistics are sent to stderr. 496 */ 497 void 498 MemoryContextStats(MemoryContext context) 499 { 500 /* A hard-wired limit on the number of children is usually good enough */ 501 MemoryContextStatsDetail(context, 100); 502 } 503 504 /* 505 * MemoryContextStatsDetail 506 * 507 * Entry point for use if you want to vary the number of child contexts shown. 508 */ 509 void 510 MemoryContextStatsDetail(MemoryContext context, int max_children) 511 { 512 MemoryContextCounters grand_totals; 513 514 memset(&grand_totals, 0, sizeof(grand_totals)); 515 516 MemoryContextStatsInternal(context, 0, true, max_children, &grand_totals); 517 518 fprintf(stderr, 519 "Grand total: %zu bytes in %zd blocks; %zu free (%zd chunks); %zu used\n", 520 grand_totals.totalspace, grand_totals.nblocks, 521 grand_totals.freespace, grand_totals.freechunks, 522 grand_totals.totalspace - grand_totals.freespace); 523 } 524 525 /* 526 * MemoryContextStatsInternal 527 * One recursion level for MemoryContextStats 528 * 529 * Print this context if print is true, but in any case accumulate counts into 530 * *totals (if given). 531 */ 532 static void 533 MemoryContextStatsInternal(MemoryContext context, int level, 534 bool print, int max_children, 535 MemoryContextCounters *totals) 536 { 537 MemoryContextCounters local_totals; 538 MemoryContext child; 539 int ichild; 540 541 AssertArg(MemoryContextIsValid(context)); 542 543 /* Examine the context itself */ 544 context->methods->stats(context, 545 print ? MemoryContextStatsPrint : NULL, 546 (void *) &level, 547 totals); 548 549 /* 550 * Examine children. If there are more than max_children of them, we do 551 * not print the rest explicitly, but just summarize them. 552 */ 553 memset(&local_totals, 0, sizeof(local_totals)); 554 555 for (child = context->firstchild, ichild = 0; 556 child != NULL; 557 child = child->nextchild, ichild++) 558 { 559 if (ichild < max_children) 560 MemoryContextStatsInternal(child, level + 1, 561 print, max_children, 562 totals); 563 else 564 MemoryContextStatsInternal(child, level + 1, 565 false, max_children, 566 &local_totals); 567 } 568 569 /* Deal with excess children */ 570 if (ichild > max_children) 571 { 572 if (print) 573 { 574 int i; 575 576 for (i = 0; i <= level; i++) 577 fprintf(stderr, " "); 578 fprintf(stderr, 579 "%d more child contexts containing %zu total in %zd blocks; %zu free (%zd chunks); %zu used\n", 580 ichild - max_children, 581 local_totals.totalspace, 582 local_totals.nblocks, 583 local_totals.freespace, 584 local_totals.freechunks, 585 local_totals.totalspace - local_totals.freespace); 586 } 587 588 if (totals) 589 { 590 totals->nblocks += local_totals.nblocks; 591 totals->freechunks += local_totals.freechunks; 592 totals->totalspace += local_totals.totalspace; 593 totals->freespace += local_totals.freespace; 594 } 595 } 596 } 597 598 /* 599 * MemoryContextStatsPrint 600 * Print callback used by MemoryContextStatsInternal 601 * 602 * For now, the passthru pointer just points to "int level"; later we might 603 * make that more complicated. 604 */ 605 static void 606 MemoryContextStatsPrint(MemoryContext context, void *passthru, 607 const char *stats_string) 608 { 609 int level = *(int *) passthru; 610 const char *name = context->name; 611 const char *ident = context->ident; 612 int i; 613 614 /* 615 * It seems preferable to label dynahash contexts with just the hash table 616 * name. Those are already unique enough, so the "dynahash" part isn't 617 * very helpful, and this way is more consistent with pre-v11 practice. 618 */ 619 if (ident && strcmp(name, "dynahash") == 0) 620 { 621 name = ident; 622 ident = NULL; 623 } 624 625 for (i = 0; i < level; i++) 626 fprintf(stderr, " "); 627 fprintf(stderr, "%s: %s", name, stats_string); 628 if (ident) 629 { 630 /* 631 * Some contexts may have very long identifiers (e.g., SQL queries). 632 * Arbitrarily truncate at 100 bytes, but be careful not to break 633 * multibyte characters. Also, replace ASCII control characters, such 634 * as newlines, with spaces. 635 */ 636 int idlen = strlen(ident); 637 bool truncated = false; 638 639 if (idlen > 100) 640 { 641 idlen = pg_mbcliplen(ident, idlen, 100); 642 truncated = true; 643 } 644 fprintf(stderr, ": "); 645 while (idlen-- > 0) 646 { 647 unsigned char c = *ident++; 648 649 if (c < ' ') 650 c = ' '; 651 fputc(c, stderr); 652 } 653 if (truncated) 654 fprintf(stderr, "..."); 655 } 656 fputc('\n', stderr); 657 } 658 659 /* 660 * MemoryContextCheck 661 * Check all chunks in the named context. 662 * 663 * This is just a debugging utility, so it's not fancy. 664 */ 665 #ifdef MEMORY_CONTEXT_CHECKING 666 void 667 MemoryContextCheck(MemoryContext context) 668 { 669 MemoryContext child; 670 671 AssertArg(MemoryContextIsValid(context)); 672 673 context->methods->check(context); 674 for (child = context->firstchild; child != NULL; child = child->nextchild) 675 MemoryContextCheck(child); 676 } 677 #endif 678 679 /* 680 * MemoryContextContains 681 * Detect whether an allocated chunk of memory belongs to a given 682 * context or not. 683 * 684 * Caution: this test is reliable as long as 'pointer' does point to 685 * a chunk of memory allocated from *some* context. If 'pointer' points 686 * at memory obtained in some other way, there is a small chance of a 687 * false-positive result, since the bits right before it might look like 688 * a valid chunk header by chance. 689 */ 690 bool 691 MemoryContextContains(MemoryContext context, void *pointer) 692 { 693 MemoryContext ptr_context; 694 695 /* 696 * NB: Can't use GetMemoryChunkContext() here - that performs assertions 697 * that aren't acceptable here since we might be passed memory not 698 * allocated by any memory context. 699 * 700 * Try to detect bogus pointers handed to us, poorly though we can. 701 * Presumably, a pointer that isn't MAXALIGNED isn't pointing at an 702 * allocated chunk. 703 */ 704 if (pointer == NULL || pointer != (void *) MAXALIGN(pointer)) 705 return false; 706 707 /* 708 * OK, it's probably safe to look at the context. 709 */ 710 ptr_context = *(MemoryContext *) (((char *) pointer) - sizeof(void *)); 711 712 return ptr_context == context; 713 } 714 715 /* 716 * MemoryContextCreate 717 * Context-type-independent part of context creation. 718 * 719 * This is only intended to be called by context-type-specific 720 * context creation routines, not by the unwashed masses. 721 * 722 * The memory context creation procedure goes like this: 723 * 1. Context-type-specific routine makes some initial space allocation, 724 * including enough space for the context header. If it fails, 725 * it can ereport() with no damage done. 726 * 2. Context-type-specific routine sets up all type-specific fields of 727 * the header (those beyond MemoryContextData proper), as well as any 728 * other management fields it needs to have a fully valid context. 729 * Usually, failure in this step is impossible, but if it's possible 730 * the initial space allocation should be freed before ereport'ing. 731 * 3. Context-type-specific routine calls MemoryContextCreate() to fill in 732 * the generic header fields and link the context into the context tree. 733 * 4. We return to the context-type-specific routine, which finishes 734 * up type-specific initialization. This routine can now do things 735 * that might fail (like allocate more memory), so long as it's 736 * sure the node is left in a state that delete will handle. 737 * 738 * node: the as-yet-uninitialized common part of the context header node. 739 * tag: NodeTag code identifying the memory context type. 740 * methods: context-type-specific methods (usually statically allocated). 741 * parent: parent context, or NULL if this will be a top-level context. 742 * name: name of context (must be statically allocated). 743 * 744 * Context routines generally assume that MemoryContextCreate can't fail, 745 * so this can contain Assert but not elog/ereport. 746 */ 747 void 748 MemoryContextCreate(MemoryContext node, 749 NodeTag tag, 750 const MemoryContextMethods *methods, 751 MemoryContext parent, 752 const char *name) 753 { 754 /* Creating new memory contexts is not allowed in a critical section */ 755 Assert(CritSectionCount == 0); 756 757 /* Initialize all standard fields of memory context header */ 758 node->type = tag; 759 node->isReset = true; 760 node->methods = methods; 761 node->parent = parent; 762 node->firstchild = NULL; 763 node->mem_allocated = 0; 764 node->prevchild = NULL; 765 node->name = name; 766 node->ident = NULL; 767 node->reset_cbs = NULL; 768 769 /* OK to link node into context tree */ 770 if (parent) 771 { 772 node->nextchild = parent->firstchild; 773 if (parent->firstchild != NULL) 774 parent->firstchild->prevchild = node; 775 parent->firstchild = node; 776 /* inherit allowInCritSection flag from parent */ 777 node->allowInCritSection = parent->allowInCritSection; 778 } 779 else 780 { 781 node->nextchild = NULL; 782 node->allowInCritSection = false; 783 } 784 785 VALGRIND_CREATE_MEMPOOL(node, 0, false); 786 } 787 788 /* 789 * MemoryContextAlloc 790 * Allocate space within the specified context. 791 * 792 * This could be turned into a macro, but we'd have to import 793 * nodes/memnodes.h into postgres.h which seems a bad idea. 794 */ 795 void * 796 MemoryContextAlloc(MemoryContext context, Size size) 797 { 798 void *ret; 799 800 AssertArg(MemoryContextIsValid(context)); 801 AssertNotInCriticalSection(context); 802 803 if (!AllocSizeIsValid(size)) 804 elog(ERROR, "invalid memory alloc request size %zu", size); 805 806 context->isReset = false; 807 808 ret = context->methods->alloc(context, size); 809 if (unlikely(ret == NULL)) 810 { 811 MemoryContextStats(TopMemoryContext); 812 813 /* 814 * Here, and elsewhere in this module, we show the target context's 815 * "name" but not its "ident" (if any) in user-visible error messages. 816 * The "ident" string might contain security-sensitive data, such as 817 * values in SQL commands. 818 */ 819 ereport(ERROR, 820 (errcode(ERRCODE_OUT_OF_MEMORY), 821 errmsg("out of memory"), 822 errdetail("Failed on request of size %zu in memory context \"%s\".", 823 size, context->name))); 824 } 825 826 VALGRIND_MEMPOOL_ALLOC(context, ret, size); 827 828 return ret; 829 } 830 831 /* 832 * MemoryContextAllocZero 833 * Like MemoryContextAlloc, but clears allocated memory 834 * 835 * We could just call MemoryContextAlloc then clear the memory, but this 836 * is a very common combination, so we provide the combined operation. 837 */ 838 void * 839 MemoryContextAllocZero(MemoryContext context, Size size) 840 { 841 void *ret; 842 843 AssertArg(MemoryContextIsValid(context)); 844 AssertNotInCriticalSection(context); 845 846 if (!AllocSizeIsValid(size)) 847 elog(ERROR, "invalid memory alloc request size %zu", size); 848 849 context->isReset = false; 850 851 ret = context->methods->alloc(context, size); 852 if (unlikely(ret == NULL)) 853 { 854 MemoryContextStats(TopMemoryContext); 855 ereport(ERROR, 856 (errcode(ERRCODE_OUT_OF_MEMORY), 857 errmsg("out of memory"), 858 errdetail("Failed on request of size %zu in memory context \"%s\".", 859 size, context->name))); 860 } 861 862 VALGRIND_MEMPOOL_ALLOC(context, ret, size); 863 864 MemSetAligned(ret, 0, size); 865 866 return ret; 867 } 868 869 /* 870 * MemoryContextAllocZeroAligned 871 * MemoryContextAllocZero where length is suitable for MemSetLoop 872 * 873 * This might seem overly specialized, but it's not because newNode() 874 * is so often called with compile-time-constant sizes. 875 */ 876 void * 877 MemoryContextAllocZeroAligned(MemoryContext context, Size size) 878 { 879 void *ret; 880 881 AssertArg(MemoryContextIsValid(context)); 882 AssertNotInCriticalSection(context); 883 884 if (!AllocSizeIsValid(size)) 885 elog(ERROR, "invalid memory alloc request size %zu", size); 886 887 context->isReset = false; 888 889 ret = context->methods->alloc(context, size); 890 if (unlikely(ret == NULL)) 891 { 892 MemoryContextStats(TopMemoryContext); 893 ereport(ERROR, 894 (errcode(ERRCODE_OUT_OF_MEMORY), 895 errmsg("out of memory"), 896 errdetail("Failed on request of size %zu in memory context \"%s\".", 897 size, context->name))); 898 } 899 900 VALGRIND_MEMPOOL_ALLOC(context, ret, size); 901 902 MemSetLoop(ret, 0, size); 903 904 return ret; 905 } 906 907 /* 908 * MemoryContextAllocExtended 909 * Allocate space within the specified context using the given flags. 910 */ 911 void * 912 MemoryContextAllocExtended(MemoryContext context, Size size, int flags) 913 { 914 void *ret; 915 916 AssertArg(MemoryContextIsValid(context)); 917 AssertNotInCriticalSection(context); 918 919 if (((flags & MCXT_ALLOC_HUGE) != 0 && !AllocHugeSizeIsValid(size)) || 920 ((flags & MCXT_ALLOC_HUGE) == 0 && !AllocSizeIsValid(size))) 921 elog(ERROR, "invalid memory alloc request size %zu", size); 922 923 context->isReset = false; 924 925 ret = context->methods->alloc(context, size); 926 if (unlikely(ret == NULL)) 927 { 928 if ((flags & MCXT_ALLOC_NO_OOM) == 0) 929 { 930 MemoryContextStats(TopMemoryContext); 931 ereport(ERROR, 932 (errcode(ERRCODE_OUT_OF_MEMORY), 933 errmsg("out of memory"), 934 errdetail("Failed on request of size %zu in memory context \"%s\".", 935 size, context->name))); 936 } 937 return NULL; 938 } 939 940 VALGRIND_MEMPOOL_ALLOC(context, ret, size); 941 942 if ((flags & MCXT_ALLOC_ZERO) != 0) 943 MemSetAligned(ret, 0, size); 944 945 return ret; 946 } 947 948 void * 949 palloc(Size size) 950 { 951 /* duplicates MemoryContextAlloc to avoid increased overhead */ 952 void *ret; 953 MemoryContext context = CurrentMemoryContext; 954 955 AssertArg(MemoryContextIsValid(context)); 956 AssertNotInCriticalSection(context); 957 958 if (!AllocSizeIsValid(size)) 959 elog(ERROR, "invalid memory alloc request size %zu", size); 960 961 context->isReset = false; 962 963 ret = context->methods->alloc(context, size); 964 if (unlikely(ret == NULL)) 965 { 966 MemoryContextStats(TopMemoryContext); 967 ereport(ERROR, 968 (errcode(ERRCODE_OUT_OF_MEMORY), 969 errmsg("out of memory"), 970 errdetail("Failed on request of size %zu in memory context \"%s\".", 971 size, context->name))); 972 } 973 974 VALGRIND_MEMPOOL_ALLOC(context, ret, size); 975 976 return ret; 977 } 978 979 void * 980 palloc0(Size size) 981 { 982 /* duplicates MemoryContextAllocZero to avoid increased overhead */ 983 void *ret; 984 MemoryContext context = CurrentMemoryContext; 985 986 AssertArg(MemoryContextIsValid(context)); 987 AssertNotInCriticalSection(context); 988 989 if (!AllocSizeIsValid(size)) 990 elog(ERROR, "invalid memory alloc request size %zu", size); 991 992 context->isReset = false; 993 994 ret = context->methods->alloc(context, size); 995 if (unlikely(ret == NULL)) 996 { 997 MemoryContextStats(TopMemoryContext); 998 ereport(ERROR, 999 (errcode(ERRCODE_OUT_OF_MEMORY), 1000 errmsg("out of memory"), 1001 errdetail("Failed on request of size %zu in memory context \"%s\".", 1002 size, context->name))); 1003 } 1004 1005 VALGRIND_MEMPOOL_ALLOC(context, ret, size); 1006 1007 MemSetAligned(ret, 0, size); 1008 1009 return ret; 1010 } 1011 1012 void * 1013 palloc_extended(Size size, int flags) 1014 { 1015 /* duplicates MemoryContextAllocExtended to avoid increased overhead */ 1016 void *ret; 1017 MemoryContext context = CurrentMemoryContext; 1018 1019 AssertArg(MemoryContextIsValid(context)); 1020 AssertNotInCriticalSection(context); 1021 1022 if (((flags & MCXT_ALLOC_HUGE) != 0 && !AllocHugeSizeIsValid(size)) || 1023 ((flags & MCXT_ALLOC_HUGE) == 0 && !AllocSizeIsValid(size))) 1024 elog(ERROR, "invalid memory alloc request size %zu", size); 1025 1026 context->isReset = false; 1027 1028 ret = context->methods->alloc(context, size); 1029 if (unlikely(ret == NULL)) 1030 { 1031 if ((flags & MCXT_ALLOC_NO_OOM) == 0) 1032 { 1033 MemoryContextStats(TopMemoryContext); 1034 ereport(ERROR, 1035 (errcode(ERRCODE_OUT_OF_MEMORY), 1036 errmsg("out of memory"), 1037 errdetail("Failed on request of size %zu in memory context \"%s\".", 1038 size, context->name))); 1039 } 1040 return NULL; 1041 } 1042 1043 VALGRIND_MEMPOOL_ALLOC(context, ret, size); 1044 1045 if ((flags & MCXT_ALLOC_ZERO) != 0) 1046 MemSetAligned(ret, 0, size); 1047 1048 return ret; 1049 } 1050 1051 /* 1052 * pfree 1053 * Release an allocated chunk. 1054 */ 1055 void 1056 pfree(void *pointer) 1057 { 1058 MemoryContext context = GetMemoryChunkContext(pointer); 1059 1060 context->methods->free_p(context, pointer); 1061 VALGRIND_MEMPOOL_FREE(context, pointer); 1062 } 1063 1064 /* 1065 * repalloc 1066 * Adjust the size of a previously allocated chunk. 1067 */ 1068 void * 1069 repalloc(void *pointer, Size size) 1070 { 1071 MemoryContext context = GetMemoryChunkContext(pointer); 1072 void *ret; 1073 1074 if (!AllocSizeIsValid(size)) 1075 elog(ERROR, "invalid memory alloc request size %zu", size); 1076 1077 AssertNotInCriticalSection(context); 1078 1079 /* isReset must be false already */ 1080 Assert(!context->isReset); 1081 1082 ret = context->methods->realloc(context, pointer, size); 1083 if (unlikely(ret == NULL)) 1084 { 1085 MemoryContextStats(TopMemoryContext); 1086 ereport(ERROR, 1087 (errcode(ERRCODE_OUT_OF_MEMORY), 1088 errmsg("out of memory"), 1089 errdetail("Failed on request of size %zu in memory context \"%s\".", 1090 size, context->name))); 1091 } 1092 1093 VALGRIND_MEMPOOL_CHANGE(context, pointer, ret, size); 1094 1095 return ret; 1096 } 1097 1098 /* 1099 * MemoryContextAllocHuge 1100 * Allocate (possibly-expansive) space within the specified context. 1101 * 1102 * See considerations in comment at MaxAllocHugeSize. 1103 */ 1104 void * 1105 MemoryContextAllocHuge(MemoryContext context, Size size) 1106 { 1107 void *ret; 1108 1109 AssertArg(MemoryContextIsValid(context)); 1110 AssertNotInCriticalSection(context); 1111 1112 if (!AllocHugeSizeIsValid(size)) 1113 elog(ERROR, "invalid memory alloc request size %zu", size); 1114 1115 context->isReset = false; 1116 1117 ret = context->methods->alloc(context, size); 1118 if (unlikely(ret == NULL)) 1119 { 1120 MemoryContextStats(TopMemoryContext); 1121 ereport(ERROR, 1122 (errcode(ERRCODE_OUT_OF_MEMORY), 1123 errmsg("out of memory"), 1124 errdetail("Failed on request of size %zu in memory context \"%s\".", 1125 size, context->name))); 1126 } 1127 1128 VALGRIND_MEMPOOL_ALLOC(context, ret, size); 1129 1130 return ret; 1131 } 1132 1133 /* 1134 * repalloc_huge 1135 * Adjust the size of a previously allocated chunk, permitting a large 1136 * value. The previous allocation need not have been "huge". 1137 */ 1138 void * 1139 repalloc_huge(void *pointer, Size size) 1140 { 1141 MemoryContext context = GetMemoryChunkContext(pointer); 1142 void *ret; 1143 1144 if (!AllocHugeSizeIsValid(size)) 1145 elog(ERROR, "invalid memory alloc request size %zu", size); 1146 1147 AssertNotInCriticalSection(context); 1148 1149 /* isReset must be false already */ 1150 Assert(!context->isReset); 1151 1152 ret = context->methods->realloc(context, pointer, size); 1153 if (unlikely(ret == NULL)) 1154 { 1155 MemoryContextStats(TopMemoryContext); 1156 ereport(ERROR, 1157 (errcode(ERRCODE_OUT_OF_MEMORY), 1158 errmsg("out of memory"), 1159 errdetail("Failed on request of size %zu in memory context \"%s\".", 1160 size, context->name))); 1161 } 1162 1163 VALGRIND_MEMPOOL_CHANGE(context, pointer, ret, size); 1164 1165 return ret; 1166 } 1167 1168 /* 1169 * MemoryContextStrdup 1170 * Like strdup(), but allocate from the specified context 1171 */ 1172 char * 1173 MemoryContextStrdup(MemoryContext context, const char *string) 1174 { 1175 char *nstr; 1176 Size len = strlen(string) + 1; 1177 1178 nstr = (char *) MemoryContextAlloc(context, len); 1179 1180 memcpy(nstr, string, len); 1181 1182 return nstr; 1183 } 1184 1185 char * 1186 pstrdup(const char *in) 1187 { 1188 return MemoryContextStrdup(CurrentMemoryContext, in); 1189 } 1190 1191 /* 1192 * pnstrdup 1193 * Like pstrdup(), but append null byte to a 1194 * not-necessarily-null-terminated input string. 1195 */ 1196 char * 1197 pnstrdup(const char *in, Size len) 1198 { 1199 char *out; 1200 1201 len = strnlen(in, len); 1202 1203 out = palloc(len + 1); 1204 memcpy(out, in, len); 1205 out[len] = '\0'; 1206 1207 return out; 1208 } 1209 1210 /* 1211 * Make copy of string with all trailing newline characters removed. 1212 */ 1213 char * 1214 pchomp(const char *in) 1215 { 1216 size_t n; 1217 1218 n = strlen(in); 1219 while (n > 0 && in[n - 1] == '\n') 1220 n--; 1221 return pnstrdup(in, n); 1222 } 1223