4 * Copyright (c) 1998 A. Krall, R. Grafl, M. Gschwind, M. Probst, Ph. Tomsich
5 * See file COPYRIGHT for information on usage and disclaimer of warranties
7 * Authors: Philipp Tomsich EMAIL: cacao@complang.tuwien.ac.at
9 * $Id: allocator.c 34 1998-11-03 11:29:37Z phil $
15 Locality preservation has not been added... yet
18 #include "allocator.h"
20 static FREE_EXACT* __freelist_exact[1 << EXACT];
21 static FREE_EXACT** freelist_exact = &__freelist_exact[-1];
22 static FREE_LARGE* freelist_large[LARGE << SUBBIT];
25 static unsigned char highest[256];
27 # if EXACT_TOP_BIT < 8
29 static unsigned char highest_0[2048];
31 static unsigned char highest_0[1024];
34 static unsigned char* highest_8 = &highest_0[256];
35 static unsigned char* highest_16 = &highest_0[512];
36 static unsigned char* highest_24 = &highest_0[768];
38 static unsigned char* highest_32 = &highest_0[1024];
39 static unsigned char* highest_40 = &highest_0[1280];
40 static unsigned char* highest_48 = &highest_0[1538];
41 static unsigned char* highest_56 = &highest_0[1792];
45 static unsigned char highest_8[1792];
47 static unsigned char highest_8[768];
50 static unsigned char* highest_16 = &highest_8[256];
51 static unsigned char* highest_24 = &highest_8[512];
53 static unsigned char* highest_32 = &highest_8[768];
54 static unsigned char* highest_40 = &highest_8[1280];
55 static unsigned char* highest_48 = &highest_8[1538];
56 static unsigned char* highest_56 = &highest_8[1792];
63 find_highest(SIZE bits){
65 /* optimize for large allocation sizes */
68 if (bits & 0xff00000000000000ULL)
69 return 56 + highest[bits >> 56 & 0xff];
70 if (bits & 0xff000000000000ULL)
71 return 48 + highest[bits >> 48 & 0xff];
72 if (bits & 0xff0000000000ULL)
73 return 40 + highest[bits >> 40 & 0xff];
74 if (bits & 0xff00000000ULL)
75 return 32 + highest[bits >> 32 & 0xff];
78 if (bits & 0xff000000)
79 return 24 + highest[bits >> 24 & 0xff];
81 return 16 + highest[bits >> 16 & 0xff];
83 return 8 + highest[bits >> 8 & 0xff];
85 # if EXACT_TOP_BIT < 8
86 return highest[bits & 0xff];
90 if (bits & 0xff00000000000000ULL)
91 return highest_56[bits >> 56 & 0xff];
92 if (bits & 0xff000000000000ULL)
93 return highest_48[bits >> 48 & 0xff];
94 if (bits & 0xff0000000000ULL)
95 return highest_40[bits >> 40 & 0xff];
96 if (bits & 0xff00000000ULL)
97 return highest_32[bits >> 32 & 0xff];
100 if (bits & 0xff000000)
101 return highest_24[bits >> 24 & 0xff];
103 return highest_16[bits >> 16 & 0xff];
105 return highest_8[bits >> 8 & 0xff];
107 # if EXACT_TOP_BIT < 8
108 return highest_0[bits & 0xff];
113 /* optimize for small allocation sizes */
116 # if EXACT_TOP_BIT < 8
117 if (!(bits & ~0xffULL))
118 return highest[bits & 0xff];
121 if (!(bits & ~0xffffULL))
122 return 8 + highest[bits >> 8 & 0xff];
124 if (!(bits & ~0xffffffULL))
125 return 16 + highest[bits >> 16 & 0xff];
128 return 24 + highest[bits >> 24 & 0xff];
130 if (!(bits & ~0xffffffffULL))
131 return 24 + highest[bits >> 24 & 0xff];
133 if (!(bits & ~0xffffffffffULL))
134 return 32 + highest[bits >> 32 & 0xff];
136 if (!(bits & ~0xffffffffffffULL))
137 return 40 + highest[bits >> 40 & 0xff];
139 if (!(bits & ~0xffffffffffffffULL))
140 return 48 + highest[bits >> 48 & 0xff];
142 return 56 + highest[bits >> 56 & 0xff];
145 # if EXACT_TOP_BIT < 8
146 if (!(bits & ~0xffULL))
147 return highest_0[bits & 0xff];
150 if (!(bits & ~0xffffULL))
151 return highest_8[bits >> 8 & 0xff];
153 if (!(bits & ~0xffffffULL))
154 return highest_16[bits >> 16 & 0xff];
157 return highest_24[bits >> 24 & 0xff];
159 if (!(bits & ~0xffffffffULL))
160 return highest_24[bits >> 24 & 0xff];
162 if (!(bits & ~0xffffffffffULL))
163 return highest_32[bits >> 32 & 0xff];
165 if (!(bits & ~0xffffffffffffULL))
166 return highest_40[bits >> 40 & 0xff];
168 if (!(bits & ~0xffffffffffffffULL))
169 return highest_48[bits >> 48 & 0xff];
171 return highest_56[bits >> 56 & 0xff];
182 static unsigned char r[10] = { 1, 1, 2, 4, 8, 16, 32, 64, 128 };
190 for (k = 0; k < 10; ++k) {
191 for (m = 0; m < r[k]; ++m) {
193 highest[i] = j - (EXACT + ALIGN) - 1;
195 # if (EXACT_TOP_BIT < 8)
196 highest_0 [i] = j - 8 - (EXACT + ALIGN) - 1;
198 highest_8 [i] = j + 8 - (EXACT + ALIGN) - 1;
199 highest_16 [i] = 8 + highest_8 [i];
200 highest_24 [i] = 16 + highest_8 [i];
202 highest_32 [i] = 24 + highest_8 [i];
203 highest_40 [i] = 32 + highest_8 [i];
204 highest_48 [i] = 40 + highest_8 [i];
205 highest_56 [i] = 48 + highest_8 [i];
216 #define PRESERVE_LOCALITY 0
219 static SIZE allocator_largest_free = 0;
222 #if PRESERVE_LOCALITY
223 static void* allocator_last_splitoff = 0;
224 static SIZE allocator_last_splitoff_size = 0;
233 allocator_largest_free = 0;
236 #if PRESERVE_LOCALITY
237 allocator_last_splitoff = 0;
238 allocator_last_splitoff_size = 0;
241 for (i = 1; i <= (1 << EXACT); ++i)
242 freelist_exact[i] = 0;
244 for (i = 0; i < (LARGE << SUBBIT); ++i)
245 freelist_large[i] = 0;
252 #if COUNT_ALLOCATIONS
253 static unsigned long long allocator_allocations = 0;
256 allocator_display_count()
258 fprintf(stderr, "total allocations: %d\n", allocator_allocations);
267 "allocator_init: $Id: allocator.c 34 1998-11-03 11:29:37Z phil $\n\n");
269 fprintf(stderr, "\t%d bit addresses\n", ADDRESS);
270 fprintf(stderr, "\t%d bit alignment\n", ALIGN);
271 fprintf(stderr, "\t%d exact bits\n", EXACT );
272 fprintf(stderr, "\t%d large bits\n", LARGE );
273 fprintf(stderr, "\t%d subbin bits\n", SUBBIT );
274 fprintf(stderr, "\tusing %s tables\n",
275 SMALL_TABLES ? "small (256 byte)" : "large (2048 byte)");
276 fprintf(stderr, "\tusing %s highest-bit search strategy\n",
277 MSB_TO_LSB_SEARCH ? "MSB-to-LSB" : "LSB-to-MSB");
280 "\tusing %d bytes for exact bins, %d bytes for sorted bins\n\n",
281 (1 << EXACT) << ALIGN,
282 (LARGE << SUBBIT) << ALIGN);
284 init_table(); /* set up the highest-table */
285 allocator_reset(); /* clear the freelists & internal variables */
289 size_to_bin(SIZE size)
292 printf ("size: %d ", size);
296 if (size > ((1 << EXACT) << ALIGN)) {
298 // unsigned char shift = shift_table_32[highbit];
299 // int bin = offset_table_32[highbit] + ( (size >> shift) & mask );
301 unsigned char highbit = find_highest(size);
302 unsigned char shift = highbit + (EXACT + ALIGN - SUBBIT);
303 static int mask = (1 << SUBBIT) - 1;
304 int bin = (highbit << SUBBIT) + ( (size >> shift) & mask );
306 // printf("shift: %d, %d; %d; large bin: %d\n", shift, (size >> shift) & mask, highbit, bin);
308 int bin = find_highest(size);
312 printf("==> large bin: %d\n", bin);
319 printf("==> exact bin: %d\n", (int)((size >> ALIGN) - 1));
322 return (size >> ALIGN);
330 #define OLDEST_FIRST 1
335 Should we enforce an additional "lowest address first" - ordering
336 for the freelist-entries ??? Right now, I'm using oldest-first for
337 the large bins and newest-first for the exact bins...
339 Sorting by the address may reduce heap fragmentation by reducing the
340 heap growth-rate... */
343 allocator_free(void* chunk, SIZE size)
345 assert(chunk && size);
348 if (size > allocator_largest_free)
349 allocator_largest_free = size;
352 if (size > ((1 << EXACT) << ALIGN)) {
353 int bin = size_to_bin(size);
354 FREE_LARGE* curr = freelist_large[bin];
356 ((FREE_LARGE*)chunk)->size = size;
358 if (!freelist_large[bin] || (freelist_large[bin]->size > size)) {
360 ((FREE_LARGE*)chunk)->next = freelist_large[bin];
361 freelist_large[bin] = (FREE_LARGE*)chunk;
365 while ((curr->next) && (curr->next->size <= size)) {
369 /* insert or append */
370 ((FREE_LARGE*)chunk)->next = curr->next;
371 curr->next=(FREE_LARGE*)chunk;
373 int bin = size >> ALIGN;
376 if (!freelist_exact[bin]) {
379 ((FREE_EXACT*)chunk)->next = freelist_exact[bin];
380 freelist_exact[bin] = (FREE_EXACT*)chunk;
383 FREE_EXACT* curr = (FREE_EXACT*)freelist_exact[bin];
384 while (curr->next && (curr < (FREE_EXACT*)chunk))
388 ((FREE_EXACT*)chunk)->next = curr->next;
389 curr->next = (FREE_EXACT*)chunk;
398 allocator_alloc(SIZE size)
404 #if COUNT_ALLOCATIONS
405 allocator_allocations++;
409 if (size > allocator_largest_free)
413 #if PRESERVE_LOCALITY
414 allocator_last_splitoff = 0;
415 allocator_last_splitoff_size = 0;
418 if (size <= ((1 << EXACT) << ALIGN)) {
419 /* search the exact bins */
423 while (bin <= maxbin) {
424 if (freelist_exact[bin]) {
426 result = (void*)freelist_exact[bin];
427 freelist_exact[bin]=freelist_exact[bin]->next;
430 if ((bin << ALIGN) > size)
431 allocator_free(result + size, (bin << ALIGN) - size);
433 // fprintf(stderr, "found chunk in exact bin %d\n", bin);
442 bin = size_to_bin(size);
445 maxbin = LARGE << SUBBIT;
447 while (bin < maxbin) {
448 if (freelist_large[bin]) {
449 FREE_LARGE* chunk = freelist_large[bin];
451 // fprintf(stderr, "found chunk in large bin %d\n", bin);
453 if (chunk->size >= size) {
455 freelist_large[bin] = chunk->next;
458 if (chunk->size > size)
459 allocator_free((void*)chunk + size, (chunk->size - size));
464 while (chunk->next && (chunk->next->size < size))
469 FREE_LARGE* new_chunk = chunk->next;
470 chunk->next = new_chunk->next;
473 if (new_chunk->size > size)
474 allocator_free((void*)new_chunk + size, (new_chunk->size - size));
476 return (void*)new_chunk;
483 return result; /* NULL */
491 for (i = 1; i <= 1 << EXACT; ++i) {
493 FREE_EXACT* chunk = freelist_exact[i];
501 printf("exact bin %d (%d byte blocks): %d\n", i, i * (1 << ALIGN), count);
503 for (i = 0; i < LARGE << SUBBIT; ++i) {
505 FREE_LARGE* chunk = freelist_large[i];
508 printf("large bin %d:\n", i);
511 printf("\t%d bytes @ 0x%lx\n", chunk->size, chunk);
517 printf("dump complete.\n");
524 * These are local overrides for various environment variables in Emacs.
525 * Please do not remove this and leave it at the end of the file, where
526 * Emacs will automagically detect them.
527 * ---------------------------------------------------------------------
530 * indent-tabs-mode: t