view anagram/support/myalloc.cpp @ 4:bebb2ba69e1d

maybe help with getting tex to fail properly on error
author David A. Holland
date Sat, 18 Apr 2020 17:12:17 -0400
parents 13d2b8934445
children
line wrap: on
line source

/*
 * 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