Move Mark_Proc Fixup_Proc and memory_in_use to NewGC struct

svn: r12268
This commit is contained in:
Kevin Tew 2008-11-05 21:06:14 +00:00
parent dee6deb1be
commit 4557c6cef1
4 changed files with 79 additions and 68 deletions

View File

@ -10,6 +10,9 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "gc2.h"
#define NUMBER_OF_TAGS 512
#include "newgc_internal.h"
#include "../src/schpriv.h"
@ -84,7 +87,6 @@ static THREAD_LOCAL NewGC *GC;
#define INCREMENT_CYCLE_COUNT_GROWTH 1048576
#include "gc2.h"
#include "gc2_dump.h"
#define BYTEPTR(x) ((char *)x)
@ -171,11 +173,10 @@ Type_Tag weak_array_tag = 42; /* set by client */
#define gc_on_free_list_tag 511
#define _num_tags_ 512
Size_Proc size_table[_num_tags_];
Mark_Proc mark_table[_num_tags_];
Fixup_Proc fixup_table[_num_tags_];
Size_Proc size_table[NUMBER_OF_TAGS];
Mark_Proc mark_table[NUMBER_OF_TAGS];
Fixup_Proc fixup_table[NUMBER_OF_TAGS];
/****************** Memory Pages ******************/
@ -762,7 +763,7 @@ static void init_tagged_mpage(void **p, MPage *page)
#endif
#if CHECKS
if ((tag < 0) || (tag >= _num_tags_) || !size_table[tag]) {
if ((tag < 0) || (tag >= NUMBER_OF_TAGS) || !size_table[tag]) {
GCPRINT(GCOUTF, "bad tag: %d at %lx\n", tag, (long)p);
GCFLUSHOUT();
CRASH(7);
@ -1085,7 +1086,7 @@ void GC_mark(const void *p)
#if CHECKS
{
Type_Tag tag = *(Type_Tag *)p;
if ((tag < 0) || (tag >= _num_tags_) || !size_table[tag]) {
if ((tag < 0) || (tag >= NUMBER_OF_TAGS) || !size_table[tag]) {
GCPRINT(GCOUTF, "bad tag: %d at %lx\n", tag, (long)p);
CRASH(11);
}
@ -1506,7 +1507,7 @@ static void do_bigblock(void **p, MPage *page, int fixup)
tag = *(Type_Tag *)p;
#if CHECKS
if ((tag < 0) || (tag >= _num_tags_) || !size_table[tag]) {
if ((tag < 0) || (tag >= NUMBER_OF_TAGS) || !size_table[tag]) {
CRASH(16);
}
prev_var_stack = GC_variable_stack;
@ -1627,7 +1628,7 @@ static void propagate_all_mpages()
#endif
#if CHECKS
if ((tag < 0) || (tag >= _num_tags_) || !size_table[tag]) {
if ((tag < 0) || (tag >= NUMBER_OF_TAGS) || !size_table[tag]) {
CRASH(18);
}
#endif
@ -2325,7 +2326,7 @@ static void fixup_tagged_mpage(void **p, MPage *page)
#endif
#if CHECKS
if ((tag < 0) || (tag >= _num_tags_) || !size_table[tag]) {
if ((tag < 0) || (tag >= NUMBER_OF_TAGS) || !size_table[tag]) {
GCFLUSHOUT();
CRASH(28);
}
@ -2755,7 +2756,7 @@ static void check_ptr(void **a)
Type_Tag tag;
tag = *(Type_Tag *)p;
if ((tag < 0) || (tag >= _num_tags_)
if ((tag < 0) || (tag >= NUMBER_OF_TAGS)
|| (!size_table[tag]
&& (tag != weak_box_tag)
&& (tag != ephemeron_tag)
@ -3202,7 +3203,7 @@ static void gcollect(int full)
if (f->tagged) {
Type_Tag tag = *(Type_Tag *)f->p;
#if CHECKS
if ((tag < 0) || (tag >= _num_tags_) || !size_table[tag]) {
if ((tag < 0) || (tag >= NUMBER_OF_TAGS) || !size_table[tag]) {
CRASH(34);
}
#endif
@ -4316,7 +4317,7 @@ static long scan_tagged_mpage(void **p, MPage *page, short trace_for_tag,
}
dump_info_array[tag]++;
dump_info_array[tag + _num_tags_] += size;
dump_info_array[tag + NUMBER_OF_TAGS] += size;
if (tag == trace_for_tag) {
#if KEEP_BACKPOINTERS
@ -4649,7 +4650,7 @@ void GC_dump_with_traces(int flags,
} else {
GCPRINT(GCOUTF, "Tag counts and sizes:\n");
GCPRINT(GCOUTF, "Begin MzScheme3m\n");
for (i = 0; i < _num_tags_; i++) {
for (i = 0; i < NUMBER_OF_TAGS; i++) {
if (dump_info_array[i]) {
char *tn, buf[256];
switch(i) {
@ -4667,7 +4668,7 @@ void GC_dump_with_traces(int flags,
}
break;
}
GCPRINT(GCOUTF, " %20.20s: %10ld %10ld\n", tn, dump_info_array[i], (dump_info_array[i + _num_tags_]) << LOG_WORD_SIZE);
GCPRINT(GCOUTF, " %20.20s: %10ld %10ld\n", tn, dump_info_array[i], (dump_info_array[i + NUMBER_OF_TAGS]) << LOG_WORD_SIZE);
}
}
GCPRINT(GCOUTF, "End MzScheme3m\n");

View File

@ -36,6 +36,9 @@
#include "gc2_dump.h"
#include "../src/schpriv.h"
/* the number of tags to use for tagged objects */
#define NUMBER_OF_TAGS 512
#include "newgc_internal.h"
static THREAD_LOCAL NewGC *GC;
@ -74,8 +77,6 @@ static THREAD_LOCAL NewGC *GC;
# define LOG_WORD_SIZE 2
#endif
/* the number of tags to use for tagged objects */
#define NUMBER_OF_TAGS 512
/* the size of a page we use for the internal mark stack */
#define STACK_PART_SIZE (1 * 1024 * 1024)
@ -295,10 +296,6 @@ static struct mpage *pages[PAGE_TYPES];
/* miscellaneous variables */
static const char *zero_sized[4]; /* all 0-sized allocs get this */
static Mark_Proc mark_table[NUMBER_OF_TAGS]; /* the table of mark procs */
static Fixup_Proc fixup_table[NUMBER_OF_TAGS]; /* the table of repair procs */
static unsigned long memory_in_use = 0; /* the amount of memory in use */
static int avoid_collection;
/* These procedures modify or use the page map. The page map provides us very
fast mappings from pointers to the page the reside on, if any. The page
@ -666,7 +663,7 @@ inline static void resize_gen0(unsigned long new_size)
inline static void reset_nursery(void)
{
unsigned long new_gen0_size;
new_gen0_size = NUM((GEN0_SIZE_FACTOR * (float)memory_in_use) + GEN0_SIZE_ADDITION);
new_gen0_size = NUM((GEN0_SIZE_FACTOR * (float)GC->memory_in_use) + GEN0_SIZE_ADDITION);
if(new_gen0_size > GEN0_MAX_SIZE)
new_gen0_size = GEN0_MAX_SIZE;
@ -1086,6 +1083,7 @@ inline static void check_finalizers(int level)
inline static void do_ordered_level3(void)
{
struct finalizer *temp;
Mark_Proc *mark_table = GC->mark_table;
for(temp = GC_resolve(finalizers); temp; temp = GC_resolve(temp->next))
if(!marked(temp->p)) {
@ -1495,8 +1493,8 @@ void GC_gcollect(void)
void GC_register_traversers(short tag, Size_Proc size, Mark_Proc mark,
Fixup_Proc fixup, int constant_Size, int atomic)
{
mark_table[tag] = atomic ? (Mark_Proc)PAGE_ATOMIC : mark;
fixup_table[tag] = fixup;
GC->mark_table[tag] = atomic ? (Mark_Proc)PAGE_ATOMIC : mark;
GC->fixup_table[tag] = fixup;
}
long GC_get_memory_use(void *o)
@ -1511,7 +1509,7 @@ long GC_get_memory_use(void *o)
retval = custodian_usage(arg);
}
} else {
retval = gen0_size_in_use() + memory_in_use;
retval = gen0_size_in_use() + GC->memory_in_use;
}
return retval;
@ -1530,6 +1528,7 @@ void GC_mark(const void *const_p)
{
struct mpage *page;
void *p = (void*)const_p;
NewGC *gc = GC;
if(!p || (NUM(p) & 0x1)) {
GCDEBUG((DEBUGOUTF, "Not marking %p (bad ptr)\n", p));
@ -1606,8 +1605,8 @@ void GC_mark(const void *const_p)
/* first check to see if this is an atomic object masquerading
as a tagged object; if it is, then convert it */
if(type == PAGE_TAGGED) {
if((unsigned long)mark_table[*(unsigned short*)p] < PAGE_TYPES)
type = ohead->type = (int)(unsigned long)mark_table[*(unsigned short*)p];
if((unsigned long)gc->mark_table[*(unsigned short*)p] < PAGE_TYPES)
type = ohead->type = (int)(unsigned long)gc->mark_table[*(unsigned short*)p];
}
/* now set us up for the search for where to put this thing */
@ -1682,6 +1681,7 @@ void GC_mark(const void *const_p)
inline static void internal_mark(void *p)
{
struct mpage *page = find_page(p);
NewGC *gc = GC;
/* we can assume a lot here -- like it's a valid pointer with a page --
because we vet bad cases out in GC_mark, above */
@ -1695,10 +1695,10 @@ inline static void internal_mark(void *p)
case PAGE_TAGGED:
{
unsigned short tag = *(unsigned short*)start;
if((unsigned long)mark_table[tag] < PAGE_TYPES) {
if((unsigned long)gc->mark_table[tag] < PAGE_TYPES) {
/* atomic */
} else
mark_table[tag](start); break;
gc->mark_table[tag](start); break;
}
case PAGE_ATOMIC: break;
case PAGE_ARRAY: while(start < end) gcMARK(*(start++)); break;
@ -1706,7 +1706,7 @@ inline static void internal_mark(void *p)
case PAGE_TARRAY: {
unsigned short tag = *(unsigned short *)start;
end -= INSET_WORDS;
while(start < end) start += mark_table[tag](start);
while(start < end) start += gc->mark_table[tag](start);
break;
}
}
@ -1716,7 +1716,7 @@ inline static void internal_mark(void *p)
set_backtrace_source(p, info->type);
switch(info->type) {
case PAGE_TAGGED: mark_table[*(unsigned short*)p](p); break;
case PAGE_TAGGED: gc->mark_table[*(unsigned short*)p](p); break;
case PAGE_ATOMIC: break;
case PAGE_ARRAY: {
void **start = p;
@ -1728,7 +1728,7 @@ inline static void internal_mark(void *p)
void **start = p;
void **end = PPTR(info) + (info->size - INSET_WORDS);
unsigned short tag = *(unsigned short *)start;
while(start < end) start += mark_table[tag](start);
while(start < end) start += gc->mark_table[tag](start);
break;
}
case PAGE_XTAGGED: GC_mark_xtagged(p); break;
@ -2172,6 +2172,7 @@ static void repair_heap(void)
{
struct mpage *page;
int i;
NewGC *gc = GC;
for(i = 0; i < PAGE_TYPES; i++) {
for(page = pages[i]; page; page = page->next) {
@ -2187,7 +2188,7 @@ static void repair_heap(void)
page->big_page = 1; /* remove the mark */
switch(page->page_type) {
case PAGE_TAGGED:
fixup_table[*(unsigned short*)start](start);
gc->fixup_table[*(unsigned short*)start](start);
break;
case PAGE_ATOMIC: break;
case PAGE_ARRAY:
@ -2199,7 +2200,7 @@ static void repair_heap(void)
case PAGE_TARRAY: {
unsigned short tag = *(unsigned short *)start;
end -= INSET_WORDS;
while(start < end) start += fixup_table[tag](start);
while(start < end) start += gc->fixup_table[tag](start);
break;
}
}
@ -2216,7 +2217,7 @@ static void repair_heap(void)
if(info->mark) {
info->mark = 0;
fixup_table[*(unsigned short*)(start+1)](start+1);
gc->fixup_table[*(unsigned short*)(start+1)](start+1);
} else {
info->dead = 1;
}
@ -2254,7 +2255,7 @@ static void repair_heap(void)
void **tempend = (start++) + (size - INSET_WORDS);
unsigned short tag = *(unsigned short*)start;
while(start < tempend)
start += fixup_table[tag](start);
start += gc->fixup_table[tag](start);
info->mark = 0;
start = PPTR(info) + size;
} else {
@ -2279,7 +2280,9 @@ static void repair_heap(void)
}
}
static inline void cleanup_vacated_pages(mpage *pages) {
static inline void cleanup_vacated_pages(NewGC *gc) {
mpage *pages = gc->release_pages;
/* Free pages vacated by compaction: */
while (pages) {
mpage *prev = pages->next;
@ -2289,16 +2292,18 @@ static inline void cleanup_vacated_pages(mpage *pages) {
free_mpage(pages);
pages = prev;
}
gc->release_pages = NULL;
}
static void clean_up_heap(void)
{
struct mpage *work, *prev;
int i;
NewGC *gc = GC;
memory_in_use = 0;
gc->memory_in_use = 0;
/* For the purposes of this little loop, s/prev/next/ */
for(work = GC->gen0.big_pages; work; work = prev) {
for(work = gc->gen0.big_pages; work; work = prev) {
prev = work->next;
pagemap_remove(work);
free_pages(work->addr, round_to_apage_size(work->size));
@ -2308,7 +2313,7 @@ static void clean_up_heap(void)
for(i = 0; i < PAGE_TYPES; i++) {
struct mpage *prev = NULL;
if(GC->gc_full) {
if(gc->gc_full) {
work = pages[i];
while(work) {
if(!work->marked_on) {
@ -2337,11 +2342,10 @@ static void clean_up_heap(void)
/* since we're here anyways, compute the total memory use */
for(work = pages[i]; work; work = work->next)
memory_in_use += work->size;
gc->memory_in_use += work->size;
}
cleanup_vacated_pages(GC->release_pages);
GC->release_pages = NULL;
cleanup_vacated_pages(gc);
}
static void protect_old_pages(void)
@ -2383,23 +2387,23 @@ extern double scheme_get_inexact_milliseconds(void);
static void garbage_collect(int force_full)
{
NewGC *gc = GC;
static unsigned long number = 0;
static unsigned int since_last_full = 0;
static unsigned int running_finalizers = 0;
static unsigned long last_full_mem_use = (20 * 1024 * 1024);
unsigned long old_mem_use = memory_in_use;
unsigned long old_mem_use = gc->memory_in_use;
unsigned long old_gen0 = GC->gen0.current_size;
int next_gc_full;
TIME_DECLS();
NewGC *gc = GC;
/* determine if this should be a full collection or not */
gc->gc_full = force_full || !gc->generations_available
|| (since_last_full > 100) || (memory_in_use > (2 * last_full_mem_use));
|| (since_last_full > 100) || (gc->memory_in_use > (2 * last_full_mem_use));
#if 0
printf("Collection %li (full = %i): %i / %i / %i / %i %ld\n", number,
gc->gc_full, force_full, !generations_available,
(since_last_full > 100), (memory_in_use > (2 * last_full_mem_use)),
(since_last_full > 100), (gc->memory_in_use > (2 * last_full_mem_use)),
last_full_mem_use);
#endif
@ -2527,23 +2531,23 @@ static void garbage_collect(int force_full)
/* update some statistics */
if(gc->gc_full) gc->num_major_collects++; else gc->num_minor_collects++;
if(gc->peak_memory_use < memory_in_use) gc->peak_memory_use = memory_in_use;
if(gc->peak_memory_use < gc->memory_in_use) gc->peak_memory_use = gc->memory_in_use;
if(gc->gc_full)
since_last_full = 0;
else if((float)(memory_in_use - old_mem_use) < (0.1 * (float)old_mem_use))
else if((float)(gc->memory_in_use - old_mem_use) < (0.1 * (float)old_mem_use))
since_last_full += 1;
else if((float)(memory_in_use - old_mem_use) < (0.4 * (float)old_mem_use))
else if((float)(gc->memory_in_use - old_mem_use) < (0.4 * (float)old_mem_use))
since_last_full += 5;
else
since_last_full += 10;
if(gc->gc_full)
last_full_mem_use = memory_in_use;
last_full_mem_use = gc->memory_in_use;
/* inform the system (if it wants us to) that we're done with collection */
if (GC_collect_start_callback)
GC_collect_end_callback();
if (GC_collect_inform_callback)
GC_collect_inform_callback(gc->gc_full, old_mem_use + old_gen0, memory_in_use);
GC_collect_inform_callback(gc->gc_full, old_mem_use + old_gen0, gc->memory_in_use);
TIME_STEP("ended");

View File

@ -73,6 +73,9 @@ typedef struct Gen0 {
typedef struct NewGC {
Gen0 gen0;
Mark_Proc *mark_table; /* the table of mark procs */
Fixup_Proc *fixup_table; /* the table of repair procs */
struct NewGC *primoridal_gc;
unsigned long max_heap_size;
unsigned long max_pages_in_heap;
@ -81,6 +84,7 @@ typedef struct NewGC {
unsigned long actual_pages_size;
unsigned long in_unsafe_allocation_mode :1;
void (*unsafe_allocation_abort)();
unsigned long memory_in_use; /* the amount of memory in use */
void *park[2];
void *park_save[2];
@ -114,6 +118,8 @@ typedef struct NewGC {
void NewGC_initialize(NewGC *newgc) {
memset(newgc, 0, sizeof(NewGC));
newgc->mark_table = malloc(NUMBER_OF_TAGS * sizeof (Mark_Proc));
newgc->fixup_table = malloc(NUMBER_OF_TAGS * sizeof (Fixup_Proc));
newgc->primoridal_gc = NULL;
newgc->max_heap_size = 0;
newgc->max_pages_in_heap = 0;

View File

@ -208,7 +208,7 @@ inline static void mark_normal_obj(struct mpage *page, void *ptr)
ignore them outright. In the case of custodians, we do need
to do the check; those differences are handled by replacing
the mark procedure in mark_table. */
mark_table[*(unsigned short*)ptr](ptr);
GC->mark_table[*(unsigned short*)ptr](ptr);
break;
}
case PAGE_ATOMIC: break;
@ -224,7 +224,7 @@ inline static void mark_normal_obj(struct mpage *page, void *ptr)
unsigned short tag = *(unsigned short*)ptr;
void **temp = ptr, **end = PPTR(info) + (info->size - INSET_WORDS);
while(temp < end) temp += mark_table[tag](temp);
while(temp < end) temp += GC->mark_table[tag](temp);
break;
}
case PAGE_XTAGGED: GC_mark_xtagged(ptr); break;
@ -240,10 +240,10 @@ inline static void mark_acc_big_page(struct mpage *page)
case PAGE_TAGGED:
{
unsigned short tag = *(unsigned short*)start;
if((unsigned long)mark_table[tag] < PAGE_TYPES) {
if((unsigned long)GC->mark_table[tag] < PAGE_TYPES) {
/* atomic */
} else
mark_table[tag](start); break;
GC->mark_table[tag](start); break;
}
case PAGE_ATOMIC: break;
case PAGE_ARRAY: while(start < end) gcMARK(*(start++)); break;
@ -251,7 +251,7 @@ inline static void mark_acc_big_page(struct mpage *page)
case PAGE_TARRAY: {
unsigned short tag = *(unsigned short *)start;
end -= INSET_WORDS;
while(start < end) start += mark_table[tag](start);
while(start < end) start += GC->mark_table[tag](start);
break;
}
}
@ -297,14 +297,14 @@ static void do_btc_accounting(void)
GC->unsafe_allocation_abort = btc_overmem_abort;
if(!normal_thread_mark) {
normal_thread_mark = mark_table[scheme_thread_type];
normal_custodian_mark = mark_table[scheme_custodian_type];
normal_cust_box_mark = mark_table[GC->cust_box_tag];
normal_thread_mark = GC->mark_table[scheme_thread_type];
normal_custodian_mark = GC->mark_table[scheme_custodian_type];
normal_cust_box_mark = GC->mark_table[GC->cust_box_tag];
}
mark_table[scheme_thread_type] = &BTC_thread_mark;
mark_table[scheme_custodian_type] = &BTC_custodian_mark;
mark_table[GC->ephemeron_tag] = btc_mark_ephemeron;
mark_table[GC->cust_box_tag] = BTC_cust_box_mark;
GC->mark_table[scheme_thread_type] = &BTC_thread_mark;
GC->mark_table[scheme_custodian_type] = &BTC_custodian_mark;
GC->mark_table[GC->ephemeron_tag] = btc_mark_ephemeron;
GC->mark_table[GC->cust_box_tag] = BTC_cust_box_mark;
/* clear the memory use numbers out */
for(i = 1; i < owner_table_top; i++)
@ -333,10 +333,10 @@ static void do_btc_accounting(void)
box = cur->global_prev; cur = box ? SCHEME_PTR1_VAL(box) : NULL;
}
mark_table[scheme_thread_type] = normal_thread_mark;
mark_table[scheme_custodian_type] = normal_custodian_mark;
mark_table[GC->ephemeron_tag] = mark_ephemeron;
mark_table[GC->cust_box_tag] = normal_cust_box_mark;
GC->mark_table[scheme_thread_type] = normal_thread_mark;
GC->mark_table[scheme_custodian_type] = normal_custodian_mark;
GC->mark_table[GC->ephemeron_tag] = mark_ephemeron;
GC->mark_table[GC->cust_box_tag] = normal_cust_box_mark;
GC->in_unsafe_allocation_mode = 0;
doing_memory_accounting = 0;
old_btc_mark = new_btc_mark;