*
* Authors: Philipp Tomsich EMAIL: cacao@complang.tuwien.ac.at
*
- * $Id: allocator2.c 98 1998-11-30 22:04:43Z phil $
+ * $Id: allocator2.c 104 1998-12-09 15:36:04Z phil $
*/
#include "allocator.h"
{
#if 0
fprintf(stderr,
- "allocator_init: $Id: allocator2.c 98 1998-11-30 22:04:43Z phil $\n\n");
+ "allocator_init: $Id: allocator2.c 104 1998-12-09 15:36:04Z phil $\n\n");
fprintf(stderr, "\t%d bit addresses\n", ADDRESS);
fprintf(stderr, "\t%d bit alignment\n", ALIGN);
printf("dump complete.\n");
}
+void
+allocator_dump_to_file(FILE* file)
+{
+ int i;
+
+ for (i = 1; i <= 1 << EXACT; ++i) {
+ int count = 0;
+ FREE_EXACT* chunk = freelist_exact[i];
+
+ while (chunk) {
+ chunk = chunk->next;
+ ++count;
+ }
+
+ if (count)
+ fprintf(file, "%d bytes\t%d\n", i * (1 << ALIGN), count);
+ }
+ for (i = 0; i < LARGE << SUBBIT; ++i) {
+ int count = 0;
+ int size = 0;
+ FREE_LARGE* chunk = freelist_large[i];
+
+ while (chunk) {
+ if (chunk->size == size) {
+ count++;
+ } else {
+ if (count)
+ fprintf(file, "%d bytes\t%d\n", size, count);
+ size = chunk->size;
+ count = 1;
+ }
+
+ chunk = chunk->next;
+ ++count;
+ }
+ }
+
+ fprintf(file,"\n");
+ fflush(file);
+}
#undef OFFSET
//#define COLLECT_LIFESPAN
-#define NEW_COLLECT_LIFESPAN
+//#define NEW_COLLECT_LIFESPAN
+#define COLLECT_FRAGMENTATION
+
#define GC_COLLECT_STATISTICS
#define FINALIZER_COUNTING
#define align_size(size) ((size) & ~((1 << ALIGN) - 1))
#define MAP_ADDRESS (void*) 0x10000000
-#define VERBOSITY_MESSAGE 1
-#define VERBOSITY_DEBUG 2
-#define VERBOSITY_MISTRUST 3
-#define VERBOSITY_TRACE 4
-#define VERBOSITY_PARANOIA 5
-#define VERBOSITY_LIFESPAN 6
-
-//#define VERBOSITY VERBOSITY_MESSAGE
-//#define VERBOSITY VERBOSITY_PARANOIA
-#define VERBOSITY VERBOSITY_LIFESPAN
-
/* --- file-wide variables */
static void* heap_base = NULL;
static FILE* tracefile;
#endif
+#ifdef COLLECT_FRAGMENTATION
+static FILE* fragfile;
+static FILE* fragsizefile;
+#endif
+
/* --- implementation */
void
#ifdef NEW_COLLECT_LIFESPAN
lifespan_init(heap_base, heap_size);
#endif
+
+ /* 10. Set up collection of fragmentation data */
+#ifdef COLLECT_FRAGMENTATION
+ fragfile = popen("gzip -9 >fragmentation.gz", "w");
+ fragsizefile = popen("gzip -9 >freeblocks.gz", "w");
+#endif
}
__inline__
lifespan_close();
#endif
+#ifdef COLLECT_FRAGMENTATION
+ pclose(fragfile);
+ pclose(fragsizefile);
+#endif
+
/* 1. Clean up on the heap... finalize all remaining objects */
#if 1
while (curr) {
new_node->next = NULL;
while (*list && (*list)->next) {
-#if VERBOSITY >= VERBOSITY_PARANOIA
- if ((*list)->address == address)
- fprintf(stderr,
- "Attempt to add a duplicate adress to an adress list.\n");
-#endif
-
if ((*list)->next->address < address)
list = &(*list)->next;
else {
++gc_alloc_count;
#endif
-#if 0
- if (free_chunk == 0x20000430228)
- fprintf(stderr, "yell!\n");
-#endif
-
#ifdef COLLECT_LIFESPAN
fprintf(tracefile, "alloc\t0x%lx\t0x%lx\n",
free_chunk, (long)free_chunk + length);
BITBLOCK* temp_bits;
bitmap_t* temp_bitmap;
+#ifdef COLLECT_FRAGMENTATION
+ unsigned long free_size = 0;
+ unsigned long free_fragments = 0;
+#endif
+
/* 1. reset the freelists */
allocator_reset();
/* 2. reclaim unmarked objects */
#if 0
- /* FIXME: add new code, please! */
+ if (!testbit(start_bits, heap_base))
+ free_start = heap_base;
+ else
+ free_start = bitmap_find_next_combination_set_unset(start_bitmap,
+ mark_bitmap,
+ free_start);
+
#else
while (free_end < heap_top) {
free_start = bitmap_find_next_combination_set_unset(start_bitmap,
if (free_end < heap_top) {
allocator_free(free_start, (long)free_end - (long)free_start);
+#ifdef COLLECT_FRAGMENTATION
+ free_size += (long)free_end - (long)free_start;
+ free_fragments++;
+#endif
+
#ifdef COLLECT_LIFESPAN
fprintf(tracefile,
"free\t0x%lx\t0x%lx\n",
bitmap_setbit(mark_bits, free_start); /* necessary to calculate obj-size bitmap based. */
#endif
}
- } else
+ } else {
free_end = heap_top;
+#ifdef NEW_COLLECT_LIFESPAN
+ lifespan_free(free_start, free_end);
+#endif
+ }
}
#endif
mark_bitmap = start_bitmap;
start_bitmap = temp_bitmap;
-#if 0 /* already heandled in allocate */
+#if 0 /* operation already handled in allocate */
/* 3.2. mask reference bitmap */
bitmap_mask_with_bitmap(reference_bitmap, start_bitmap);
#endif
if (heap_top < heap_limit)
bitmap_setbit(start_bits, heap_top);
+ /* 3.4. emit fragmentation info */
+#ifdef COLLECT_FRAGMENTATION
+ fprintf(fragfile,
+ "%ld\t%ld\t%ld\t%ld\n",
+ (unsigned long)heap_top - (unsigned long)heap_base,
+ (unsigned long)heap_top - (unsigned long)heap_base - free_size,
+ free_size,
+ free_fragments);
+ fflush(fragfile);
+
+ allocator_dump_to_file(fragsizefile);
+#endif
+
/* 4. adjust the collection threshold */
- heap_next_collection = (void*)((long)heap_top + ((long)heap_limit - (long)heap_top) / 4);
+ heap_next_collection = (void*)((long)heap_top + ((long)heap_limit - (long)heap_top) / 8);
if (heap_next_collection > heap_limit)
heap_next_collection = heap_limit;
/* 1.a. if addr doesn't point into the heap, return. */
- if (!((void*)addr >= heap_base && (void*)addr < heap_top)) {
+ if ((unsigned long)addr - (unsigned long)heap_base >= heap_size) {
#ifdef GC_COLLECT_STATISTICS
++gc_mark_not_inheap;
#endif
void** end;
#ifdef SIZE_FROM_CLASSINFO
-#if 0
- if (addr == 0x20000430228)
- fprintf(stderr, "stop me!\n");
-#endif
-
if (((java_objectheader*)addr)->vftbl == class_array->vftbl)
end = (void**)((long)addr + (long)((java_arrayheader*)addr)->alignedsize);
else