diff options
| author | apnadkarni <apnmbx-wits@yahoo.com> | 2023-05-20 15:40:17 (GMT) |
|---|---|---|
| committer | apnadkarni <apnmbx-wits@yahoo.com> | 2023-05-20 15:40:17 (GMT) |
| commit | 96d441c29a2a47269655285a02c546765c163fd2 (patch) | |
| tree | 6906aa04fcb87740b514d40f1b4c83435a53a645 | |
| parent | 1b8701ee3d55320b42676e77ce32c04950facee6 (diff) | |
| download | tcl-96d441c29a2a47269655285a02c546765c163fd2.zip tcl-96d441c29a2a47269655285a02c546765c163fd2.tar.gz tcl-96d441c29a2a47269655285a02c546765c163fd2.tar.bz2 | |
Minor refactor to combine alloc/realloc
| -rw-r--r-- | generic/tclCkalloc.c | 84 | ||||
| -rw-r--r-- | generic/tclInt.h | 17 | ||||
| -rw-r--r-- | generic/tclStringObj.c | 8 |
3 files changed, 37 insertions, 72 deletions
diff --git a/generic/tclCkalloc.c b/generic/tclCkalloc.c index 6aabf9f..106a62c 100644 --- a/generic/tclCkalloc.c +++ b/generic/tclCkalloc.c @@ -1237,64 +1237,6 @@ TclDumpMemoryInfo( /* *------------------------------------------------------------------------ * - * TclAttemptAllocElemsEx -- - * - * Attempts to allocate memory of the requested size plus some more for - * future growth. The amount of allocation is adjusted depending on - * on failure. - * - * Results: - * Pointer to allocated memory block which is at least large enough - * to hold elemCount elements or NULL if allocation failed. - * - *------------------------------------------------------------------------ - */ -void * -TclAttemptAllocElemsEx( - Tcl_Size elemCount, /* Allocation will store at least these many... */ - Tcl_Size elemSize, /* ...elements of this size */ - Tcl_Size leadSize, /* Additional leading space in bytes */ - Tcl_Size *capacityPtr) /* OUTPUT: Actual capacity is stored - here if non-NULL. Only modified on success */ -{ - void *ptr; - Tcl_Size limit; - Tcl_Size attempt; - - assert(elemCount > 0); - assert(elemSize > 0); - assert(elemSize < TCL_SIZE_MAX); - assert(leadSize > 0); - assert(leadSize < TCL_SIZE_MAX); - - limit = (TCL_SIZE_MAX - leadSize) / elemSize; - if (elemCount > limit) { - return NULL; - } - /* Loop trying for extra space, reducing request each time */ - attempt = TclUpsizeAlloc(0, elemCount, limit); - ptr = NULL; - while (attempt > elemCount) { - ptr = Tcl_AttemptAlloc(leadSize + attempt*elemSize); - if (ptr) { - break; - } - attempt = TclUpsizeRetry(elemCount, attempt); - } - /* Try exact size as a last resort */ - if (ptr == NULL) { - attempt = elemCount; - ptr = Tcl_AttemptAlloc(leadSize + attempt*elemSize); - } - if (ptr && capacityPtr) { - *capacityPtr = attempt; - } - return ptr; -} - -/* - *------------------------------------------------------------------------ - * * TclAllocElemsEx -- * * See TclAttemptAllocElemsEx. This function differs in that it panics @@ -1317,8 +1259,8 @@ TclAllocElemsEx( Tcl_Size *capacityPtr) /* OUTPUT: Actual capacity is stored here if non-NULL. Only modified on success */ { - void *ptr = TclAttemptAllocElemsEx( - elemCount, elemSize, leadSize, capacityPtr); + void *ptr = TclAttemptReallocElemsEx( + NULL, elemCount, elemSize, leadSize, capacityPtr); if (ptr == NULL) { Tcl_Panic("Failed to allocate %" TCL_SIZE_MODIFIER "d elements of size %" TCL_SIZE_MODIFIER "d bytes.", @@ -1333,9 +1275,10 @@ TclAllocElemsEx( * * TclAttemptReallocElemsEx -- * - * Attempts to reallocate memory of the requested size plus some more for - * future growth. The amount of reallocation is adjusted depending on - * on failure. + * Attempts to allocate (oldPtr == NULL) or reallocate memory of the + * requested size plus some more for future growth. The amount of + * reallocation is adjusted depending on on failure. + * * * Results: * Pointer to allocated memory block which is at least as large @@ -1345,7 +1288,8 @@ TclAllocElemsEx( */ void * TclAttemptReallocElemsEx( - void *oldPtr, /* Pointer to memory block to reallocate */ + void *oldPtr, /* Pointer to memory block to reallocate or + * NULL to indicate this is a new allocation */ Tcl_Size elemCount, /* Allocation will store at least these many... */ Tcl_Size elemSize, /* ...elements of this size */ Tcl_Size leadSize, /* Additional leading space in bytes */ @@ -1370,7 +1314,11 @@ TclAttemptReallocElemsEx( attempt = TclUpsizeAlloc(0, elemCount, limit); ptr = NULL; while (attempt > elemCount) { - ptr = Tcl_AttemptRealloc(oldPtr, leadSize + attempt*elemSize); + if (oldPtr) { + ptr = Tcl_AttemptRealloc(oldPtr, leadSize + attempt * elemSize); + } else { + ptr = Tcl_AttemptAlloc(leadSize + attempt * elemSize); + } if (ptr) { break; } @@ -1379,7 +1327,11 @@ TclAttemptReallocElemsEx( /* Try exact size as a last resort */ if (ptr == NULL) { attempt = elemCount; - ptr = Tcl_AttemptRealloc(oldPtr, leadSize + attempt*elemSize); + if (oldPtr) { + ptr = Tcl_AttemptRealloc(oldPtr, leadSize + attempt * elemSize); + } else { + ptr = Tcl_AttemptAlloc(leadSize + attempt * elemSize); + } } if (ptr && capacityPtr) { *capacityPtr = attempt; diff --git a/generic/tclInt.h b/generic/tclInt.h index f2123b5..bf42f6a 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -2909,23 +2909,34 @@ static inline Tcl_Size TclUpsizeRetry(Tcl_Size needed, Tcl_Size lastAttempt) { } MODULE_SCOPE void *TclAllocElemsEx(Tcl_Size elemCount, Tcl_Size elemSize, Tcl_Size leadSize, Tcl_Size *capacityPtr); -MODULE_SCOPE void *TclAttemptAllocElemsEx(Tcl_Size elemCount, Tcl_Size elemSize, - Tcl_Size leadSize, Tcl_Size *capacityPtr); MODULE_SCOPE void *TclReallocElemsEx(void *oldPtr, Tcl_Size elemCount, Tcl_Size elemSize, Tcl_Size leadSize, Tcl_Size *capacityPtr); MODULE_SCOPE void *TclAttemptReallocElemsEx(void *oldPtr, Tcl_Size elemCount, Tcl_Size elemSize, Tcl_Size leadSize, Tcl_Size *capacityPtr); +/* Alloc elemCount elements of size elemSize with leadSize header + * returning actual capacity (in elements) in *capacityPtr. */ +static inline void *TclAttemptAllocElemsEx(Tcl_Size elemCount, Tcl_Size elemSize, + Tcl_Size leadSize, Tcl_Size *capacityPtr) { + return TclAttemptReallocElemsEx( + NULL, elemCount, elemSize, leadSize, capacityPtr); +} +/* Alloc numByte bytes, returning actual capacity in *capacityPtr. */ static inline void *TclAllocEx(Tcl_Size numBytes, Tcl_Size *capacityPtr) { return TclAllocElemsEx(numBytes, 1, 0, capacityPtr); } -static inline void *TclAttemptAllocEx(Tcl_Size numBytes, Tcl_Size *capacityPtr) { +/* Alloc numByte bytes, returning actual capacity in *capacityPtr. */ +static inline void * +TclAttemptAllocEx(Tcl_Size numBytes, Tcl_Size *capacityPtr) +{ return TclAttemptAllocElemsEx(numBytes, 1, 0, capacityPtr); } +/* Realloc numByte bytes, returning actual capacity in *capacityPtr. */ static inline void *TclReallocEx(void *oldPtr, Tcl_Size numBytes, Tcl_Size *capacityPtr) { return TclReallocElemsEx(oldPtr, numBytes, 1, 0, capacityPtr); } +/* Realloc numByte bytes, returning actual capacity in *capacityPtr. */ static inline void *TclAttemptReallocEx(void *oldPtr, Tcl_Size numBytes, Tcl_Size *capacityPtr) { return TclAttemptReallocElemsEx(oldPtr, numBytes, 1, 0, capacityPtr); } diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index 0da5f04..5864ebc 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -157,8 +157,7 @@ GrowStringBuffer( */ if (flag == 0 || stringPtr->allocated > 0) { ptr = (char *)TclReallocEx(objPtr->bytes, needed, &capacity); - } - else { + } else { /* Allocate exact size */ ptr = (char *)Tcl_Realloc(objPtr->bytes, needed); capacity = needed; @@ -197,7 +196,10 @@ GrowUnicodeBuffer( maxChars -= 1; /* End nul not included */ } else { - /* First allocation - just big enough */ + /* + * First allocation - just big enough. Note needed does + * not include terminating nul but STRING_SIZE does + */ stringPtr = (String *)Tcl_Realloc(stringPtr, STRING_SIZE(needed)); maxChars = needed; } |
