aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
authorLinus Torvalds <torvalds@ppc970.osdl.org>2004-12-02 12:08:51 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-07 21:05:25 -0700
commit2035e136c41f24b9b991917fd0ead512e4fd3fd8 (patch)
tree9151d61dd60d8f1d8087e9d97b62b89e1484ccfe
parent34c0cd11a43671d68d47c99a895fb68dd920f0a5 (diff)
downloadsparse-dev-2035e136c41f24b9b991917fd0ead512e4fd3fd8.tar.gz
Split out the blob allocator from lib.c into allocate.c.
It's disgusting how intimate lib.c is with all the types, and this is slowly trying to split things up a bit. Now the intimate part is in allocate.c, but maybe we can get to the point where each allocation user just declares its own allocation strategy, and just uses the generic routines in allocate.c
-rw-r--r--Makefile5
-rw-r--r--allocate.c149
-rw-r--r--allocate.h46
-rw-r--r--check.c1
-rw-r--r--compat-cygwin.c1
-rw-r--r--compat-linux.c1
-rw-r--r--compat-mingw.c1
-rw-r--r--compat-solaris.c1
-rw-r--r--compile-i386.c1
-rw-r--r--compile.c1
-rw-r--r--evaluate.c1
-rw-r--r--expand.c1
-rw-r--r--expression.c2
-rw-r--r--expression.h2
-rw-r--r--inline.c1
-rw-r--r--lib.c145
-rw-r--r--lib.h23
-rw-r--r--obfuscate.c1
-rw-r--r--parse.c1
-rw-r--r--pre-process.c1
-rw-r--r--scope.c1
-rw-r--r--show-parse.c1
-rw-r--r--sort.c4
-rw-r--r--symbol.c1
-rw-r--r--test-linearize.c1
-rw-r--r--test-parsing.c1
-rw-r--r--test-sort.c1
-rw-r--r--tokenize.c1
28 files changed, 226 insertions, 170 deletions
diff --git a/Makefile b/Makefile
index 29b49811..26f2a64e 100644
--- a/Makefile
+++ b/Makefile
@@ -12,11 +12,12 @@ PREFIX=$(HOME)
PROGRAMS=test-lexing test-parsing obfuscate check compile test-linearize
LIB_H= token.h parse.h lib.h symbol.h scope.h expression.h target.h \
- linearize.h bitmap.h ident-list.h compat.h flow.h
+ linearize.h bitmap.h ident-list.h compat.h flow.h allocate.h
LIB_OBJS= target.o parse.o tokenize.o pre-process.o symbol.o lib.o scope.o \
expression.o show-parse.o evaluate.o expand.o inline.o linearize.o \
- sort.o flow.o cse.o simplify.o memops.o liveness.o compat-$(OS).o
+ sort.o allocate.o compat-$(OS).o \
+ flow.o cse.o simplify.o memops.o liveness.o
LIB_FILE= sparse.a
LIBS=$(LIB_FILE)
diff --git a/allocate.c b/allocate.c
new file mode 100644
index 00000000..c3b39572
--- /dev/null
+++ b/allocate.c
@@ -0,0 +1,149 @@
+/*
+ * allocate.c - simple space-efficient blob allocator.
+ *
+ * Copyright (C) 2003 Transmeta Corp.
+ * 2003-2004 Linus Torvalds
+ *
+ * Licensed under the Open Software License version 1.1
+ *
+ * Simple allocator for data that doesn't get partially free'd.
+ * The tokenizer and parser allocate a _lot_ of small data structures
+ * (often just two-three bytes for things like small integers),
+ * and since they all depend on each other you can't free them
+ * individually _anyway_. So do something that is very space-
+ * efficient: allocate larger "blobs", and give out individual
+ * small bits and pieces of it with no maintenance overhead.
+ */
+#include <stdlib.h>
+#include <stddef.h>
+#include <stdio.h>
+
+#include "lib.h"
+#include "allocate.h"
+#include "compat.h"
+#include "token.h"
+#include "symbol.h"
+#include "scope.h"
+#include "expression.h"
+#include "linearize.h"
+
+void drop_all_allocations(struct allocator_struct *desc)
+{
+ struct allocation_blob *blob = desc->blobs;
+
+ desc->blobs = NULL;
+ desc->allocations = 0;
+ desc->total_bytes = 0;
+ desc->useful_bytes = 0;
+ while (blob) {
+ struct allocation_blob *next = blob->next;
+ blob_free(blob, desc->chunking);
+ blob = next;
+ }
+}
+
+void free_one_entry(struct allocator_struct *desc, void *entry)
+{
+ void **p = entry;
+ *p = desc->freelist;
+ desc->freelist = p;
+}
+
+void *allocate(struct allocator_struct *desc, unsigned int size)
+{
+ unsigned long alignment = desc->alignment;
+ struct allocation_blob *blob = desc->blobs;
+ void *retval;
+
+ /*
+ * NOTE! The freelist only works with things that are
+ * (a) sufficiently aligned
+ * (b) use a constant size
+ * Don't try to free allocators that don't follow
+ * these rules.
+ */
+ if (desc->freelist) {
+ void **p = desc->freelist;
+ retval = p;
+ desc->freelist = *p;
+ do {
+ *p = NULL;
+ p++;
+ } while ((size -= sizeof(void *)) > 0);
+ return retval;
+ }
+
+ desc->allocations++;
+ desc->useful_bytes += size;
+ size = (size + alignment - 1) & ~(alignment-1);
+ if (!blob || blob->left < size) {
+ unsigned int offset, chunking = desc->chunking;
+ struct allocation_blob *newblob = blob_alloc(chunking);
+ if (!newblob)
+ die("out of memory");
+ desc->total_bytes += chunking;
+ newblob->next = blob;
+ blob = newblob;
+ desc->blobs = newblob;
+ offset = offsetof(struct allocation_blob, data);
+ offset = (offset + alignment - 1) & ~(alignment-1);
+ blob->left = chunking - offset;
+ blob->offset = offset - offsetof(struct allocation_blob, data);
+ }
+ retval = blob->data + blob->offset;
+ blob->offset += size;
+ blob->left -= size;
+ return retval;
+}
+
+static void show_allocations(struct allocator_struct *x)
+{
+ fprintf(stderr, "%s: %d allocations, %d bytes (%d total bytes, "
+ "%6.2f%% usage, %6.2f average size)\n",
+ x->name, x->allocations, x->useful_bytes, x->total_bytes,
+ 100 * (double) x->useful_bytes / x->total_bytes,
+ (double) x->useful_bytes / x->allocations);
+}
+
+struct allocator_struct ident_allocator = { "identifiers", NULL, __alignof__(struct ident), CHUNK };
+struct allocator_struct token_allocator = { "tokens", NULL, __alignof__(struct token), CHUNK };
+struct allocator_struct symbol_allocator = { "symbols", NULL, __alignof__(struct symbol), CHUNK };
+struct allocator_struct expression_allocator = { "expressions", NULL, __alignof__(struct expression), CHUNK };
+struct allocator_struct statement_allocator = { "statements", NULL, __alignof__(struct statement), CHUNK };
+struct allocator_struct string_allocator = { "strings", NULL, __alignof__(struct statement), CHUNK };
+struct allocator_struct scope_allocator = { "scopes", NULL, __alignof__(struct scope), CHUNK };
+struct allocator_struct bytes_allocator = { "bytes", NULL, 1, CHUNK };
+struct allocator_struct basic_block_allocator = { "basic_block", NULL, __alignof__(struct basic_block), CHUNK };
+struct allocator_struct entrypoint_allocator = { "entrypoint", NULL, __alignof__(struct entrypoint), CHUNK };
+struct allocator_struct instruction_allocator = { "instruction", NULL, __alignof__(struct instruction), CHUNK };
+struct allocator_struct multijmp_allocator = { "multijmp", NULL, __alignof__(struct multijmp), CHUNK };
+struct allocator_struct pseudo_allocator = { "pseudo", NULL, __alignof__(struct pseudo), CHUNK };
+
+#define __ALLOCATOR(type, size, x) \
+ type *__alloc_##x(int extra) \
+ { \
+ return allocate(&x##_allocator, size+extra); \
+ } \
+ void __free_##x(type *entry) \
+ { \
+ return free_one_entry(&x##_allocator, entry); \
+ } \
+ void show_##x##_alloc(void) \
+ { \
+ show_allocations(&x##_allocator); \
+ } \
+ void clear_##x##_alloc(void) \
+ { \
+ drop_all_allocations(&x##_allocator); \
+ }
+#define ALLOCATOR(x) __ALLOCATOR(struct x, sizeof(struct x), x)
+
+ALLOCATOR(ident); ALLOCATOR(token); ALLOCATOR(symbol);
+ALLOCATOR(expression); ALLOCATOR(statement); ALLOCATOR(string);
+ALLOCATOR(scope); __ALLOCATOR(void, 0, bytes);
+ALLOCATOR(basic_block); ALLOCATOR(entrypoint);
+ALLOCATOR(instruction);
+ALLOCATOR(multijmp);
+ALLOCATOR(pseudo);
+
+
diff --git a/allocate.h b/allocate.h
new file mode 100644
index 00000000..56abb0c7
--- /dev/null
+++ b/allocate.h
@@ -0,0 +1,46 @@
+#ifndef ALLOCATE_H
+#define ALLOCATE_H
+
+struct allocation_blob {
+ struct allocation_blob *next;
+ unsigned int left, offset;
+ unsigned char data[];
+};
+
+struct allocator_struct {
+ const char *name;
+ struct allocation_blob *blobs;
+ unsigned int alignment;
+ unsigned int chunking;
+ void *freelist;
+ /* statistics */
+ unsigned int allocations, total_bytes, useful_bytes;
+};
+
+extern void drop_all_allocations(struct allocator_struct *desc);
+extern void *allocate(struct allocator_struct *desc, unsigned int size);
+extern void free_one_entry(struct allocator_struct *desc, void *entry);
+
+#define __DECLARE_ALLOCATOR(type, x) \
+ extern type *__alloc_##x(int); \
+ extern void __free_##x(type *); \
+ extern void show_##x##_alloc(void); \
+ extern void clear_##x##_alloc(void);
+#define DECLARE_ALLOCATOR(x) __DECLARE_ALLOCATOR(struct x, x)
+
+DECLARE_ALLOCATOR(ident);
+DECLARE_ALLOCATOR(token);
+DECLARE_ALLOCATOR(symbol);
+DECLARE_ALLOCATOR(expression);
+DECLARE_ALLOCATOR(statement);
+DECLARE_ALLOCATOR(string);
+DECLARE_ALLOCATOR(scope);
+__DECLARE_ALLOCATOR(void, bytes);
+DECLARE_ALLOCATOR(basic_block);
+DECLARE_ALLOCATOR(entrypoint);
+DECLARE_ALLOCATOR(instruction);
+DECLARE_ALLOCATOR(multijmp);
+DECLARE_ALLOCATOR(phi);
+DECLARE_ALLOCATOR(pseudo);
+
+#endif
diff --git a/check.c b/check.c
index e7f8a497..9c5b3590 100644
--- a/check.c
+++ b/check.c
@@ -17,6 +17,7 @@
#include <fcntl.h>
#include "lib.h"
+#include "allocate.h"
#include "token.h"
#include "parse.h"
#include "symbol.h"
diff --git a/compat-cygwin.c b/compat-cygwin.c
index 972d7c96..7545703d 100644
--- a/compat-cygwin.c
+++ b/compat-cygwin.c
@@ -13,6 +13,7 @@
#include <sys/stat.h>
#include "lib.h"
+#include "allocate.h"
#include "token.h"
void *blob_alloc(unsigned long size)
diff --git a/compat-linux.c b/compat-linux.c
index 8f621ae6..da24ab83 100644
--- a/compat-linux.c
+++ b/compat-linux.c
@@ -1,6 +1,7 @@
#define _GNU_SOURCE
#include "lib.h"
+#include "allocate.h"
#include "compat/id-files-stat.c"
#include "compat/mmap-blob.c"
diff --git a/compat-mingw.c b/compat-mingw.c
index 1941c0b0..66456c72 100644
--- a/compat-mingw.c
+++ b/compat-mingw.c
@@ -14,6 +14,7 @@
#include <string.h>
#include "lib.h"
+#include "allocate.h"
#include "token.h"
void *blob_alloc(unsigned long size)
diff --git a/compat-solaris.c b/compat-solaris.c
index d8fa1d9e..62a7714b 100644
--- a/compat-solaris.c
+++ b/compat-solaris.c
@@ -1,4 +1,5 @@
#include "lib.h"
+#include "allocate.h"
#include "compat/id-files-stat.c"
#include "compat/mmap-blob.c"
diff --git a/compile-i386.c b/compile-i386.c
index eedd65b5..9e72a548 100644
--- a/compile-i386.c
+++ b/compile-i386.c
@@ -32,6 +32,7 @@
#include <assert.h>
#include "lib.h"
+#include "allocate.h"
#include "token.h"
#include "parse.h"
#include "symbol.h"
diff --git a/compile.c b/compile.c
index edbd44b4..f8fb6219 100644
--- a/compile.c
+++ b/compile.c
@@ -18,6 +18,7 @@
#include <fcntl.h>
#include "lib.h"
+#include "allocate.h"
#include "token.h"
#include "parse.h"
#include "symbol.h"
diff --git a/evaluate.c b/evaluate.c
index 2c60db41..731eb54e 100644
--- a/evaluate.c
+++ b/evaluate.c
@@ -19,6 +19,7 @@
#include <limits.h>
#include "lib.h"
+#include "allocate.h"
#include "parse.h"
#include "token.h"
#include "symbol.h"
diff --git a/expand.c b/expand.c
index c10d804a..3b9adb8a 100644
--- a/expand.c
+++ b/expand.c
@@ -19,6 +19,7 @@
#include <limits.h>
#include "lib.h"
+#include "allocate.h"
#include "parse.h"
#include "token.h"
#include "symbol.h"
diff --git a/expression.c b/expression.c
index 66aa6dfd..8a1b40e6 100644
--- a/expression.c
+++ b/expression.c
@@ -19,6 +19,8 @@
#include <limits.h>
#include "lib.h"
+#include "allocate.h"
+#include "allocate.h"
#include "token.h"
#include "parse.h"
#include "symbol.h"
diff --git a/expression.h b/expression.h
index c0b1292d..6f244fc6 100644
--- a/expression.h
+++ b/expression.h
@@ -11,6 +11,8 @@
* Declarations and helper functions for expression parsing.
*/
+#include "allocate.h"
+
struct expression_list;
enum expression_type {
diff --git a/inline.c b/inline.c
index ef1a37fa..d4ec0a37 100644
--- a/inline.c
+++ b/inline.c
@@ -11,6 +11,7 @@
#include <stdio.h>
#include "lib.h"
+#include "allocate.h"
#include "token.h"
#include "parse.h"
#include "symbol.h"
diff --git a/lib.c b/lib.c
index f7e7c2fb..58d9e5c9 100644
--- a/lib.c
+++ b/lib.c
@@ -20,6 +20,7 @@
#include <sys/stat.h>
#include "lib.h"
+#include "allocate.h"
#include "token.h"
#include "parse.h"
#include "symbol.h"
@@ -70,150 +71,6 @@ unsigned int hexval(unsigned int c)
return retval;
}
-/*
- * Simple allocator for data that doesn't get partially free'd.
- * The tokenizer and parser allocate a _lot_ of small data structures
- * (often just two-three bytes for things like small integers),
- * and since they all depend on each other you can't free them
- * individually _anyway_. So do something that is very space-
- * efficient: allocate larger "blobs", and give out individual
- * small bits and pieces of it with no maintenance overhead.
- */
-struct allocation_blob {
- struct allocation_blob *next;
- unsigned int left, offset;
- unsigned char data[];
-};
-
-struct allocator_struct {
- const char *name;
- struct allocation_blob *blobs;
- unsigned int alignment;
- unsigned int chunking;
- void *freelist;
- /* statistics */
- unsigned int allocations, total_bytes, useful_bytes;
-};
-
-void drop_all_allocations(struct allocator_struct *desc)
-{
- struct allocation_blob *blob = desc->blobs;
-
- desc->blobs = NULL;
- desc->allocations = 0;
- desc->total_bytes = 0;
- desc->useful_bytes = 0;
- while (blob) {
- struct allocation_blob *next = blob->next;
- blob_free(blob, desc->chunking);
- blob = next;
- }
-}
-
-void free_one_entry(struct allocator_struct *desc, void *entry)
-{
- void **p = entry;
- *p = desc->freelist;
- desc->freelist = p;
-}
-
-void *allocate(struct allocator_struct *desc, unsigned int size)
-{
- unsigned long alignment = desc->alignment;
- struct allocation_blob *blob = desc->blobs;
- void *retval;
-
- /*
- * NOTE! The freelist only works with things that are
- * (a) sufficiently aligned
- * (b) use a constant size
- * Don't try to free allocators that don't follow
- * these rules.
- */
- if (desc->freelist) {
- void **p = desc->freelist;
- retval = p;
- desc->freelist = *p;
- do {
- *p = NULL;
- p++;
- } while ((size -= sizeof(void *)) > 0);
- return retval;
- }
-
- desc->allocations++;
- desc->useful_bytes += size;
- size = (size + alignment - 1) & ~(alignment-1);
- if (!blob || blob->left < size) {
- unsigned int offset, chunking = desc->chunking;
- struct allocation_blob *newblob = blob_alloc(chunking);
- if (!newblob)
- die("out of memory");
- desc->total_bytes += chunking;
- newblob->next = blob;
- blob = newblob;
- desc->blobs = newblob;
- offset = offsetof(struct allocation_blob, data);
- offset = (offset + alignment - 1) & ~(alignment-1);
- blob->left = chunking - offset;
- blob->offset = offset - offsetof(struct allocation_blob, data);
- }
- retval = blob->data + blob->offset;
- blob->offset += size;
- blob->left -= size;
- return retval;
-}
-
-static void show_allocations(struct allocator_struct *x)
-{
- fprintf(stderr, "%s: %d allocations, %d bytes (%d total bytes, "
- "%6.2f%% usage, %6.2f average size)\n",
- x->name, x->allocations, x->useful_bytes, x->total_bytes,
- 100 * (double) x->useful_bytes / x->total_bytes,
- (double) x->useful_bytes / x->allocations);
-}
-
-struct allocator_struct ident_allocator = { "identifiers", NULL, __alignof__(struct ident), CHUNK };
-struct allocator_struct token_allocator = { "tokens", NULL, __alignof__(struct token), CHUNK };
-struct allocator_struct symbol_allocator = { "symbols", NULL, __alignof__(struct symbol), CHUNK };
-struct allocator_struct expression_allocator = { "expressions", NULL, __alignof__(struct expression), CHUNK };
-struct allocator_struct statement_allocator = { "statements", NULL, __alignof__(struct statement), CHUNK };
-struct allocator_struct string_allocator = { "strings", NULL, __alignof__(struct statement), CHUNK };
-struct allocator_struct scope_allocator = { "scopes", NULL, __alignof__(struct scope), CHUNK };
-struct allocator_struct bytes_allocator = { "bytes", NULL, 1, CHUNK };
-struct allocator_struct basic_block_allocator = { "basic_block", NULL, __alignof__(struct basic_block), CHUNK };
-struct allocator_struct entrypoint_allocator = { "entrypoint", NULL, __alignof__(struct entrypoint), CHUNK };
-struct allocator_struct instruction_allocator = { "instruction", NULL, __alignof__(struct instruction), CHUNK };
-struct allocator_struct multijmp_allocator = { "multijmp", NULL, __alignof__(struct multijmp), CHUNK };
-struct allocator_struct pseudo_allocator = { "pseudo", NULL, __alignof__(struct pseudo), CHUNK };
-
-#define __ALLOCATOR(type, size, x) \
- type *__alloc_##x(int extra) \
- { \
- return allocate(&x##_allocator, size+extra); \
- } \
- void __free_##x(type *entry) \
- { \
- return free_one_entry(&x##_allocator, entry); \
- } \
- void show_##x##_alloc(void) \
- { \
- show_allocations(&x##_allocator); \
- } \
- void clear_##x##_alloc(void) \
- { \
- drop_all_allocations(&x##_allocator); \
- }
-#define ALLOCATOR(x) __ALLOCATOR(struct x, sizeof(struct x), x)
-
-ALLOCATOR(ident); ALLOCATOR(token); ALLOCATOR(symbol);
-ALLOCATOR(expression); ALLOCATOR(statement); ALLOCATOR(string);
-ALLOCATOR(scope); __ALLOCATOR(void, 0, bytes);
-ALLOCATOR(basic_block); ALLOCATOR(entrypoint);
-ALLOCATOR(instruction);
-ALLOCATOR(multijmp);
-ALLOCATOR(pseudo);
-
int ptr_list_size(struct ptr_list *head)
{
int nr = 0;
diff --git a/lib.h b/lib.h
index 00c939a2..b6fe35ec 100644
--- a/lib.h
+++ b/lib.h
@@ -75,29 +75,6 @@ extern void error(struct position, const char *, ...) FORMAT_ATTR(2);
extern void error_die(struct position, const char *, ...) FORMAT_ATTR(2);
#undef FORMAT_ATTR
-#define __DECLARE_ALLOCATOR(type, x) \
- extern type *__alloc_##x(int); \
- extern void __free_##x(type *); \
- extern void show_##x##_alloc(void); \
- extern void clear_##x##_alloc(void);
-#define DECLARE_ALLOCATOR(x) __DECLARE_ALLOCATOR(struct x, x)
-
-DECLARE_ALLOCATOR(ident);
-DECLARE_ALLOCATOR(token);
-DECLARE_ALLOCATOR(symbol);
-DECLARE_ALLOCATOR(expression);
-DECLARE_ALLOCATOR(statement);
-DECLARE_ALLOCATOR(string);
-DECLARE_ALLOCATOR(scope);
-__DECLARE_ALLOCATOR(void, bytes);
-DECLARE_ALLOCATOR(basic_block);
-DECLARE_ALLOCATOR(entrypoint);
-DECLARE_ALLOCATOR(instruction);
-DECLARE_ALLOCATOR(multijmp);
-DECLARE_ALLOCATOR(phi);
-DECLARE_ALLOCATOR(pseudo);
-
-
#define LIST_NODE_NR (29)
struct ptr_list {
diff --git a/obfuscate.c b/obfuscate.c
index aa1a32fd..12fb9c39 100644
--- a/obfuscate.c
+++ b/obfuscate.c
@@ -17,6 +17,7 @@
#include <fcntl.h>
#include "lib.h"
+#include "allocate.h"
#include "token.h"
#include "parse.h"
#include "symbol.h"
diff --git a/parse.c b/parse.c
index af40eccc..81b5e13b 100644
--- a/parse.c
+++ b/parse.c
@@ -19,6 +19,7 @@
#include <limits.h>
#include "lib.h"
+#include "allocate.h"
#include "token.h"
#include "parse.h"
#include "symbol.h"
diff --git a/pre-process.c b/pre-process.c
index d243766a..950aea37 100644
--- a/pre-process.c
+++ b/pre-process.c
@@ -21,6 +21,7 @@
#include "pre-process.h"
#include "lib.h"
+#include "allocate.h"
#include "parse.h"
#include "token.h"
#include "symbol.h"
diff --git a/scope.c b/scope.c
index 9e4c5248..58dd1ee3 100644
--- a/scope.c
+++ b/scope.c
@@ -12,6 +12,7 @@
#include <string.h>
#include "lib.h"
+#include "allocate.h"
#include "symbol.h"
#include "scope.h"
diff --git a/show-parse.c b/show-parse.c
index 3516991d..2b8e4715 100644
--- a/show-parse.c
+++ b/show-parse.c
@@ -17,6 +17,7 @@
#include <fcntl.h>
#include "lib.h"
+#include "allocate.h"
#include "token.h"
#include "parse.h"
#include "symbol.h"
diff --git a/sort.c b/sort.c
index 9cd446ab..f6cb6054 100644
--- a/sort.c
+++ b/sort.c
@@ -9,11 +9,13 @@
* Stable: yes.
*/
-#include "lib.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include "lib.h"
+#include "allocate.h"
+
#undef PARANOIA
#undef COVERAGE
diff --git a/symbol.c b/symbol.c
index d705350c..68de5e1a 100644
--- a/symbol.c
+++ b/symbol.c
@@ -12,6 +12,7 @@
#include <string.h>
#include "lib.h"
+#include "allocate.h"
#include "token.h"
#include "parse.h"
#include "symbol.h"
diff --git a/test-linearize.c b/test-linearize.c
index 75826a0c..df233299 100644
--- a/test-linearize.c
+++ b/test-linearize.c
@@ -15,6 +15,7 @@
#include <fcntl.h>
#include "lib.h"
+#include "allocate.h"
#include "token.h"
#include "parse.h"
#include "symbol.h"
diff --git a/test-parsing.c b/test-parsing.c
index 59ae4be6..7f6f4bf4 100644
--- a/test-parsing.c
+++ b/test-parsing.c
@@ -17,6 +17,7 @@
#include <fcntl.h>
#include "lib.h"
+#include "allocate.h"
#include "token.h"
#include "parse.h"
#include "symbol.h"
diff --git a/test-sort.c b/test-sort.c
index c259e2b6..d0ffb670 100644
--- a/test-sort.c
+++ b/test-sort.c
@@ -1,4 +1,5 @@
#include "lib.h"
+#include "allocate.h"
#include <stdio.h>
#include <stdlib.h>
diff --git a/tokenize.c b/tokenize.c
index 5883c08d..98ea9c5c 100644
--- a/tokenize.c
+++ b/tokenize.c
@@ -17,6 +17,7 @@
#include <sys/stat.h>
#include "lib.h"
+#include "allocate.h"
#include "token.h"
#include "symbol.h"