Mercurial > ~dholland > hg > ag > index.cgi
diff anagram/support/myalloc.cpp @ 0:13d2b8934445
Import AnaGram (near-)release tree into Mercurial.
author | David A. Holland |
---|---|
date | Sat, 22 Dec 2007 17:52:45 -0500 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/anagram/support/myalloc.cpp Sat Dec 22 17:52:45 2007 -0500 @@ -0,0 +1,240 @@ +/* + * AnaGram, A System for Syntax Directed Programming + * Copyright 1993-1999 Parsifal Software. All Rights Reserved. + * See the file COPYING for license and usage terms. + * + * myalloc.cpp - memory allocation wrappers + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "port.h" + +#include "assert.h" +#include "myalloc.h" + +//#define INCLUDE_LOGGING +#include "log.h" + + +typedef struct { + unsigned size, comp; +} fence; + + +static void check_mem(void *p) { + if (p == NULL) { + bailOut("Out of memory"); + } +} + +static fence make_fence(int n) { + fence f; + n -= 2*sizeof(fence); + f.size = n; + f.comp = ~n; + return f; +} + + +static char longjmp_msg[128]; + +void *myalloc(unsigned n) { + fence *ptr; + fence *top, *bot; + + if (n == 0) { + return NULL; + } + //myallocs++; + n += 2*sizeof(fence); + if (n&1) { + n++; + } + bot = ptr = (fence *) malloc(n); + check_mem(ptr); + ptr = (bot + 1); + top = (fence *)((char *)bot + n - sizeof(fence)); + //*top = *bot = make_fence(n); + *bot = make_fence(n); + memcpy(top, bot, sizeof(fence)); + //myallocBytes += n; + return (void *) ptr; +} + +void *myzalloc(unsigned n, unsigned size) { + unsigned k = n*size; + fence *ptr = (fence *) myalloc(k); + memset(ptr, 0, k); + + return ptr; +} + +static void *ersatz_realloc(void *bot, int n) { + int m = *(int *) bot + 2*sizeof(fence); + void *old_bot = bot; + + bot = malloc(n); + if (bot == NULL) { + return bot; + } + if (n < m) { + m = n; + } + memmove(bot, old_bot, m); + free(old_bot); + return bot; +} + +void *myrealloc(void *p, unsigned n, const char *file, int line) { + fence *ptr; + fence *top, *bot = (fence *) p; // , *oldbot; + + if (p == NULL) { + ptr = (fence *) myalloc(n); + return ptr; + } + ptr_ng(p, file, line); + n += 2*sizeof(fence); + if (n&1) { + n++; + } + bot--; + if (n > 64000) { + bot = (fence *) ersatz_realloc(bot, n); + } + else { + //myfreeBytes += bot->size; + bot = (fence *) realloc(bot, n); + //myallocBytes += n; + } + check_mem(bot); + + ptr = (bot + 1); + top = (fence *)((char *)bot + n - sizeof(fence)); + //*top = *bot = make_fence(n); + *bot = make_fence(n); + memcpy(top, bot, sizeof(fence)); + return ptr; +} + +char *mystrdup(const char *s) { + assert(s != NULL); + int k = strlen(s) + 1; + char *c = ALLOCATE(k, char); + + return strcpy(c,s); +} + +static int fence_ng(const void *f) { + if (f == NULL) { + return 3; + } + const fence *bot=(const fence *)f-1; + if (bot->size != ~bot->comp) { + return 1; + } + const fence *top = (const fence *) ((const char *)f + bot->size); + + //if (bot->size != top->size) { + // return 2; + //} + //if (top->size != ~top->comp) { + // return 2; + //} + if (memcmp(top, bot, sizeof(fence))) { + return 2; + } + + return 0; +} + + + +int ptr_ok(void *f) { + fence *bot=(fence *)f-1, *top; + + if (f == NULL) { + return 0; + } + if (bot->size != ~bot->comp) { + return 0; + } + top = (fence *)((char *)f + bot->size); + if ((bot->size ^ top->size) | (bot->comp ^ top->comp)) { + return 0; + } + return 1; +} + + +void ptr_ng(const void *ptr, const char *file, int line) { + int flag = fence_ng(ptr); + if (flag) { + flag = " BTN"[flag]; + } + if (!flag || no_assertions) { + return; + } + no_assertions = 1; + snprintf(longjmp_msg, sizeof(longjmp_msg), + "AnaGram internal error: bad pointer %p (%c), %s line %d", + ptr, flag, file, line); + LOGSECTION("Bad array fence"); + LOGSTACK; + LOGV(longjmp_msg); + bailOut(longjmp_msg); +} + +void size_ok(const void *ptr, unsigned n, const char *file, int line) { + const fence *fp = (const fence *) ptr; + check_stack; + fp--; + if (n <= fp->size || no_assertions) { + return; + } + no_assertions = 1; + snprintf(longjmp_msg, sizeof(longjmp_msg), + "AnaGram internal error: bad size %u, %s line %d", n, file, line); + LOGSECTION("size_ok"); + LOGSTACK; + LOGV(longjmp_msg); + bailOut(longjmp_msg); +} + +void myfree(void *ptr, const char *file, int line) { + if (ptr == NULL) { + return; + } + //myfrees++; + ptr_ng(ptr, file, line); + fence *base = (fence *)ptr - 1; + //myfreeBytes += base->size + 2*sizeof(fence); + base->size = 0; + free(base); +} + +#if 0 +void *operator new(size_t size) { + //newCalls++; + void *pointer = myalloc(size); + return pointer; +} + +void operator delete(void *p) { + //deleteCalls++; + DEALLOCATE(p); +} + +void *operator new[](size_t size) { + //newArrayCalls++; + void *pointer = myalloc(size); + return pointer; +} + +void operator delete[](void *p) { + //deleteArrayCalls++; + DEALLOCATE(p); +} +#endif