summaryrefslogtreecommitdiffstats
path: root/src/corelib/global/qalloc.h
blob: 9d40f4261d30a105a91e0d10227ea8710fc27027 (plain)
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
// Copyright (C) 2025 Aurélien Brooke <aurelien@bahiasoft.fr>// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only#ifndef QALLOC_H#define QALLOC_H//// W A R N I N G// -------------//// This file is not part of the Qt API. It exists purely as an// implementation detail. This header file may change from version to// version without notice, or even be removed.//// We mean it.//#include <QtCore/qtconfigmacros.h>#include <QtCore/qtcoreexports.h>#include <QtCore/qnumeric.h>#include <QtCore/qtypeinfo.h>#include <cstddef> QT_BEGIN_NAMESPACE namespace QtPrivate {/** * \internal * \return the size that would be allocated for the given request. * * Computes the actual allocation size for \a allocSize and \a alignment, * as determined by the active allocator, without performing the allocation. * * In practice, it only returns nonzero when using jemalloc. */ Q_CORE_EXPORT Q_DECL_PURE_FUNCTION size_texpectedAllocSize(size_t allocSize,size_t alignment) noexcept;/** * \internal * \brief Computes the best allocation size for the requested minimum capacity, and updates capacity. * * Computes the allocation size starting from \a headerSize and a requested minimum capacity in \a capacity, * multiplied by the \a elementSize and adjusted by the \a unusedCapacity. * The final capacity is written back into \a capacity. * The \a headerSize and \a unusedCapacity values are not included in the final reported capacity. */inlinesize_tfittedAllocSize(size_t headerSize,size_t*capacity,size_t elementSize,size_t unusedCapacity,size_t alignment) noexcept {size_t totalCapacity =0;// = capacity + unusedCapacityif(Q_UNLIKELY(qAddOverflow(*capacity, unusedCapacity, &totalCapacity)))return0;// or handle errorsize_t payloadSize =0;// = totalCapacity * elementSizeif(Q_UNLIKELY(qMulOverflow(totalCapacity, elementSize, &payloadSize)))return0;size_t allocSize =0;// = headerSize + payloadSizeif(Q_UNLIKELY(qAddOverflow(headerSize, payloadSize, &allocSize)))return0;if(size_t fittedSize =expectedAllocSize(allocSize, alignment); fittedSize !=0) {// no need to overflow/underflow check from fittedSize,// since allocSize <= fittedSize <= SIZE_T_MAX*capacity = (fittedSize - headerSize) / elementSize - unusedCapacity;size_t newTotalCapacity = *capacity + unusedCapacity;size_t newPayloadSize = newTotalCapacity * elementSize;return headerSize + newPayloadSize;}return allocSize;}#ifdef Q_CC_GNU__attribute__((malloc))#endifinlinevoid*fittedMalloc(size_t headerSize,size_t*capacity,size_t elementSize,size_t unusedCapacity) noexcept {size_t allocSize =fittedAllocSize(headerSize, capacity, elementSize, unusedCapacity,alignof(std::max_align_t));if(Q_LIKELY(allocSize !=0))returnmalloc(allocSize);elsereturnnullptr;}inlinevoid*fittedMalloc(size_t headerSize, qsizetype *capacity,size_t elementSize,size_t unusedCapacity =0) noexcept {size_t uCapacity =size_t(*capacity);void*ptr =fittedMalloc(headerSize, &uCapacity, elementSize, unusedCapacity);*capacity =qsizetype(uCapacity);return ptr;}inlinevoid*fittedRealloc(void*ptr,size_t headerSize,size_t*capacity,size_t elementSize,size_t unusedCapacity) noexcept {size_t newCapacity = *capacity;size_t allocSize =fittedAllocSize(headerSize, &newCapacity, elementSize, unusedCapacity,alignof(std::max_align_t));if(Q_LIKELY(allocSize !=0)) {void*newPtr =realloc(ptr, allocSize);if(newPtr)*capacity = newCapacity;return newPtr;}else{returnnullptr;}}inlinevoid*fittedRealloc(void*ptr,size_t headerSize, qsizetype *capacity,size_t elementSize,size_t unusedCapacity =0) noexcept {size_t uCapacity =size_t(*capacity); ptr =fittedRealloc(ptr, headerSize, &uCapacity, elementSize, unusedCapacity);*capacity =qsizetype(uCapacity);return ptr;} Q_CORE_EXPORT voidsizedFree(void*ptr,size_t allocSize) noexcept;inlinevoidsizedFree(void*ptr,size_t capacity,size_t elementSize) noexcept {sizedFree(ptr, capacity * elementSize);}}// namespace QtPrivate QT_END_NAMESPACE #endif// QALLOC_H
close