Index: src/clientgame.mm ================================================================== --- src/clientgame.mm +++ src/clientgame.mm @@ -98,11 +98,11 @@ }; dynent * newdynent() // create a new blank player or monster { - dynent *d = (dynent *)gp()->alloc(sizeof(dynent)); + dynent *d = (dynent *)malloc(sizeof(dynent)); d->o.x = 0; d->o.y = 0; d->o.z = 0; d->yaw = 270; d->pitch = 0; @@ -184,11 +184,11 @@ void zapdynent(dynent *&d) { if (d) - gp()->dealloc(d, sizeof(dynent)); + free(d); d = NULL; }; extern int democlientnum; Index: src/commands.mm ================================================================== --- src/commands.mm +++ src/commands.mm @@ -17,12 +17,12 @@ } char * exchangestr(char *o, const char *n) { - gp()->deallocstr(o); - return newstring(n); + free(o); + return strdup(n); } // contains ALL vars/commands/aliases static OFMutableDictionary *identifiers; @@ -130,11 +130,11 @@ p--; conoutf(@"missing \"%c\"", right); return NULL; } } - char *s = newstring(word, p - word - 1); + char *s = strndup(word, p - word - 1); if (left == '(') { string t; // evaluate () exps directly, and substitute result @autoreleasepool { itoa(t, execute(@(s))); @@ -152,11 +152,11 @@ p += strcspn(p, "\n\0"); if (*p == '\"') { p++; char *word = p; p += strcspn(p, "\"\r\n\0"); - char *s = newstring(word, p - word); + char *s = strndup(word, p - word); if (*p == '\"') p++; return s; } if (*p == '(') @@ -165,11 +165,11 @@ return parseexp(p, ']'); char *word = p; p += strcspn(p, "; \t\r\n\0"); if (p - word == 0) return NULL; - return newstring(word, p - word); + return strndup(word, p - word); } OFString * lookup(OFString *n) // find value of ident referenced with $ in exp { Index: src/console.mm ================================================================== --- src/console.mm +++ src/console.mm @@ -30,14 +30,15 @@ static void conline(OFString *sf, bool highlight) // add a line to the console buffer { cline cl; - cl.cref = conlines.length() > 100 - ? conlines.pop().cref - : newstringbuf(""); // constrain the buffer size - cl.outtime = lastmillis; // for how long to keep line on screen + // constrain the buffer size + cl.cref = conlines.length() > 100 ? conlines.pop().cref + : (char *)calloc(_MAXDEFSTR, 1); + // for how long to keep line on screen + cl.outtime = lastmillis; conlines.insert(0, cl); if (highlight) // show line in a different colour, for chat etc. { cl.cref[0] = '\f'; cl.cref[1] = 0; Index: src/monster.mm ================================================================== --- src/monster.mm +++ src/monster.mm @@ -100,11 +100,11 @@ void monsterclear() // called after map start of when toggling edit mode to // reset/spawn all monsters to initial state { - loopv(monsters) gp()->dealloc(monsters[i], sizeof(dynent)); + loopv(monsters) free(monsters[i]); monsters.setsize(0); numkilled = 0; monstertotal = 0; spawnremain = 0; if (m_dmsp) { Index: src/tools.h ================================================================== --- src/tools.h +++ src/tools.h @@ -117,85 +117,26 @@ #define fast_f2nat(val) ((int)(val)) extern void endianswap(void *, int, int); -// memory pool that uses buckets and linear allocation for small objects -// VERY fast, and reasonably good memory reuse - -struct pool { - enum { POOLSIZE = 4096 }; // can be absolutely anything - enum { PTRSIZE = sizeof(char *) }; - enum { - MAXBUCKETS = 65 - }; // meaning up to size 256 on 32bit pointer systems - enum { MAXREUSESIZE = MAXBUCKETS * PTRSIZE - PTRSIZE }; - - inline size_t - bucket(size_t s) - { - return (s + PTRSIZE - 1) >> PTRBITS; - } - - enum { PTRBITS = PTRSIZE == 2 ? 1 : PTRSIZE == 4 ? 2 : 3 }; - - char *p; - size_t left; - char *blocks; - void *reuse[MAXBUCKETS]; - - pool(); - ~pool() { dealloc_block(blocks); }; - - void *alloc(size_t size); - void dealloc(void *p, size_t size); - void *realloc(void *p, size_t oldsize, size_t newsize); - - char *string(const char *s, size_t l); - - char * - string(const char *s) - { - return string(s, strlen(s)); - } - - void - deallocstr(char *s) - { - dealloc(s, strlen(s) + 1); - } - - char * - stringbuf(const char *s) - { - return string(s, _MAXDEFSTR - 1); - } - - void dealloc_block(void *b); - void allocnext(size_t allocsize); -}; - -pool *gp(); - template struct vector { T *buf; int alen; int ulen; - pool *p; vector() { - this->p = gp(); alen = 8; - buf = (T *)p->alloc(alen * sizeof(T)); + buf = (T *)malloc(alen * sizeof(T)); ulen = 0; } ~vector() { setsize(0); - p->dealloc(buf, alen * sizeof(T)); + free(buf); } vector(vector &v); void operator=(vector &v); @@ -269,13 +210,11 @@ } void realloc() { - int olen = alen; - buf = (T *)p->realloc( - buf, olen * sizeof(T), (alen *= 2) * sizeof(T)); + buf = (T *)::realloc(buf, (alen *= 2) * sizeof(T)); } T remove(int i) { @@ -304,24 +243,6 @@ #define loopvrev(v) \ if (false) { \ } else \ for (int i = (v).length() - 1; i >= 0; i--) -inline char * -newstring(const char *s) -{ - return gp()->string(s); -} - -inline char * -newstring(const char *s, size_t l) -{ - return gp()->string(s, l); -} - -inline char * -newstringbuf(const char *s) -{ - return gp()->stringbuf(s); -} - #endif Index: src/tools.mm ================================================================== --- src/tools.mm +++ src/tools.mm @@ -1,105 +1,10 @@ // implementation of generic tools #include "tools.h" #include -//////////////////////////// pool /////////////////////////// - -pool::pool() -{ - blocks = 0; - allocnext(POOLSIZE); - for (int i = 0; i < MAXBUCKETS; i++) - reuse[i] = NULL; -}; - -void * -pool::alloc(size_t size) -{ - if (size > MAXREUSESIZE) { - return malloc(size); - } else { - size = bucket(size); - void **r = (void **)reuse[size]; - if (r) { - reuse[size] = *r; - return (void *)r; - } else { - size <<= PTRBITS; - if (left < size) - allocnext(POOLSIZE); - char *r = p; - p += size; - left -= size; - return r; - }; - }; -}; - -void -pool::dealloc(void *p, size_t size) -{ - if (size > MAXREUSESIZE) { - free(p); - } else { - size = bucket(size); - if (size) // only needed for 0-size free, are there any? - { - *((void **)p) = reuse[size]; - reuse[size] = p; - }; - }; -}; - -void * -pool::realloc(void *p, size_t oldsize, size_t newsize) -{ - void *np = alloc(newsize); - if (!oldsize) - return np; - memcpy(np, p, newsize > oldsize ? oldsize : newsize); - dealloc(p, oldsize); - return np; -}; - -void -pool::dealloc_block(void *b) -{ - if (b) { - dealloc_block(*((char **)b)); - free(b); - }; -} - -void -pool::allocnext(size_t allocsize) -{ - char *b = (char *)malloc(allocsize + PTRSIZE); - *((char **)b) = blocks; - blocks = b; - p = b + PTRSIZE; - left = allocsize; -}; - -char * -pool::string(const char *s, size_t l) -{ - char *b = (char *)alloc(l + 1); - strncpy(b, s, l); - b[l] = 0; - return b; -} - -pool * -gp() // useful for global buffers that need to be initialisation order - // independant -{ - static pool *p = NULL; - return p ? p : (p = new pool()); -}; - ///////////////////////// misc tools /////////////////////// void endianswap( void *memory, int stride, int length) // little indians as storage format