view anagram/support/myalloc.cpp @ 21:1c9dac05d040

Add lint-style FALLTHROUGH annotations to fallthrough cases. (in the parse engine and thus the output code) Document this, because the old output causes warnings with gcc10.
author David A. Holland
date Mon, 13 Jun 2022 00:04:38 -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