/*
* cacao/mm/allocator.h
- * $Id: allocator.h 93 1998-11-25 11:49:36Z phil $
+ * $Id: allocator.h 105 1998-12-10 17:48:53Z phil $
*/
#ifndef __allocator_h_
#define __allocator_h_
+#include "bitmap2.h"
+
#ifndef YES
# define YES 1
#endif
void allocator_init(void);
void allocator_reset(void);
+void allocator_mark_free_kludge(BITBLOCK* bitmap);
+
+unsigned char find_highest(SIZE bits);
+
#endif /* !defined(__allocator_h_) */
*
* Authors: Philipp Tomsich EMAIL: cacao@complang.tuwien.ac.at
*
- * $Id: allocator2.c 104 1998-12-09 15:36:04Z phil $
+ * $Id: allocator2.c 105 1998-12-10 17:48:53Z phil $
*/
#include "allocator.h"
{
#if 0
fprintf(stderr,
- "allocator_init: $Id: allocator2.c 104 1998-12-09 15:36:04Z phil $\n\n");
+ "allocator_init: $Id: allocator2.c 105 1998-12-10 17:48:53Z phil $\n\n");
fprintf(stderr, "\t%d bit addresses\n", ADDRESS);
fprintf(stderr, "\t%d bit alignment\n", ALIGN);
}
+void allocator_mark_free_kludge(BITBLOCK* bitmap)
+{
+ int i;
+
+ for (i = 1; i <= 1 << EXACT; ++i) {
+ FREE_EXACT* chunk = freelist_exact[i];
+
+ while (chunk) {
+ bitmap_setbit(bitmap, chunk);
+ chunk = chunk->next;
+ }
+ }
+
+ for (i = 0; i < LARGE << SUBBIT; ++i) {
+ FREE_LARGE* chunk = freelist_large[i];
+
+ while (chunk) {
+ bitmap_setbit(bitmap, chunk);
+ chunk = chunk->next;
+ }
+ }
+}
+
/*
* These are local overrides for various environment variables in Emacs.
#undef ALIGN
#undef OFFSET
+//#define PSEUDO_GENERATIONAL
//#define COLLECT_LIFESPAN
//#define NEW_COLLECT_LIFESPAN
-#define COLLECT_FRAGMENTATION
+//#define COLLECT_FRAGMENTATION
-#define GC_COLLECT_STATISTICS
-#define FINALIZER_COUNTING
+//#define GC_COLLECT_STATISTICS
+//#define FINALIZER_COUNTING
#undef STRUCTURES_ON_HEAP
//#define STRUCTURES_ON_HEAP
static
void gc_reclaim (void)
{
+#ifdef PSEUDO_GENERATIONAL
+ static void* generation_start = 0;
+ staitc int generation_num = 0;
+#endif
void* free_start;
void* free_end = heap_base;
BITBLOCK* temp_bits;
unsigned long free_fragments = 0;
#endif
+#ifdef PSEUDO_GENERATIONAL
+ if (!generation_start || !(generation_start % 5))
+ generation_start = heap_base;
+#endif
+
/* 1. reset the freelists */
+
+#if 1
+ allocator_mark_free_kludge(start_bits); /* this line will be kicked out, when
+ the SIZE_FROM_CLASSINFO reclaim
+ is implemented (very soon!!) */
+#endif
+
allocator_reset();
/* 2. reclaim unmarked objects */
}
} else {
free_end = heap_top;
-#ifdef NEW_COLLECT_LIFESPAN
- lifespan_free(free_start, free_end);
-#endif
}
}
#endif
#endif
/* 3.3. update heap_top */
- if (free_start < heap_top)
+ if (free_start < heap_top) {
heap_top = free_start;
+#ifdef NEW_COLLECT_LIFESPAN
+ lifespan_free(free_start, free_end);
+#endif
+ }
if (heap_top < heap_limit)
bitmap_setbit(start_bits, heap_top);
#ifdef COLLECT_LIFESPAN
fprintf(tracefile, "heap_top\t0x%lx\n", heap_top);
#endif
+
+#ifdef PSEUDO_GENERATIONAL
+ generation_start = heap_top;
+#endif
}
__inline__
/* 1.a. if addr doesn't point into the heap, return. */
- if ((unsigned long)addr - (unsigned long)heap_base >= heap_size) {
+ if ((unsigned long)addr - (unsigned long)heap_base >=
+ (heap_top - heap_base)) {
#ifdef GC_COLLECT_STATISTICS
++gc_mark_not_inheap;
#endif
/*
* cacao/mm/lifespan.c
- * $Id: lifespan.c 100 1998-11-30 22:30:41Z phil $
+ * $Id: lifespan.c 105 1998-12-10 17:48:53Z phil $
*/
#include "mm.h"
typedef struct {
unsigned long time;
+ unsigned long number;
unsigned long size;
} lifespan_object;
static unsigned long current_time = 0;
+static unsigned long current_number = 0;
static lifespan_object** lifespan_objects = NULL;
static lifespan_object** lifespan_objects_end = NULL;
static void* lifespan_objects_off = NULL;
static FILE* lifespan_file = NULL;
+static unsigned long lifespan_histo_size[64] = {};
+static unsigned long lifespan_histo_lifespan[64] = {};
+
void lifespan_init(void* heap_base, unsigned long heap_size)
{
current_time = 0;
static __inline__ void lifespan_free_object(lifespan_object** o)
{
+ int size, high = 0;
/* file format: alloc time, size, lifespan */
if (*o) {
- fprintf(lifespan_file, "%ld\t%ld\t%ld\n", (*o)->time, (*o)->size, current_time - (*o)->time);
+ fprintf(lifespan_file,
+ "%ld\t%ld\t%ld\t%ld\t%ld\n",
+ (*o)->number,
+ (*o)->time,
+ (*o)->size,
+ current_number - (*o)->number,
+ current_time - (*o)->time);
+
+ /* histo_size */
+ size = (*o)->size;
+ while (size) {
+ ++high;
+ size = size >> 1;
+ }
+
+ ++lifespan_histo_size[high];
+
+ /* histo_life */
+ high = 0;
+ size = current_time - (*o)->time;
+ while (size) {
+ ++high;
+ size = size >> 1;
+ }
+
+ ++lifespan_histo_lifespan[high];
+
free(*o);
*o = NULL;
}
void lifespan_emit()
{
/* emit summary */
+ int i;
+
+ for (i = 4; i < 24; ++i)
+ fprintf(stderr, "%Lu-%Lu\t%Lu\n",
+ (1LL << (i-1)),
+ (1LL << i) - 1,
+ lifespan_histo_size[i]);
+
+ fprintf(stderr, "\n\n\n");
+
+ for (i = 4; i < 24; ++i)
+ fprintf(stderr, "%Lu-%Lu\t%Lu\n",
+ (1LL << (i-1)),
+ (1LL << i) - 1,
+ lifespan_histo_lifespan[i]);
}
void lifespan_free(void** from, void** limit)
}
(*object)->time = current_time;
(*object)->size = size;
+ (*object)->number = ++current_number;
current_time += size;
}