diff options
Diffstat (limited to 'generic/tclAlloc.c')
| -rw-r--r-- | generic/tclAlloc.c | 125 | 
1 files changed, 57 insertions, 68 deletions
| diff --git a/generic/tclAlloc.c b/generic/tclAlloc.c index b51084d..64df1a2 100644 --- a/generic/tclAlloc.c +++ b/generic/tclAlloc.c @@ -14,8 +14,6 @@   *   * See the file "license.terms" for information on usage and redistribution of   * this file, and for a DISCLAIMER OF ALL WARRANTIES. - * - * RCS: @(#) $Id: tclAlloc.c,v 1.23 2005/11/01 15:30:52 dkf Exp $   */  /* @@ -28,19 +26,13 @@  #if USE_TCLALLOC -#ifdef TCL_DEBUG -#   define DEBUG -/* #define MSTATS */ -#   define RCHECK -#endif -  /*   * We should really make use of AC_CHECK_TYPE(caddr_t) here, but it can wait   * until Tcl uses config.h properly.   */ -#if defined(_MSC_VER) || defined(__MINGW32__) || defined(__BORLANDC__) -typedef unsigned long caddr_t; +#if defined(_MSC_VER) || defined(__MSVCRT__) || defined(__BORLANDC__) +typedef size_t caddr_t;  #endif  /* @@ -55,17 +47,17 @@ typedef unsigned long caddr_t;   */  union overhead { -    union overhead *next;	/* when free */ -    unsigned char padding[8];	/* Ensure the structure is 8-byte aligned. */ +    union overhead *next;		/* when free */ +    unsigned char padding[TCL_ALLOCALIGN];	/* align struct to TCL_ALLOCALIGN bytes */      struct { -	unsigned char magic0;	/* magic number */ -	unsigned char index;	/* bucket # */ -	unsigned char unused;	/* unused */ -	unsigned char magic1;	/* other magic number */ -#ifdef RCHECK -	unsigned short rmagic;	/* range magic number */ -	unsigned long size;	/* actual block size */ -	unsigned short unused2;	/* padding to 8-byte align */ +	unsigned char magic0;		/* magic number */ +	unsigned char index;		/* bucket # */ +	unsigned char unused;		/* unused */ +	unsigned char magic1;		/* other magic number */ +#ifndef NDEBUG +	unsigned short rmagic;		/* range magic number */ +	size_t size;		/* actual block size */ +	unsigned short unused2;		/* padding to 8-byte align */  #endif      } ovu;  #define overMagic0	ovu.magic0 @@ -79,8 +71,8 @@ union overhead {  #define MAGIC		0xef	/* magic # on accounting info */  #define RMAGIC		0x5555	/* magic # on range info */ -#ifdef RCHECK -#define	RSLOP		sizeof (unsigned short) +#ifndef NDEBUG +#define	RSLOP		sizeof(unsigned short)  #else  #define	RSLOP		0  #endif @@ -96,11 +88,12 @@ union overhead {  /*   * nextf[i] is the pointer to the next free block of size 2^(i+3). The - * smallest allocatable block is 8 bytes. The overhead information precedes - * the data area returned to the user. + * smallest allocatable block is MINBLOCK bytes. The overhead information + * precedes the data area returned to the user.   */ -#define NBUCKETS	13 +#define MINBLOCK	((sizeof(union overhead) + (TCL_ALLOCALIGN-1)) & ~(TCL_ALLOCALIGN-1)) +#define NBUCKETS	(13 - (MINBLOCK >> 4))  #define MAXMALLOC	(1<<(NBUCKETS+2))  static union overhead *nextf[NBUCKETS]; @@ -140,11 +133,10 @@ static int allocInit = 0;   * a given block size.   */ -static	unsigned int numMallocs[NBUCKETS+1]; -#include <stdio.h> +static	size_t numMallocs[NBUCKETS+1];  #endif -#if defined(DEBUG) || defined(RCHECK) +#if !defined(NDEBUG)  #define	ASSERT(p)	if (!(p)) Tcl_Panic(# p)  #define RANGE_ASSERT(p) if (!(p)) Tcl_Panic(# p)  #else @@ -156,7 +148,7 @@ static	unsigned int numMallocs[NBUCKETS+1];   * Prototypes for functions used only in this file.   */ -static void 		MoreCore(int bucket); +static void		MoreCore(size_t bucket);  /*   *------------------------------------------------------------------------- @@ -211,7 +203,7 @@ TclInitAlloc(void)  void  TclFinalizeAllocSubsystem(void)  { -    int i; +    unsigned int i;      struct block *blockPtr, *nextPtr;      Tcl_MutexLock(allocMutexPtr); @@ -262,9 +254,9 @@ TclpAlloc(      unsigned int numBytes)	/* Number of bytes to allocate. */  {      register union overhead *overPtr; -    register long bucket; +    register size_t bucket;      register unsigned amount; -    struct block *bigBlockPtr; +    struct block *bigBlockPtr = NULL;      if (!allocInit) {  	/* @@ -280,9 +272,11 @@ TclpAlloc(       * First the simple case: we simple allocate big blocks directly.       */ -    if (numBytes + OVERHEAD >= MAXMALLOC) { -	bigBlockPtr = (struct block *) TclpSysAlloc((unsigned) -		(sizeof(struct block) + OVERHEAD + numBytes), 0); +    if (numBytes >= MAXMALLOC - OVERHEAD) { +	if (numBytes <= UINT_MAX - OVERHEAD -sizeof(struct block)) { +	    bigBlockPtr = (struct block *) TclpSysAlloc((unsigned) +		    (sizeof(struct block) + OVERHEAD + numBytes), 0); +	}  	if (bigBlockPtr == NULL) {  	    Tcl_MutexUnlock(allocMutexPtr);  	    return NULL; @@ -299,7 +293,7 @@ TclpAlloc(  	numMallocs[NBUCKETS]++;  #endif -#ifdef RCHECK +#ifndef NDEBUG  	/*  	 * Record allocated size of block and bound space with magic numbers.  	 */ @@ -319,13 +313,8 @@ TclpAlloc(       * for accounting.       */ -#ifndef RCHECK -    amount = 8;		/* size of first bucket */ -    bucket = 0; -#else -    amount = 16;	/* size of first bucket */ -    bucket = 1; -#endif +    amount = MINBLOCK;		/* size of first bucket */ +    bucket = MINBLOCK >> 4;      while (numBytes + OVERHEAD > amount) {  	amount <<= 1; @@ -362,7 +351,7 @@ TclpAlloc(      numMallocs[bucket]++;  #endif -#ifdef RCHECK +#ifndef NDEBUG      /*       * Record allocated size of block and bound space with magic numbers.       */ @@ -396,12 +385,12 @@ TclpAlloc(  static void  MoreCore( -    int bucket)			/* What bucket to allocat to. */ +    size_t bucket)	/* What bucket to allocate to. */  {      register union overhead *overPtr; -    register long size;		/* size of desired block */ -    long amount;		/* amount to allocate */ -    int numBlocks;		/* how many blocks we get */ +    register size_t size;	/* size of desired block */ +    size_t amount;		/* amount to allocate */ +    size_t numBlocks;		/* how many blocks we get */      struct block *blockPtr;      /* @@ -409,14 +398,14 @@ MoreCore(       * VAX, I think) or for a negative arg.       */ -    size = 1 << (bucket + 3); +    size = ((size_t)1) << (bucket + 3);      ASSERT(size > 0);      amount = MAXMALLOC;      numBlocks = amount / size;      ASSERT(numBlocks*size == amount); -    blockPtr = (struct block *) TclpSysAlloc((unsigned) +    blockPtr = (struct block *) TclpSysAlloc(  	    (sizeof(struct block) + amount), 1);      /* no more room! */      if (blockPtr == NULL) { @@ -459,7 +448,7 @@ void  TclpFree(      char *oldPtr)		/* Pointer to memory to free. */  { -    register long size; +    register size_t size;      register union overhead *overPtr;      struct block *bigBlockPtr; @@ -468,7 +457,7 @@ TclpFree(      }      Tcl_MutexLock(allocMutexPtr); -    overPtr = (union overhead *)((caddr_t)oldPtr - sizeof (union overhead)); +    overPtr = (union overhead *)((caddr_t)oldPtr - sizeof(union overhead));      ASSERT(overPtr->overMagic0 == MAGIC);	/* make sure it was in use */      ASSERT(overPtr->overMagic1 == MAGIC); @@ -529,7 +518,7 @@ TclpRealloc(      union overhead *overPtr;      struct block *bigBlockPtr;      int expensive; -    unsigned long maxSize; +    size_t maxSize;      if (oldPtr == NULL) {  	return TclpAlloc(numBytes); @@ -537,7 +526,7 @@ TclpRealloc(      Tcl_MutexLock(allocMutexPtr); -    overPtr = (union overhead *)((caddr_t)oldPtr - sizeof (union overhead)); +    overPtr = (union overhead *)((caddr_t)oldPtr - sizeof(union overhead));      ASSERT(overPtr->overMagic0 == MAGIC);	/* make sure it was in use */      ASSERT(overPtr->overMagic1 == MAGIC); @@ -582,7 +571,7 @@ TclpRealloc(  	numMallocs[NBUCKETS]++;  #endif -#ifdef RCHECK +#ifndef NDEBUG  	/*  	 * Record allocated size of block and update magic number bounds.  	 */ @@ -615,7 +604,7 @@ TclpRealloc(  	if (maxSize < numBytes) {  	    numBytes = maxSize;  	} -	memcpy((VOID *) newPtr, (VOID *) oldPtr, (size_t) numBytes); +	memcpy(newPtr, oldPtr, (size_t) numBytes);  	TclpFree(oldPtr);  	return newPtr;      } @@ -624,7 +613,7 @@ TclpRealloc(       * Ok, we don't have to copy, it fits as-is       */ -#ifdef RCHECK +#ifndef NDEBUG      overPtr->realBlockSize = (numBytes + RSLOP - 1) & ~(RSLOP - 1);      BLOCK_END(overPtr) = RMAGIC;  #endif @@ -656,30 +645,30 @@ void  mstats(      char *s)			/* Where to write info. */  { -    register int i, j; +    register unsigned int i, j;      register union overhead *overPtr; -    int totalFree = 0, totalUsed = 0; +    size_t totalFree = 0, totalUsed = 0;      Tcl_MutexLock(allocMutexPtr);      fprintf(stderr, "Memory allocation statistics %s\nTclpFree:\t", s);      for (i = 0; i < NBUCKETS; i++) {  	for (j=0, overPtr=nextf[i]; overPtr; overPtr=overPtr->next, j++) { -	    fprintf(stderr, " %d", j); +	    fprintf(stderr, " %u", j);  	} -	totalFree += j * (1 << (i + 3)); +	totalFree += ((size_t)j) * (1 << (i + 3));      }      fprintf(stderr, "\nused:\t");      for (i = 0; i < NBUCKETS; i++) { -	fprintf(stderr, " %d", numMallocs[i]); +	fprintf(stderr, " %" TCL_LL_MODIFIER "d", (Tcl_WideInt)numMallocs[i]);  	totalUsed += numMallocs[i] * (1 << (i + 3));      } -    fprintf(stderr, "\n\tTotal small in use: %d, total free: %d\n", -	    totalUsed, totalFree); -    fprintf(stderr, "\n\tNumber of big (>%d) blocks in use: %d\n", -	    MAXMALLOC, numMallocs[NBUCKETS]); +    fprintf(stderr, "\n\tTotal small in use: %" TCL_LL_MODIFIER "d, total free: %" TCL_LL_MODIFIER "d\n", +	(Tcl_WideInt)totalUsed, (Tcl_WideInt)totalFree); +    fprintf(stderr, "\n\tNumber of big (>%d) blocks in use: %" TCL_LL_MODIFIER "d\n", +	    MAXMALLOC, (Tcl_WideInt)numMallocs[NBUCKETS]);      Tcl_MutexUnlock(allocMutexPtr);  } @@ -707,7 +696,7 @@ char *  TclpAlloc(      unsigned int numBytes)	/* Number of bytes to allocate. */  { -    return (char*) malloc(numBytes); +    return (char *) malloc(numBytes);  }  /* @@ -755,7 +744,7 @@ TclpRealloc(      char *oldPtr,		/* Pointer to alloced block. */      unsigned int numBytes)	/* New size of memory. */  { -    return (char*) realloc(oldPtr, numBytes); +    return (char *) realloc(oldPtr, numBytes);  }  #endif /* !USE_TCLALLOC */ | 
