/* * MemoryContextAllocExtended * Allocate space within the specified context using the given flags. */ void * MemoryContextAllocExtended(MemoryContext context, Size size, int flags) { void *ret; AssertArg(MemoryContextIsValid(context)); AssertNotInCriticalSection(context); if (((flags & MCXT_ALLOC_HUGE) != 0 && !AllocHugeSizeIsValid(size)) || ((flags & MCXT_ALLOC_HUGE) == 0 && !AllocSizeIsValid(size))) elog(ERROR, "invalid memory alloc request size %zu", size); context->isReset = false; ret = (*context->methods->alloc) (context, size); if (ret == NULL) { if ((flags & MCXT_ALLOC_NO_OOM) == 0) { MemoryContextStats(TopMemoryContext); ereport(ERROR, (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of memory"), errdetail("Failed on request of size %zu.", size))); } return NULL; } VALGRIND_MEMPOOL_ALLOC(context, ret, size); if ((flags & MCXT_ALLOC_ZERO) != 0) MemSetAligned(ret, 0, size); return ret; }
void * palloc0(Size size) { /* duplicates MemoryContextAllocZero to avoid increased overhead */ void *ret; AssertArg(MemoryContextIsValid(CurrentMemoryContext)); AssertNotInCriticalSection(CurrentMemoryContext); if (!AllocSizeIsValid(size)) elog(ERROR, "invalid memory alloc request size %zu", size); CurrentMemoryContext->isReset = false; ret = (*CurrentMemoryContext->methods->alloc) (CurrentMemoryContext, size); if (ret == NULL) { MemoryContextStats(TopMemoryContext); ereport(ERROR, (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of memory"), errdetail("Failed on request of size %zu.", size))); } VALGRIND_MEMPOOL_ALLOC(CurrentMemoryContext, ret, size); MemSetAligned(ret, 0, size); return ret; }
/* * This is a mocked version of palloc to be used in getSpillFile(). * It returns allocated memory padded with 0x7f pattern. */ void * getSpillFile_palloc_mock(Size size) { void *ptr = MemoryContextAlloc(CurrentMemoryContext, size); MemSetAligned(ptr, 0x7f, size); return ptr; }
/* * MemoryContextAllocZero * Like MemoryContextAlloc, but clears allocated memory * * We could just call MemoryContextAlloc then clear the memory, but this * is a very common combination, so we provide the combined operation. */ void * MemoryContextAllocZero(MemoryContext context, Size size) { void *ret; AssertArg(MemoryContextIsValid(context)); AssertNotInCriticalSection(context); if (!AllocSizeIsValid(size)) elog(ERROR, "invalid memory alloc request size %zu", size); context->isReset = false; ret = (*context->methods->alloc) (context, size); if (ret == NULL) { MemoryContextStats(TopMemoryContext); ereport(ERROR, (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of memory"), errdetail("Failed on request of size %zu.", size))); } VALGRIND_MEMPOOL_ALLOC(context, ret, size); MemSetAligned(ret, 0, size); return ret; }
/* * MemoryContextAllocZero * Like MemoryContextAlloc, but clears allocated memory * * We could just call MemoryContextAlloc then clear the memory, but this * is a very common combination, so we provide the combined operation. */ void * MemoryContextAllocZeroImpl(MemoryContext context, Size size, const char* sfile, const char *sfunc, int sline) { void *ret; #ifdef PGTRACE_ENABLED StandardChunkHeader *header; #endif AssertArg(MemoryContextIsValid(context)); #ifdef CDB_PALLOC_CALLER_ID context->callerFile = sfile; context->callerLine = sline; #endif if (!AllocSizeIsValid(size)) MemoryContextError(ERRCODE_INTERNAL_ERROR, context, CDB_MCXT_WHERE(context), "invalid memory alloc request size %lu", (unsigned long)size); ret = (*context->methods.alloc) (context, size); MemSetAligned(ret, 0, size); #ifdef PGTRACE_ENABLED header = (StandardChunkHeader *) ((char *) ret - STANDARDCHUNKHEADERSIZE); PG_TRACE5(memctxt__alloc, size, header->size, 0, 0, (long) context->name); #endif return ret; }
/* * MemoryContextAllocZero * Like MemoryContextAlloc, but clears allocated memory * * We could just call MemoryContextAlloc then clear the memory, but this * is a very common combination, so we provide the combined operation. */ void * MemoryContextAllocZero(MemoryContext context, Size size) { void *ret; AssertArg(MemoryContextIsValid(context)); if (!AllocSizeIsValid(size)) elog(ERROR, "invalid memory alloc request size %lu", (unsigned long) size); context->isReset = false; ret = (*context->methods->alloc) (context, size); MemSetAligned(ret, 0, size); return ret; }
void * palloc0(Size size) { /* duplicates MemoryContextAllocZero to avoid increased overhead */ void *ret; AssertArg(MemoryContextIsValid(CurrentMemoryContext)); if (!AllocSizeIsValid(size)) elog(ERROR, "invalid memory alloc request size %lu", (unsigned long) size); CurrentMemoryContext->isReset = false; ret = (*CurrentMemoryContext->methods->alloc) (CurrentMemoryContext, size); MemSetAligned(ret, 0, size); return ret; }
/* * MemoryContextAllocZero * Like MemoryContextAlloc, but clears allocated memory * * We could just call MemoryContextAlloc then clear the memory, but this * is a very common combination, so we provide the combined operation. */ void * MemoryContextAllocZero(MemoryContext context, Size size) { void *ret; AssertArg(MemoryContextIsValid(context)); AssertNotInCriticalSection(context); if (!AllocSizeIsValid(size)) elog(ERROR, "invalid memory alloc request size %zu", size); context->isReset = false; ret = (*context->methods->alloc) (context, size); VALGRIND_MEMPOOL_ALLOC(context, ret, size); MemSetAligned(ret, 0, size); return ret; }
void * palloc0(Size size) { /* duplicates MemoryContextAllocZero to avoid increased overhead */ void *ret; AssertArg(MemoryContextIsValid(CurrentMemoryContext)); AssertNotInCriticalSection(CurrentMemoryContext); if (!AllocSizeIsValid(size)) elog(ERROR, "invalid memory alloc request size %zu", size); CurrentMemoryContext->isReset = false; ret = (*CurrentMemoryContext->methods->alloc) (CurrentMemoryContext, size); VALGRIND_MEMPOOL_ALLOC(CurrentMemoryContext, ret, size); MemSetAligned(ret, 0, size); return ret; }
HeapTuple CvtChunksToHeapTup(TupleChunkList tcList, SerTupInfo * pSerInfo) { StringInfoData serData; TupleChunkListItem tcItem; int i; HeapTuple htup; TupleChunkType tcType; AssertArg(tcList != NULL); AssertArg(tcList->p_first != NULL); AssertArg(pSerInfo != NULL); tcItem = tcList->p_first; if (tcList->num_chunks == 1) { GetChunkType(tcItem, &tcType); if (tcType == TC_EMPTY) { /* * the sender is indicating that there was a row with no attributes: * return a NULL tuple */ clearTCList(NULL, tcList); htup = heap_form_tuple(pSerInfo->tupdesc, pSerInfo->values, pSerInfo->nulls); return htup; } } /* * Dump all of the data in the tuple chunk list into a single StringInfo, * so that we can convert it into a HeapTuple. Check chunk types based on * whether there is only one chunk, or multiple chunks. * * We know roughly how much space we'll need, allocate all in one go. * */ initStringInfoOfSize(&serData, tcList->num_chunks * tcList->max_chunk_length); i = 0; do { /* Make sure that the type of this tuple chunk is correct! */ GetChunkType(tcItem, &tcType); if (i == 0) { if (tcItem->p_next == NULL) { if (tcType != TC_WHOLE) { ereport(ERROR, (errcode(ERRCODE_PROTOCOL_VIOLATION), errmsg("Single chunk's type must be TC_WHOLE."))); } } else /* tcItem->p_next != NULL */ { if (tcType != TC_PARTIAL_START) { ereport(ERROR, (errcode(ERRCODE_PROTOCOL_VIOLATION), errmsg("First chunk of collection must have type" " TC_PARTIAL_START."))); } } } else /* i > 0 */ { if (tcItem->p_next == NULL) { if (tcType != TC_PARTIAL_END) { ereport(ERROR, (errcode(ERRCODE_PROTOCOL_VIOLATION), errmsg("Last chunk of collection must have type" " TC_PARTIAL_END."))); } } else /* tcItem->p_next != NULL */ { if (tcType != TC_PARTIAL_MID) { ereport(ERROR, (errcode(ERRCODE_PROTOCOL_VIOLATION), errmsg("Last chunk of collection must have type" " TC_PARTIAL_MID."))); } } } /* Copy this chunk into the tuple data. Don't include the header! */ appendBinaryStringInfo(&serData, (const char *) GetChunkDataPtr(tcItem) + TUPLE_CHUNK_HEADER_SIZE, tcItem->chunk_length - TUPLE_CHUNK_HEADER_SIZE); /* Go to the next chunk. */ tcItem = tcItem->p_next; i++; } while (tcItem != NULL); /* we've finished with the TCList, free it now. */ clearTCList(NULL, tcList); { TupSerHeader *tshp; unsigned int datalen; unsigned int nullslen; unsigned int hoff; HeapTupleHeader t_data; char *pos = (char *)serData.data; tshp = (TupSerHeader *)pos; if ((tshp->tuplen & MEMTUP_LEAD_BIT) != 0) { uint32 tuplen = memtuple_size_from_uint32(tshp->tuplen); htup = (HeapTuple) palloc(tuplen); memcpy(htup, pos, tuplen); pos += TYPEALIGN(TUPLE_CHUNK_ALIGN,tuplen); } else { pos += sizeof(TupSerHeader); /* if the tuple had toasted elements we have to deserialize * the old slow way. */ if ((tshp->infomask & HEAP_HASEXTERNAL) != 0) { serData.cursor += sizeof(TupSerHeader); htup = DeserializeTuple(pSerInfo, &serData); /* Free up memory we used. */ pfree(serData.data); return htup; } /* reconstruct lengths of null bitmap and data part */ if (tshp->infomask & HEAP_HASNULL) nullslen = BITMAPLEN(tshp->natts); else nullslen = 0; if (tshp->tuplen < sizeof(TupSerHeader) + nullslen) ereport(ERROR, (errcode(ERRCODE_GP_INTERCONNECTION_ERROR), errmsg("Interconnect error: cannot convert chunks to a heap tuple."), errdetail("tuple len %d < nullslen %d + headersize (%d)", tshp->tuplen, nullslen, (int)sizeof(TupSerHeader)))); datalen = tshp->tuplen - sizeof(TupSerHeader) - TYPEALIGN(TUPLE_CHUNK_ALIGN, nullslen); /* determine overhead size of tuple (should match heap_form_tuple) */ hoff = offsetof(HeapTupleHeaderData, t_bits) + TYPEALIGN(TUPLE_CHUNK_ALIGN, nullslen); if (tshp->infomask & HEAP_HASOID) hoff += sizeof(Oid); hoff = MAXALIGN(hoff); /* Allocate the space in one chunk, like heap_form_tuple */ htup = (HeapTuple)palloc(HEAPTUPLESIZE + hoff + datalen); t_data = (HeapTupleHeader) ((char *)htup + HEAPTUPLESIZE); /* make sure unused header fields are zeroed */ MemSetAligned(t_data, 0, hoff); /* reconstruct the HeapTupleData fields */ htup->t_len = hoff + datalen; ItemPointerSetInvalid(&(htup->t_self)); htup->t_data = t_data; /* reconstruct the HeapTupleHeaderData fields */ ItemPointerSetInvalid(&(t_data->t_ctid)); HeapTupleHeaderSetNatts(t_data, tshp->natts); t_data->t_infomask = tshp->infomask & ~HEAP_XACT_MASK; t_data->t_infomask |= HEAP_XMIN_INVALID | HEAP_XMAX_INVALID; t_data->t_hoff = hoff; if (nullslen) { memcpy((void *)t_data->t_bits, pos, nullslen); pos += TYPEALIGN(TUPLE_CHUNK_ALIGN,nullslen); } /* does the tuple descriptor expect an OID ? Note: we don't * have to set the oid itself, just the flag! (see heap_formtuple()) */ if (pSerInfo->tupdesc->tdhasoid) /* else leave infomask = 0 */ { t_data->t_infomask |= HEAP_HASOID; } /* and now the data proper (it would be nice if we could just * point our caller into our existing buffer in-place, but * we'll leave that for another day) */ memcpy((char *)t_data + hoff, pos, datalen); } } /* Free up memory we used. */ pfree(serData.data); return htup; }