Move Mark_Proc Fixup_Proc and memory_in_use to NewGC struct
svn: r12268
This commit is contained in:
parent
dee6deb1be
commit
4557c6cef1
|
@ -10,6 +10,9 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include "gc2.h"
|
||||||
|
|
||||||
|
#define NUMBER_OF_TAGS 512
|
||||||
#include "newgc_internal.h"
|
#include "newgc_internal.h"
|
||||||
#include "../src/schpriv.h"
|
#include "../src/schpriv.h"
|
||||||
|
|
||||||
|
@ -84,7 +87,6 @@ static THREAD_LOCAL NewGC *GC;
|
||||||
#define INCREMENT_CYCLE_COUNT_GROWTH 1048576
|
#define INCREMENT_CYCLE_COUNT_GROWTH 1048576
|
||||||
|
|
||||||
|
|
||||||
#include "gc2.h"
|
|
||||||
#include "gc2_dump.h"
|
#include "gc2_dump.h"
|
||||||
|
|
||||||
#define BYTEPTR(x) ((char *)x)
|
#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 gc_on_free_list_tag 511
|
||||||
|
|
||||||
#define _num_tags_ 512
|
|
||||||
|
|
||||||
Size_Proc size_table[_num_tags_];
|
Size_Proc size_table[NUMBER_OF_TAGS];
|
||||||
Mark_Proc mark_table[_num_tags_];
|
Mark_Proc mark_table[NUMBER_OF_TAGS];
|
||||||
Fixup_Proc fixup_table[_num_tags_];
|
Fixup_Proc fixup_table[NUMBER_OF_TAGS];
|
||||||
|
|
||||||
/****************** Memory Pages ******************/
|
/****************** Memory Pages ******************/
|
||||||
|
|
||||||
|
@ -762,7 +763,7 @@ static void init_tagged_mpage(void **p, MPage *page)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CHECKS
|
#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);
|
GCPRINT(GCOUTF, "bad tag: %d at %lx\n", tag, (long)p);
|
||||||
GCFLUSHOUT();
|
GCFLUSHOUT();
|
||||||
CRASH(7);
|
CRASH(7);
|
||||||
|
@ -1085,7 +1086,7 @@ void GC_mark(const void *p)
|
||||||
#if CHECKS
|
#if CHECKS
|
||||||
{
|
{
|
||||||
Type_Tag tag = *(Type_Tag *)p;
|
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);
|
GCPRINT(GCOUTF, "bad tag: %d at %lx\n", tag, (long)p);
|
||||||
CRASH(11);
|
CRASH(11);
|
||||||
}
|
}
|
||||||
|
@ -1506,7 +1507,7 @@ static void do_bigblock(void **p, MPage *page, int fixup)
|
||||||
tag = *(Type_Tag *)p;
|
tag = *(Type_Tag *)p;
|
||||||
|
|
||||||
#if CHECKS
|
#if CHECKS
|
||||||
if ((tag < 0) || (tag >= _num_tags_) || !size_table[tag]) {
|
if ((tag < 0) || (tag >= NUMBER_OF_TAGS) || !size_table[tag]) {
|
||||||
CRASH(16);
|
CRASH(16);
|
||||||
}
|
}
|
||||||
prev_var_stack = GC_variable_stack;
|
prev_var_stack = GC_variable_stack;
|
||||||
|
@ -1627,7 +1628,7 @@ static void propagate_all_mpages()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CHECKS
|
#if CHECKS
|
||||||
if ((tag < 0) || (tag >= _num_tags_) || !size_table[tag]) {
|
if ((tag < 0) || (tag >= NUMBER_OF_TAGS) || !size_table[tag]) {
|
||||||
CRASH(18);
|
CRASH(18);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -2325,7 +2326,7 @@ static void fixup_tagged_mpage(void **p, MPage *page)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CHECKS
|
#if CHECKS
|
||||||
if ((tag < 0) || (tag >= _num_tags_) || !size_table[tag]) {
|
if ((tag < 0) || (tag >= NUMBER_OF_TAGS) || !size_table[tag]) {
|
||||||
GCFLUSHOUT();
|
GCFLUSHOUT();
|
||||||
CRASH(28);
|
CRASH(28);
|
||||||
}
|
}
|
||||||
|
@ -2755,7 +2756,7 @@ static void check_ptr(void **a)
|
||||||
Type_Tag tag;
|
Type_Tag tag;
|
||||||
|
|
||||||
tag = *(Type_Tag *)p;
|
tag = *(Type_Tag *)p;
|
||||||
if ((tag < 0) || (tag >= _num_tags_)
|
if ((tag < 0) || (tag >= NUMBER_OF_TAGS)
|
||||||
|| (!size_table[tag]
|
|| (!size_table[tag]
|
||||||
&& (tag != weak_box_tag)
|
&& (tag != weak_box_tag)
|
||||||
&& (tag != ephemeron_tag)
|
&& (tag != ephemeron_tag)
|
||||||
|
@ -3202,7 +3203,7 @@ static void gcollect(int full)
|
||||||
if (f->tagged) {
|
if (f->tagged) {
|
||||||
Type_Tag tag = *(Type_Tag *)f->p;
|
Type_Tag tag = *(Type_Tag *)f->p;
|
||||||
#if CHECKS
|
#if CHECKS
|
||||||
if ((tag < 0) || (tag >= _num_tags_) || !size_table[tag]) {
|
if ((tag < 0) || (tag >= NUMBER_OF_TAGS) || !size_table[tag]) {
|
||||||
CRASH(34);
|
CRASH(34);
|
||||||
}
|
}
|
||||||
#endif
|
#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]++;
|
||||||
dump_info_array[tag + _num_tags_] += size;
|
dump_info_array[tag + NUMBER_OF_TAGS] += size;
|
||||||
|
|
||||||
if (tag == trace_for_tag) {
|
if (tag == trace_for_tag) {
|
||||||
#if KEEP_BACKPOINTERS
|
#if KEEP_BACKPOINTERS
|
||||||
|
@ -4649,7 +4650,7 @@ void GC_dump_with_traces(int flags,
|
||||||
} else {
|
} else {
|
||||||
GCPRINT(GCOUTF, "Tag counts and sizes:\n");
|
GCPRINT(GCOUTF, "Tag counts and sizes:\n");
|
||||||
GCPRINT(GCOUTF, "Begin MzScheme3m\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]) {
|
if (dump_info_array[i]) {
|
||||||
char *tn, buf[256];
|
char *tn, buf[256];
|
||||||
switch(i) {
|
switch(i) {
|
||||||
|
@ -4667,7 +4668,7 @@ void GC_dump_with_traces(int flags,
|
||||||
}
|
}
|
||||||
break;
|
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");
|
GCPRINT(GCOUTF, "End MzScheme3m\n");
|
||||||
|
|
|
@ -36,6 +36,9 @@
|
||||||
#include "gc2_dump.h"
|
#include "gc2_dump.h"
|
||||||
#include "../src/schpriv.h"
|
#include "../src/schpriv.h"
|
||||||
|
|
||||||
|
/* the number of tags to use for tagged objects */
|
||||||
|
#define NUMBER_OF_TAGS 512
|
||||||
|
|
||||||
#include "newgc_internal.h"
|
#include "newgc_internal.h"
|
||||||
static THREAD_LOCAL NewGC *GC;
|
static THREAD_LOCAL NewGC *GC;
|
||||||
|
|
||||||
|
@ -74,8 +77,6 @@ static THREAD_LOCAL NewGC *GC;
|
||||||
# define LOG_WORD_SIZE 2
|
# define LOG_WORD_SIZE 2
|
||||||
#endif
|
#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 */
|
/* the size of a page we use for the internal mark stack */
|
||||||
#define STACK_PART_SIZE (1 * 1024 * 1024)
|
#define STACK_PART_SIZE (1 * 1024 * 1024)
|
||||||
|
@ -295,10 +296,6 @@ static struct mpage *pages[PAGE_TYPES];
|
||||||
|
|
||||||
/* miscellaneous variables */
|
/* miscellaneous variables */
|
||||||
static const char *zero_sized[4]; /* all 0-sized allocs get this */
|
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
|
/* 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
|
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)
|
inline static void reset_nursery(void)
|
||||||
{
|
{
|
||||||
unsigned long new_gen0_size;
|
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)
|
if(new_gen0_size > GEN0_MAX_SIZE)
|
||||||
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)
|
inline static void do_ordered_level3(void)
|
||||||
{
|
{
|
||||||
struct finalizer *temp;
|
struct finalizer *temp;
|
||||||
|
Mark_Proc *mark_table = GC->mark_table;
|
||||||
|
|
||||||
for(temp = GC_resolve(finalizers); temp; temp = GC_resolve(temp->next))
|
for(temp = GC_resolve(finalizers); temp; temp = GC_resolve(temp->next))
|
||||||
if(!marked(temp->p)) {
|
if(!marked(temp->p)) {
|
||||||
|
@ -1495,8 +1493,8 @@ void GC_gcollect(void)
|
||||||
void GC_register_traversers(short tag, Size_Proc size, Mark_Proc mark,
|
void GC_register_traversers(short tag, Size_Proc size, Mark_Proc mark,
|
||||||
Fixup_Proc fixup, int constant_Size, int atomic)
|
Fixup_Proc fixup, int constant_Size, int atomic)
|
||||||
{
|
{
|
||||||
mark_table[tag] = atomic ? (Mark_Proc)PAGE_ATOMIC : mark;
|
GC->mark_table[tag] = atomic ? (Mark_Proc)PAGE_ATOMIC : mark;
|
||||||
fixup_table[tag] = fixup;
|
GC->fixup_table[tag] = fixup;
|
||||||
}
|
}
|
||||||
|
|
||||||
long GC_get_memory_use(void *o)
|
long GC_get_memory_use(void *o)
|
||||||
|
@ -1511,7 +1509,7 @@ long GC_get_memory_use(void *o)
|
||||||
retval = custodian_usage(arg);
|
retval = custodian_usage(arg);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
retval = gen0_size_in_use() + memory_in_use;
|
retval = gen0_size_in_use() + GC->memory_in_use;
|
||||||
}
|
}
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
|
@ -1530,6 +1528,7 @@ void GC_mark(const void *const_p)
|
||||||
{
|
{
|
||||||
struct mpage *page;
|
struct mpage *page;
|
||||||
void *p = (void*)const_p;
|
void *p = (void*)const_p;
|
||||||
|
NewGC *gc = GC;
|
||||||
|
|
||||||
if(!p || (NUM(p) & 0x1)) {
|
if(!p || (NUM(p) & 0x1)) {
|
||||||
GCDEBUG((DEBUGOUTF, "Not marking %p (bad ptr)\n", p));
|
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
|
/* first check to see if this is an atomic object masquerading
|
||||||
as a tagged object; if it is, then convert it */
|
as a tagged object; if it is, then convert it */
|
||||||
if(type == PAGE_TAGGED) {
|
if(type == PAGE_TAGGED) {
|
||||||
if((unsigned long)mark_table[*(unsigned short*)p] < PAGE_TYPES)
|
if((unsigned long)gc->mark_table[*(unsigned short*)p] < PAGE_TYPES)
|
||||||
type = ohead->type = (int)(unsigned long)mark_table[*(unsigned short*)p];
|
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 */
|
/* 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)
|
inline static void internal_mark(void *p)
|
||||||
{
|
{
|
||||||
struct mpage *page = find_page(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 --
|
/* 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 */
|
because we vet bad cases out in GC_mark, above */
|
||||||
|
@ -1695,10 +1695,10 @@ inline static void internal_mark(void *p)
|
||||||
case PAGE_TAGGED:
|
case PAGE_TAGGED:
|
||||||
{
|
{
|
||||||
unsigned short tag = *(unsigned short*)start;
|
unsigned short tag = *(unsigned short*)start;
|
||||||
if((unsigned long)mark_table[tag] < PAGE_TYPES) {
|
if((unsigned long)gc->mark_table[tag] < PAGE_TYPES) {
|
||||||
/* atomic */
|
/* atomic */
|
||||||
} else
|
} else
|
||||||
mark_table[tag](start); break;
|
gc->mark_table[tag](start); break;
|
||||||
}
|
}
|
||||||
case PAGE_ATOMIC: break;
|
case PAGE_ATOMIC: break;
|
||||||
case PAGE_ARRAY: while(start < end) gcMARK(*(start++)); break;
|
case PAGE_ARRAY: while(start < end) gcMARK(*(start++)); break;
|
||||||
|
@ -1706,7 +1706,7 @@ inline static void internal_mark(void *p)
|
||||||
case PAGE_TARRAY: {
|
case PAGE_TARRAY: {
|
||||||
unsigned short tag = *(unsigned short *)start;
|
unsigned short tag = *(unsigned short *)start;
|
||||||
end -= INSET_WORDS;
|
end -= INSET_WORDS;
|
||||||
while(start < end) start += mark_table[tag](start);
|
while(start < end) start += gc->mark_table[tag](start);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1716,7 +1716,7 @@ inline static void internal_mark(void *p)
|
||||||
set_backtrace_source(p, info->type);
|
set_backtrace_source(p, info->type);
|
||||||
|
|
||||||
switch(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_ATOMIC: break;
|
||||||
case PAGE_ARRAY: {
|
case PAGE_ARRAY: {
|
||||||
void **start = p;
|
void **start = p;
|
||||||
|
@ -1728,7 +1728,7 @@ inline static void internal_mark(void *p)
|
||||||
void **start = p;
|
void **start = p;
|
||||||
void **end = PPTR(info) + (info->size - INSET_WORDS);
|
void **end = PPTR(info) + (info->size - INSET_WORDS);
|
||||||
unsigned short tag = *(unsigned short *)start;
|
unsigned short tag = *(unsigned short *)start;
|
||||||
while(start < end) start += mark_table[tag](start);
|
while(start < end) start += gc->mark_table[tag](start);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PAGE_XTAGGED: GC_mark_xtagged(p); break;
|
case PAGE_XTAGGED: GC_mark_xtagged(p); break;
|
||||||
|
@ -2172,6 +2172,7 @@ static void repair_heap(void)
|
||||||
{
|
{
|
||||||
struct mpage *page;
|
struct mpage *page;
|
||||||
int i;
|
int i;
|
||||||
|
NewGC *gc = GC;
|
||||||
|
|
||||||
for(i = 0; i < PAGE_TYPES; i++) {
|
for(i = 0; i < PAGE_TYPES; i++) {
|
||||||
for(page = pages[i]; page; page = page->next) {
|
for(page = pages[i]; page; page = page->next) {
|
||||||
|
@ -2187,7 +2188,7 @@ static void repair_heap(void)
|
||||||
page->big_page = 1; /* remove the mark */
|
page->big_page = 1; /* remove the mark */
|
||||||
switch(page->page_type) {
|
switch(page->page_type) {
|
||||||
case PAGE_TAGGED:
|
case PAGE_TAGGED:
|
||||||
fixup_table[*(unsigned short*)start](start);
|
gc->fixup_table[*(unsigned short*)start](start);
|
||||||
break;
|
break;
|
||||||
case PAGE_ATOMIC: break;
|
case PAGE_ATOMIC: break;
|
||||||
case PAGE_ARRAY:
|
case PAGE_ARRAY:
|
||||||
|
@ -2199,7 +2200,7 @@ static void repair_heap(void)
|
||||||
case PAGE_TARRAY: {
|
case PAGE_TARRAY: {
|
||||||
unsigned short tag = *(unsigned short *)start;
|
unsigned short tag = *(unsigned short *)start;
|
||||||
end -= INSET_WORDS;
|
end -= INSET_WORDS;
|
||||||
while(start < end) start += fixup_table[tag](start);
|
while(start < end) start += gc->fixup_table[tag](start);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2216,7 +2217,7 @@ static void repair_heap(void)
|
||||||
|
|
||||||
if(info->mark) {
|
if(info->mark) {
|
||||||
info->mark = 0;
|
info->mark = 0;
|
||||||
fixup_table[*(unsigned short*)(start+1)](start+1);
|
gc->fixup_table[*(unsigned short*)(start+1)](start+1);
|
||||||
} else {
|
} else {
|
||||||
info->dead = 1;
|
info->dead = 1;
|
||||||
}
|
}
|
||||||
|
@ -2254,7 +2255,7 @@ static void repair_heap(void)
|
||||||
void **tempend = (start++) + (size - INSET_WORDS);
|
void **tempend = (start++) + (size - INSET_WORDS);
|
||||||
unsigned short tag = *(unsigned short*)start;
|
unsigned short tag = *(unsigned short*)start;
|
||||||
while(start < tempend)
|
while(start < tempend)
|
||||||
start += fixup_table[tag](start);
|
start += gc->fixup_table[tag](start);
|
||||||
info->mark = 0;
|
info->mark = 0;
|
||||||
start = PPTR(info) + size;
|
start = PPTR(info) + size;
|
||||||
} else {
|
} 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: */
|
/* Free pages vacated by compaction: */
|
||||||
while (pages) {
|
while (pages) {
|
||||||
mpage *prev = pages->next;
|
mpage *prev = pages->next;
|
||||||
|
@ -2289,16 +2292,18 @@ static inline void cleanup_vacated_pages(mpage *pages) {
|
||||||
free_mpage(pages);
|
free_mpage(pages);
|
||||||
pages = prev;
|
pages = prev;
|
||||||
}
|
}
|
||||||
|
gc->release_pages = NULL;
|
||||||
}
|
}
|
||||||
static void clean_up_heap(void)
|
static void clean_up_heap(void)
|
||||||
{
|
{
|
||||||
struct mpage *work, *prev;
|
struct mpage *work, *prev;
|
||||||
int i;
|
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 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;
|
prev = work->next;
|
||||||
pagemap_remove(work);
|
pagemap_remove(work);
|
||||||
free_pages(work->addr, round_to_apage_size(work->size));
|
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++) {
|
for(i = 0; i < PAGE_TYPES; i++) {
|
||||||
struct mpage *prev = NULL;
|
struct mpage *prev = NULL;
|
||||||
|
|
||||||
if(GC->gc_full) {
|
if(gc->gc_full) {
|
||||||
work = pages[i];
|
work = pages[i];
|
||||||
while(work) {
|
while(work) {
|
||||||
if(!work->marked_on) {
|
if(!work->marked_on) {
|
||||||
|
@ -2337,11 +2342,10 @@ static void clean_up_heap(void)
|
||||||
|
|
||||||
/* since we're here anyways, compute the total memory use */
|
/* since we're here anyways, compute the total memory use */
|
||||||
for(work = pages[i]; work; work = work->next)
|
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);
|
cleanup_vacated_pages(gc);
|
||||||
GC->release_pages = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void protect_old_pages(void)
|
static void protect_old_pages(void)
|
||||||
|
@ -2383,23 +2387,23 @@ extern double scheme_get_inexact_milliseconds(void);
|
||||||
|
|
||||||
static void garbage_collect(int force_full)
|
static void garbage_collect(int force_full)
|
||||||
{
|
{
|
||||||
|
NewGC *gc = GC;
|
||||||
static unsigned long number = 0;
|
static unsigned long number = 0;
|
||||||
static unsigned int since_last_full = 0;
|
static unsigned int since_last_full = 0;
|
||||||
static unsigned int running_finalizers = 0;
|
static unsigned int running_finalizers = 0;
|
||||||
static unsigned long last_full_mem_use = (20 * 1024 * 1024);
|
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;
|
unsigned long old_gen0 = GC->gen0.current_size;
|
||||||
int next_gc_full;
|
int next_gc_full;
|
||||||
TIME_DECLS();
|
TIME_DECLS();
|
||||||
NewGC *gc = GC;
|
|
||||||
|
|
||||||
/* determine if this should be a full collection or not */
|
/* determine if this should be a full collection or not */
|
||||||
gc->gc_full = force_full || !gc->generations_available
|
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
|
#if 0
|
||||||
printf("Collection %li (full = %i): %i / %i / %i / %i %ld\n", number,
|
printf("Collection %li (full = %i): %i / %i / %i / %i %ld\n", number,
|
||||||
gc->gc_full, force_full, !generations_available,
|
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);
|
last_full_mem_use);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -2527,23 +2531,23 @@ static void garbage_collect(int force_full)
|
||||||
|
|
||||||
/* update some statistics */
|
/* update some statistics */
|
||||||
if(gc->gc_full) gc->num_major_collects++; else gc->num_minor_collects++;
|
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)
|
if(gc->gc_full)
|
||||||
since_last_full = 0;
|
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;
|
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;
|
since_last_full += 5;
|
||||||
else
|
else
|
||||||
since_last_full += 10;
|
since_last_full += 10;
|
||||||
if(gc->gc_full)
|
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 */
|
/* inform the system (if it wants us to) that we're done with collection */
|
||||||
if (GC_collect_start_callback)
|
if (GC_collect_start_callback)
|
||||||
GC_collect_end_callback();
|
GC_collect_end_callback();
|
||||||
if (GC_collect_inform_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");
|
TIME_STEP("ended");
|
||||||
|
|
||||||
|
|
|
@ -73,6 +73,9 @@ typedef struct Gen0 {
|
||||||
|
|
||||||
typedef struct NewGC {
|
typedef struct NewGC {
|
||||||
Gen0 gen0;
|
Gen0 gen0;
|
||||||
|
Mark_Proc *mark_table; /* the table of mark procs */
|
||||||
|
Fixup_Proc *fixup_table; /* the table of repair procs */
|
||||||
|
|
||||||
struct NewGC *primoridal_gc;
|
struct NewGC *primoridal_gc;
|
||||||
unsigned long max_heap_size;
|
unsigned long max_heap_size;
|
||||||
unsigned long max_pages_in_heap;
|
unsigned long max_pages_in_heap;
|
||||||
|
@ -81,6 +84,7 @@ typedef struct NewGC {
|
||||||
unsigned long actual_pages_size;
|
unsigned long actual_pages_size;
|
||||||
unsigned long in_unsafe_allocation_mode :1;
|
unsigned long in_unsafe_allocation_mode :1;
|
||||||
void (*unsafe_allocation_abort)();
|
void (*unsafe_allocation_abort)();
|
||||||
|
unsigned long memory_in_use; /* the amount of memory in use */
|
||||||
|
|
||||||
void *park[2];
|
void *park[2];
|
||||||
void *park_save[2];
|
void *park_save[2];
|
||||||
|
@ -114,6 +118,8 @@ typedef struct NewGC {
|
||||||
|
|
||||||
void NewGC_initialize(NewGC *newgc) {
|
void NewGC_initialize(NewGC *newgc) {
|
||||||
memset(newgc, 0, sizeof(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->primoridal_gc = NULL;
|
||||||
newgc->max_heap_size = 0;
|
newgc->max_heap_size = 0;
|
||||||
newgc->max_pages_in_heap = 0;
|
newgc->max_pages_in_heap = 0;
|
||||||
|
|
|
@ -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
|
ignore them outright. In the case of custodians, we do need
|
||||||
to do the check; those differences are handled by replacing
|
to do the check; those differences are handled by replacing
|
||||||
the mark procedure in mark_table. */
|
the mark procedure in mark_table. */
|
||||||
mark_table[*(unsigned short*)ptr](ptr);
|
GC->mark_table[*(unsigned short*)ptr](ptr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PAGE_ATOMIC: 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;
|
unsigned short tag = *(unsigned short*)ptr;
|
||||||
void **temp = ptr, **end = PPTR(info) + (info->size - INSET_WORDS);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
case PAGE_XTAGGED: GC_mark_xtagged(ptr); 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:
|
case PAGE_TAGGED:
|
||||||
{
|
{
|
||||||
unsigned short tag = *(unsigned short*)start;
|
unsigned short tag = *(unsigned short*)start;
|
||||||
if((unsigned long)mark_table[tag] < PAGE_TYPES) {
|
if((unsigned long)GC->mark_table[tag] < PAGE_TYPES) {
|
||||||
/* atomic */
|
/* atomic */
|
||||||
} else
|
} else
|
||||||
mark_table[tag](start); break;
|
GC->mark_table[tag](start); break;
|
||||||
}
|
}
|
||||||
case PAGE_ATOMIC: break;
|
case PAGE_ATOMIC: break;
|
||||||
case PAGE_ARRAY: while(start < end) gcMARK(*(start++)); 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: {
|
case PAGE_TARRAY: {
|
||||||
unsigned short tag = *(unsigned short *)start;
|
unsigned short tag = *(unsigned short *)start;
|
||||||
end -= INSET_WORDS;
|
end -= INSET_WORDS;
|
||||||
while(start < end) start += mark_table[tag](start);
|
while(start < end) start += GC->mark_table[tag](start);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -297,14 +297,14 @@ static void do_btc_accounting(void)
|
||||||
GC->unsafe_allocation_abort = btc_overmem_abort;
|
GC->unsafe_allocation_abort = btc_overmem_abort;
|
||||||
|
|
||||||
if(!normal_thread_mark) {
|
if(!normal_thread_mark) {
|
||||||
normal_thread_mark = mark_table[scheme_thread_type];
|
normal_thread_mark = GC->mark_table[scheme_thread_type];
|
||||||
normal_custodian_mark = mark_table[scheme_custodian_type];
|
normal_custodian_mark = GC->mark_table[scheme_custodian_type];
|
||||||
normal_cust_box_mark = mark_table[GC->cust_box_tag];
|
normal_cust_box_mark = GC->mark_table[GC->cust_box_tag];
|
||||||
}
|
}
|
||||||
mark_table[scheme_thread_type] = &BTC_thread_mark;
|
GC->mark_table[scheme_thread_type] = &BTC_thread_mark;
|
||||||
mark_table[scheme_custodian_type] = &BTC_custodian_mark;
|
GC->mark_table[scheme_custodian_type] = &BTC_custodian_mark;
|
||||||
mark_table[GC->ephemeron_tag] = btc_mark_ephemeron;
|
GC->mark_table[GC->ephemeron_tag] = btc_mark_ephemeron;
|
||||||
mark_table[GC->cust_box_tag] = BTC_cust_box_mark;
|
GC->mark_table[GC->cust_box_tag] = BTC_cust_box_mark;
|
||||||
|
|
||||||
/* clear the memory use numbers out */
|
/* clear the memory use numbers out */
|
||||||
for(i = 1; i < owner_table_top; i++)
|
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;
|
box = cur->global_prev; cur = box ? SCHEME_PTR1_VAL(box) : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
mark_table[scheme_thread_type] = normal_thread_mark;
|
GC->mark_table[scheme_thread_type] = normal_thread_mark;
|
||||||
mark_table[scheme_custodian_type] = normal_custodian_mark;
|
GC->mark_table[scheme_custodian_type] = normal_custodian_mark;
|
||||||
mark_table[GC->ephemeron_tag] = mark_ephemeron;
|
GC->mark_table[GC->ephemeron_tag] = mark_ephemeron;
|
||||||
mark_table[GC->cust_box_tag] = normal_cust_box_mark;
|
GC->mark_table[GC->cust_box_tag] = normal_cust_box_mark;
|
||||||
GC->in_unsafe_allocation_mode = 0;
|
GC->in_unsafe_allocation_mode = 0;
|
||||||
doing_memory_accounting = 0;
|
doing_memory_accounting = 0;
|
||||||
old_btc_mark = new_btc_mark;
|
old_btc_mark = new_btc_mark;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user