summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorapnadkarni <apnmbx-wits@yahoo.com>2023-05-20 15:40:17 (GMT)
committerapnadkarni <apnmbx-wits@yahoo.com>2023-05-20 15:40:17 (GMT)
commit96d441c29a2a47269655285a02c546765c163fd2 (patch)
tree6906aa04fcb87740b514d40f1b4c83435a53a645
parent1b8701ee3d55320b42676e77ce32c04950facee6 (diff)
downloadtcl-96d441c29a2a47269655285a02c546765c163fd2.zip
tcl-96d441c29a2a47269655285a02c546765c163fd2.tar.gz
tcl-96d441c29a2a47269655285a02c546765c163fd2.tar.bz2
Minor refactor to combine alloc/realloc
-rw-r--r--generic/tclCkalloc.c84
-rw-r--r--generic/tclInt.h17
-rw-r--r--generic/tclStringObj.c8
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;
}