added collection of fragmentation data
authorphil <none@none>
Wed, 9 Dec 1998 15:36:04 +0000 (15:36 +0000)
committerphil <none@none>
Wed, 9 Dec 1998 15:36:04 +0000 (15:36 +0000)
mm/allocator2.c
mm/heap2.c

index b3c36f3d5a233fb7b9b3193a45ab4b37afca850f..b31c2b2059ed9c131a05520f123d4a8d33d09573 100644 (file)
@@ -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);
+}
 
 
 
index 4e20e60f989a7032375c740a5669714cb866bb56..ac315506789cf8276a33d9df0248507eeedd9dcf 100644 (file)
@@ -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