2 * allocate.c - simple space-efficient blob allocator.
4 * Copyright (C) 2003 Transmeta Corp.
5 * 2003-2004 Linus Torvalds
7 * Licensed under the Open Software License version 1.1
9 * Simple allocator for data that doesn't get partially free'd.
10 * The tokenizer and parser allocate a _lot_ of small data structures
11 * (often just two-three bytes for things like small integers),
12 * and since they all depend on each other you can't free them
13 * individually _anyway_. So do something that is very space-
14 * efficient: allocate larger "blobs", and give out individual
15 * small bits and pieces of it with no maintenance overhead.
27 #include "expression.h"
28 #include "linearize.h"
30 void drop_all_allocations(struct allocator_struct
*desc
)
32 struct allocation_blob
*blob
= desc
->blobs
;
35 desc
->allocations
= 0;
36 desc
->total_bytes
= 0;
37 desc
->useful_bytes
= 0;
38 desc
->freelist
= NULL
;
40 struct allocation_blob
*next
= blob
->next
;
41 blob_free(blob
, desc
->chunking
);
46 void free_one_entry(struct allocator_struct
*desc
, void *entry
)
53 void *allocate(struct allocator_struct
*desc
, unsigned int size
)
55 unsigned long alignment
= desc
->alignment
;
56 struct allocation_blob
*blob
= desc
->blobs
;
60 * NOTE! The freelist only works with things that are
61 * (a) sufficiently aligned
62 * (b) use a constant size
63 * Don't try to free allocators that don't follow
67 void **p
= desc
->freelist
;
73 } while ((size
-= sizeof(void *)) > 0);
78 desc
->useful_bytes
+= size
;
79 size
= (size
+ alignment
- 1) & ~(alignment
-1);
80 if (!blob
|| blob
->left
< size
) {
81 unsigned int offset
, chunking
= desc
->chunking
;
82 struct allocation_blob
*newblob
= blob_alloc(chunking
);
85 desc
->total_bytes
+= chunking
;
88 desc
->blobs
= newblob
;
89 offset
= offsetof(struct allocation_blob
, data
);
90 offset
= (offset
+ alignment
- 1) & ~(alignment
-1);
91 blob
->left
= chunking
- offset
;
92 blob
->offset
= offset
- offsetof(struct allocation_blob
, data
);
94 retval
= blob
->data
+ blob
->offset
;
100 void show_allocations(struct allocator_struct
*x
)
102 fprintf(stderr
, "%s: %d allocations, %d bytes (%d total bytes, "
103 "%6.2f%% usage, %6.2f average size)\n",
104 x
->name
, x
->allocations
, x
->useful_bytes
, x
->total_bytes
,
105 100 * (double) x
->useful_bytes
/ x
->total_bytes
,
106 (double) x
->useful_bytes
/ x
->allocations
);
109 ALLOCATOR(ident
, "identifiers");
110 ALLOCATOR(token
, "tokens");
111 ALLOCATOR(symbol
, "symbols");
112 ALLOCATOR(expression
, "expressions");
113 ALLOCATOR(statement
, "statements");
114 ALLOCATOR(string
, "strings");
115 ALLOCATOR(scope
, "scopes");
116 __ALLOCATOR(void, 0, 1, "bytes", bytes
);
117 ALLOCATOR(basic_block
, "basic_block");
118 ALLOCATOR(entrypoint
, "entrypoint");
119 ALLOCATOR(instruction
, "instruction");
120 ALLOCATOR(multijmp
, "multijmp");
121 ALLOCATOR(pseudo
, "pseudo");