From e1c9ba8cf78ae2f00a0756ac4032186f69b29ade Mon Sep 17 00:00:00 2001 From: phil Date: Wed, 9 Dec 1998 15:36:04 +0000 Subject: [PATCH] added collection of fragmentation data --- mm/allocator2.c | 44 ++++++++++++++++++++++-- mm/heap2.c | 90 +++++++++++++++++++++++++++++++------------------ 2 files changed, 99 insertions(+), 35 deletions(-) diff --git a/mm/allocator2.c b/mm/allocator2.c index b3c36f3d5..b31c2b205 100644 --- a/mm/allocator2.c +++ b/mm/allocator2.c @@ -6,7 +6,7 @@ * * 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" @@ -259,7 +259,7 @@ allocator_init() { #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); @@ -492,6 +492,46 @@ allocator_dump() 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); +} diff --git a/mm/heap2.c b/mm/heap2.c index 4e20e60f9..ac3155067 100644 --- a/mm/heap2.c +++ b/mm/heap2.c @@ -21,7 +21,9 @@ #undef OFFSET //#define COLLECT_LIFESPAN -#define NEW_COLLECT_LIFESPAN +//#define NEW_COLLECT_LIFESPAN +#define COLLECT_FRAGMENTATION + #define GC_COLLECT_STATISTICS #define FINALIZER_COUNTING @@ -43,17 +45,6 @@ void gc_call (void); #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; @@ -111,6 +102,11 @@ static iMux alloc_mutex; static FILE* tracefile; #endif +#ifdef COLLECT_FRAGMENTATION +static FILE* fragfile; +static FILE* fragsizefile; +#endif + /* --- implementation */ void @@ -198,6 +194,12 @@ heap_init (SIZE size, #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__ @@ -229,6 +231,11 @@ heap_close (void) 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) { @@ -300,12 +307,6 @@ heap_add_address_to_address_list(address_list_node** list, void* address) 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 { @@ -421,11 +422,6 @@ heap_allocate (SIZE in_length, ++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); @@ -493,12 +489,23 @@ void gc_reclaim (void) 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, @@ -511,6 +518,11 @@ void gc_reclaim (void) 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", @@ -528,8 +540,12 @@ void gc_reclaim (void) 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 @@ -542,7 +558,7 @@ void gc_reclaim (void) 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 @@ -554,8 +570,21 @@ void gc_reclaim (void) 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; @@ -626,7 +655,7 @@ gc_mark_object_at (void** addr) /* 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 @@ -673,11 +702,6 @@ gc_mark_object_at (void** addr) 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 -- 2.25.1