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