aboutsummaryrefslogtreecommitdiff
path: root/code/tools/lcc/src/alloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'code/tools/lcc/src/alloc.c')
-rw-r--r--code/tools/lcc/src/alloc.c94
1 files changed, 94 insertions, 0 deletions
diff --git a/code/tools/lcc/src/alloc.c b/code/tools/lcc/src/alloc.c
new file mode 100644
index 0000000..e0566df
--- /dev/null
+++ b/code/tools/lcc/src/alloc.c
@@ -0,0 +1,94 @@
+#include "c.h"
+struct block {
+ struct block *next;
+ char *limit;
+ char *avail;
+};
+union align {
+ long l;
+ char *p;
+ double d;
+ int (*f)(void);
+};
+union header {
+ struct block b;
+ union align a;
+};
+#ifdef PURIFY
+union header *arena[3];
+
+void *allocate(unsigned long n, unsigned a) {
+ union header *new = malloc(sizeof *new + n);
+
+ assert(a < NELEMS(arena));
+ if (new == NULL) {
+ error("insufficient memory\n");
+ exit(1);
+ }
+ new->b.next = (void *)arena[a];
+ arena[a] = new;
+ return new + 1;
+}
+
+void deallocate(unsigned a) {
+ union header *p, *q;
+
+ assert(a < NELEMS(arena));
+ for (p = arena[a]; p; p = q) {
+ q = (void *)p->b.next;
+ free(p);
+ }
+ arena[a] = NULL;
+}
+
+void *newarray(unsigned long m, unsigned long n, unsigned a) {
+ return allocate(m*n, a);
+}
+#else
+static struct block
+ first[] = { { NULL }, { NULL }, { NULL } },
+ *arena[] = { &first[0], &first[1], &first[2] };
+static struct block *freeblocks;
+
+void *allocate(unsigned long n, unsigned a) {
+ struct block *ap;
+
+ assert(a < NELEMS(arena));
+ assert(n > 0);
+ ap = arena[a];
+ n = roundup(n, sizeof (union align));
+ while (n > ap->limit - ap->avail) {
+ if ((ap->next = freeblocks) != NULL) {
+ freeblocks = freeblocks->next;
+ ap = ap->next;
+ } else
+ {
+ unsigned m = sizeof (union header) + n + roundup(10*1024, sizeof (union align));
+ ap->next = malloc(m);
+ ap = ap->next;
+ if (ap == NULL) {
+ error("insufficient memory\n");
+ exit(1);
+ }
+ ap->limit = (char *)ap + m;
+ }
+ ap->avail = (char *)((union header *)ap + 1);
+ ap->next = NULL;
+ arena[a] = ap;
+
+ }
+ ap->avail += n;
+ return ap->avail - n;
+}
+
+void *newarray(unsigned long m, unsigned long n, unsigned a) {
+ return allocate(m*n, a);
+}
+void deallocate(unsigned a) {
+ assert(a < NELEMS(arena));
+ arena[a]->next = freeblocks;
+ freeblocks = first[a].next;
+ first[a].next = NULL;
+ arena[a] = &first[a];
+}
+#endif