summaryrefslogtreecommitdiffstats
path: root/generic/tclAlloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tclAlloc.c')
-rw-r--r--generic/tclAlloc.c70
1 files changed, 60 insertions, 10 deletions
diff --git a/generic/tclAlloc.c b/generic/tclAlloc.c
index 782a12b..ff04c2b 100644
--- a/generic/tclAlloc.c
+++ b/generic/tclAlloc.c
@@ -197,7 +197,6 @@ typedef struct Block {
#define magicNum1 u.s.magic1
#define magicNum2 u.s.magic2
#define MAGIC 0xEF
-#define blockReqSize reqSize
/*
* The following defines the minimum and maximum block sizes and the number
@@ -385,7 +384,7 @@ Block2Ptr(
blockPtr->magicNum1 = blockPtr->magicNum2 = MAGIC;
blockPtr->sourceBucket = bucket;
- blockPtr->blockReqSize = reqSize;
+ blockPtr->reqSize = reqSize;
ptr = (void *) (((char *)blockPtr) + OFFSET);
#if RCHECK
((unsigned char *)(ptr))[reqSize] = MAGIC;
@@ -405,10 +404,10 @@ Ptr2Block(
blockPtr, blockPtr->magicNum1, blockPtr->magicNum2);
}
#if RCHECK
- if (((unsigned char *) ptr)[blockPtr->blockReqSize] != MAGIC) {
+ if (((unsigned char *) ptr)[blockPtr->reqSize] != MAGIC) {
Tcl_Panic("alloc: invalid block: %p: %x %x %x",
blockPtr, blockPtr->magicNum1, blockPtr->magicNum2,
- ((unsigned char *) ptr)[blockPtr->blockReqSize]);
+ ((unsigned char *) ptr)[blockPtr->reqSize]);
}
#endif
return blockPtr;
@@ -707,14 +706,14 @@ TclpFree(
bucket = blockPtr->sourceBucket;
if (bucket == nBuckets) {
#ifdef ZIPPY_STATS
- cachePtr->totalAssigned -= blockPtr->blockReqSize;
+ cachePtr->totalAssigned -= blockPtr->reqSize;
#endif
free(blockPtr);
return;
}
#ifdef ZIPPY_STATS
- cachePtr->buckets[bucket].totalAssigned -= blockPtr->blockReqSize;
+ cachePtr->buckets[bucket].totalAssigned -= blockPtr->reqSize;
#endif
blockPtr->nextBlock = cachePtr->buckets[bucket].firstPtr;
cachePtr->buckets[bucket].firstPtr = blockPtr;
@@ -800,14 +799,14 @@ TclpRealloc(
}
if (size > min && size <= bucketInfo[bucket].blockSize) {
#ifdef ZIPPY_STATS
- cachePtr->buckets[bucket].totalAssigned -= blockPtr->blockReqSize;
+ cachePtr->buckets[bucket].totalAssigned -= blockPtr->reqSize;
cachePtr->buckets[bucket].totalAssigned += reqSize;
#endif
return Block2Ptr(blockPtr, bucket, reqSize);
}
} else if (size > MAXALLOC) {
#ifdef ZIPPY_STATS
- cachePtr->totalAssigned -= blockPtr->blockReqSize;
+ cachePtr->totalAssigned -= blockPtr->reqSize;
cachePtr->totalAssigned += reqSize;
#endif
blockPtr = realloc(blockPtr, size);
@@ -823,14 +822,65 @@ TclpRealloc(
newPtr = TclpAlloc(reqSize);
if (newPtr != NULL) {
- if (reqSize > blockPtr->blockReqSize) {
- reqSize = blockPtr->blockReqSize;
+ if (reqSize > blockPtr->reqSize) {
+ reqSize = blockPtr->reqSize;
}
memcpy(newPtr, ptr, reqSize);
TclpFree(ptr);
}
return newPtr;
}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclAllocMaximize --
+ *
+ * Given a TclpAlloc'ed pointer, it returns the maximal size that can be used
+ * by the allocated memory. This is almost always larger than the requested
+ * size, as it corresponds to the bucket's size.
+ *
+ * Results:
+ * New size.
+ *
+ *----------------------------------------------------------------------
+ */
+ unsigned int
+ TclAllocMaximize(
+ void *ptr)
+{
+ Block *blockPtr;
+ int bucket;
+ size_t oldSize, newSize;
+
+ if (allocator < aNONE) {
+ /*
+ * No info, return UINT_MAX as a signal.
+ */
+
+ return UINT_MAX;
+ }
+
+ blockPtr = Ptr2Block(ptr);
+ bucket = blockPtr->sourceBucket;
+
+ if (bucket == nBuckets) {
+ /*
+ * System malloc'ed: no info
+ */
+
+ return UINT_MAX;
+ }
+
+ oldSize = blockPtr->reqSize;
+ newSize = bucketInfo[bucket].blockSize - OFFSET - RCHECK;
+ blockPtr->reqSize = newSize;
+#if RCHECK
+ ((unsigned char *)(ptr))[newSize] = MAGIC;
+#endif
+ return newSize;
+}
+
#ifdef ZIPPY_STATS
/*