693018 | 1996-02-25 | Fredrik Hübinette (Hubbe) | |
#include "global.h"
#ifdef GC2
|
c94c37 | 1996-03-28 | Fredrik Hübinette (Hubbe) | |
#include "array.h"
#include "list.h"
#include "mapping.h"
#include "object.h"
#include "program.h"
|
693018 | 1996-02-25 | Fredrik Hübinette (Hubbe) | | #include "gc.h"
#include "main.h"
#define GC_CONST 20
#define MIN_ALLOC_THRESHOLD 1000
|
b95bef | 1996-03-29 | Fredrik Hübinette (Hubbe) | | #define MAX_ALLOC_THRESHOLD 10000000
|
693018 | 1996-02-25 | Fredrik Hübinette (Hubbe) | | #define MULTIPLIER 0.9
|
c94c37 | 1996-03-28 | Fredrik Hübinette (Hubbe) | | #define MARKER_CHUNK_SIZE 1023
|
693018 | 1996-02-25 | Fredrik Hübinette (Hubbe) | |
INT32 num_objects;
INT32 num_allocs;
INT32 alloc_threshold = MIN_ALLOC_THRESHOLD;
static double objects_alloced;
static double objects_freed;
|
c94c37 | 1996-03-28 | Fredrik Hübinette (Hubbe) | | #define GC_REFERENCED 1
struct marker
{
struct marker *next;
void *marked;
INT32 refs;
INT32 flags;
};
struct marker_chunk
{
struct marker_chunk *next;
struct marker markers[MARKER_CHUNK_SIZE];
};
static struct marker_chunk *chunk=0;
static int markers_left_in_chunk=0;
static struct marker *new_marker()
{
if(!markers_left_in_chunk)
{
struct marker_chunk *m;
m=(struct marker_chunk *)xalloc(sizeof(struct marker_chunk));
m->next=chunk;
chunk=m;
markers_left_in_chunk=MARKER_CHUNK_SIZE;
}
markers_left_in_chunk--;
return chunk->markers + markers_left_in_chunk;
}
static struct marker **hash=0;
static int hashsize=0;
static struct marker *getmark(void *a)
{
int hashval;
struct marker *m;
hashval=((long)a)%hashsize;
for(m=hash[hashval];m;m=m->next)
if(m->marked == a)
return m;
m=new_marker();
m->marked=a;
m->refs=0;
m->flags=0;
m->next=hash[hashval];
hash[hashval]=m;
return m;
}
void gc_check(void *a)
{
getmark(a)->refs++;
}
int gc_is_referenced(void *a)
{
struct marker *m;
m=getmark(a);
#ifdef DEBUG
if(m->refs > *(INT32 *)a)
fatal("Ref counts are totally wrong!!!\n");
#endif
return m->refs < *(INT32 *)a;
}
int gc_mark(void *a)
{
struct marker *m;
m=getmark(a);
if(m->flags & GC_REFERENCED)
{
return 0;
}else{
m->flags |= GC_REFERENCED;
return 1;
}
}
int gc_do_free(void *a)
{
struct marker *m;
m=getmark(a);
return !(m->flags & GC_REFERENCED);
}
static INT32 hashprimes[] =
{
31,
31,
31,
31,
31,
31,
61,
127,
251,
541,
1151,
2111,
4327,
8803,
17903,
32321,
65599,
133153,
270001,
547453,
1109891,
2000143,
4561877,
9248339,
16777215,
33554431,
67108863,
134217727,
268435455,
536870911,
1073741823,
2147483647,
};
|
6b9216 | 1996-05-16 | Fredrik Hübinette (Hubbe) | | void do_gc(void)
|
693018 | 1996-02-25 | Fredrik Hübinette (Hubbe) | | {
double tmp;
INT32 tmp2;
|
c94c37 | 1996-03-28 | Fredrik Hübinette (Hubbe) | | struct marker_chunk *m;
|
693018 | 1996-02-25 | Fredrik Hübinette (Hubbe) | |
tmp2=num_objects;
#ifdef DEBUG
if(t_flag)
fprintf(stderr,"Garbage collecting ... ");
#endif
objects_alloced*=MULTIPLIER;
objects_alloced += (double) num_allocs;
objects_freed*=MULTIPLIER;
objects_freed += (double) num_objects;
|
c94c37 | 1996-03-28 | Fredrik Hübinette (Hubbe) | |
hashsize=my_log2(num_objects);
hashsize-=2;
if(hashsize<0) hashsize=0;
hashsize=hashprimes[hashsize];
hash=(struct marker **)xalloc(sizeof(struct marker **)*hashsize);
MEMSET((char *)hash,0,sizeof(struct marker **)*hashsize);
markers_left_in_chunk=0;
|
693018 | 1996-02-25 | Fredrik Hübinette (Hubbe) | |
gc_check_all_arrays();
|
c94c37 | 1996-03-28 | Fredrik Hübinette (Hubbe) | | gc_check_all_lists();
gc_check_all_mappings();
|
693018 | 1996-02-25 | Fredrik Hübinette (Hubbe) | | gc_check_all_programs();
gc_check_all_objects();
|
c94c37 | 1996-03-28 | Fredrik Hübinette (Hubbe) | |
gc_mark_all_arrays();
gc_mark_all_lists();
gc_mark_all_mappings();
gc_mark_all_programs();
gc_mark_all_objects();
gc_free_all_unreferenced_arrays();
gc_free_all_unreferenced_lists();
gc_free_all_unreferenced_mappings();
gc_free_all_unreferenced_programs();
gc_free_all_unreferenced_objects();
free((char *)hash);
while(m=chunk)
{
chunk=m->next;
free((char *)m);
}
|
693018 | 1996-02-25 | Fredrik Hübinette (Hubbe) | |
objects_freed -= (double) num_objects;
tmp=(double)num_objects;
tmp=tmp * GC_CONST/100.0 * (objects_alloced+1.0) / (objects_freed+1.0);
if((int)tmp < alloc_threshold + num_allocs)
{
alloc_threshold=(int)tmp;
}else{
alloc_threshold+=num_allocs;
}
if(alloc_threshold < MIN_ALLOC_THRESHOLD)
alloc_threshold = MIN_ALLOC_THRESHOLD;
|
b95bef | 1996-03-29 | Fredrik Hübinette (Hubbe) | | if(alloc_threshold > MAX_ALLOC_THRESHOLD)
alloc_threshold = MAX_ALLOC_THRESHOLD;
|
693018 | 1996-02-25 | Fredrik Hübinette (Hubbe) | | num_allocs=0;
#ifdef DEBUG
if(t_flag)
fprintf(stderr,"done (freed %ld of %ld objects).\n",
(long)(tmp2-num_objects),(long)tmp2);
#endif
}
|
c94c37 | 1996-03-28 | Fredrik Hübinette (Hubbe) | | #endif
|
693018 | 1996-02-25 | Fredrik Hübinette (Hubbe) | |
|