Moved normal_*_mark to NewGC struct
svn: r12271
This commit is contained in:
parent
a8b5999a19
commit
13f3eefa6c
|
@ -1125,126 +1125,6 @@ inline static void reset_weak_finalizers(void)
|
||||||
#undef is_marked
|
#undef is_marked
|
||||||
#undef weak_box_resolve
|
#undef weak_box_resolve
|
||||||
|
|
||||||
/*****************************************************************************/
|
|
||||||
/* thread list */
|
|
||||||
/*****************************************************************************/
|
|
||||||
#ifdef NEWGC_BTC_ACCOUNT
|
|
||||||
inline static int current_owner(Scheme_Custodian *c);
|
|
||||||
|
|
||||||
struct gc_thread_info {
|
|
||||||
void *thread;
|
|
||||||
int owner;
|
|
||||||
struct gc_thread_info *next;
|
|
||||||
};
|
|
||||||
|
|
||||||
static Mark_Proc normal_thread_mark = NULL;
|
|
||||||
static Mark_Proc normal_custodian_mark = NULL;
|
|
||||||
static Mark_Proc normal_cust_box_mark = NULL;
|
|
||||||
static struct gc_thread_info *threads = NULL;
|
|
||||||
|
|
||||||
|
|
||||||
inline static void register_new_thread(void *t, void *c)
|
|
||||||
{
|
|
||||||
struct gc_thread_info *work;
|
|
||||||
|
|
||||||
work = (struct gc_thread_info *)malloc(sizeof(struct gc_thread_info));
|
|
||||||
if (!work) out_of_memory();
|
|
||||||
((Scheme_Thread *)t)->gc_info = work;
|
|
||||||
work->owner = current_owner((Scheme_Custodian *)c);
|
|
||||||
work->thread = t;
|
|
||||||
work->next = threads;
|
|
||||||
threads = work;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline static void register_thread(void *t, void *c)
|
|
||||||
{
|
|
||||||
struct gc_thread_info *work;
|
|
||||||
|
|
||||||
work = ((Scheme_Thread *)t)->gc_info;
|
|
||||||
work->owner = current_owner((Scheme_Custodian *)c);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline static void mark_threads(int owner)
|
|
||||||
{
|
|
||||||
struct gc_thread_info *work;
|
|
||||||
|
|
||||||
for(work = threads; work; work = work->next)
|
|
||||||
if(work->owner == owner) {
|
|
||||||
if (((Scheme_Thread *)work->thread)->running) {
|
|
||||||
normal_thread_mark(work->thread);
|
|
||||||
if (work->thread == scheme_current_thread) {
|
|
||||||
GC_mark_variable_stack(GC_variable_stack, 0, get_stack_base(), NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline static void mark_cust_boxes(Scheme_Custodian *cur)
|
|
||||||
{
|
|
||||||
Scheme_Object *pr, *prev = NULL, *next;
|
|
||||||
GC_Weak_Box *wb;
|
|
||||||
|
|
||||||
/* cust boxes is a list of weak boxes to cust boxes */
|
|
||||||
|
|
||||||
pr = cur->cust_boxes;
|
|
||||||
while (pr) {
|
|
||||||
wb = (GC_Weak_Box *)SCHEME_CAR(pr);
|
|
||||||
next = SCHEME_CDR(pr);
|
|
||||||
if (wb->val) {
|
|
||||||
normal_cust_box_mark(wb->val);
|
|
||||||
prev = pr;
|
|
||||||
} else {
|
|
||||||
if (prev)
|
|
||||||
SCHEME_CDR(prev) = next;
|
|
||||||
else
|
|
||||||
cur->cust_boxes = next;
|
|
||||||
}
|
|
||||||
pr = next;
|
|
||||||
}
|
|
||||||
cur->cust_boxes = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline static void clean_up_thread_list(void)
|
|
||||||
{
|
|
||||||
struct gc_thread_info *work = threads, *prev = NULL;
|
|
||||||
|
|
||||||
while(work) {
|
|
||||||
if(!find_page(work->thread) || marked(work->thread)) {
|
|
||||||
work->thread = GC_resolve(work->thread);
|
|
||||||
prev = work;
|
|
||||||
work = work->next;
|
|
||||||
} else {
|
|
||||||
struct gc_thread_info *next = work->next;
|
|
||||||
|
|
||||||
if(prev) prev->next = next;
|
|
||||||
if(!prev) threads = next;
|
|
||||||
free(work);
|
|
||||||
work = next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline static int thread_get_owner(void *p)
|
|
||||||
{
|
|
||||||
return ((Scheme_Thread *)p)->gc_info->owner;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef NEWGC_BTC_ACCOUNT
|
|
||||||
# define register_thread(t,c) /* */
|
|
||||||
# define register_new_thread(t,c) /* */
|
|
||||||
# define clean_up_thread_list() /* */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void GC_register_thread(void *t, void *c)
|
|
||||||
{
|
|
||||||
register_thread(t, c);
|
|
||||||
}
|
|
||||||
void GC_register_new_thread(void *t, void *c)
|
|
||||||
{
|
|
||||||
register_new_thread(t, c);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Internal Stack Routines */
|
/* Internal Stack Routines */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -1348,6 +1228,80 @@ inline static void reset_pointer_stack(void)
|
||||||
mark_stack->top = PPTR(mark_stack) + 4;
|
mark_stack->top = PPTR(mark_stack) + 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* thread list */
|
||||||
|
/*****************************************************************************/
|
||||||
|
#ifdef NEWGC_BTC_ACCOUNT
|
||||||
|
inline static int current_owner(Scheme_Custodian *c);
|
||||||
|
|
||||||
|
struct gc_thread_info {
|
||||||
|
void *thread;
|
||||||
|
int owner;
|
||||||
|
struct gc_thread_info *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct gc_thread_info *threads = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
inline static void register_new_thread(void *t, void *c)
|
||||||
|
{
|
||||||
|
struct gc_thread_info *work;
|
||||||
|
|
||||||
|
work = (struct gc_thread_info *)malloc(sizeof(struct gc_thread_info));
|
||||||
|
((Scheme_Thread *)t)->gc_info = work;
|
||||||
|
work->owner = current_owner((Scheme_Custodian *)c);
|
||||||
|
work->thread = t;
|
||||||
|
work->next = threads;
|
||||||
|
threads = work;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static void register_thread(void *t, void *c)
|
||||||
|
{
|
||||||
|
struct gc_thread_info *work;
|
||||||
|
|
||||||
|
work = ((Scheme_Thread *)t)->gc_info;
|
||||||
|
work->owner = current_owner((Scheme_Custodian *)c);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static void mark_threads(int owner)
|
||||||
|
{
|
||||||
|
struct gc_thread_info *work;
|
||||||
|
|
||||||
|
for(work = threads; work; work = work->next)
|
||||||
|
if(work->owner == owner) {
|
||||||
|
if (((Scheme_Thread *)work->thread)->running) {
|
||||||
|
GC->normal_thread_mark(work->thread);
|
||||||
|
if (work->thread == scheme_current_thread) {
|
||||||
|
GC_mark_variable_stack(GC_variable_stack, 0, get_stack_base(), NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static void clean_up_thread_list(void)
|
||||||
|
{
|
||||||
|
struct gc_thread_info *work = threads, *prev = NULL;
|
||||||
|
|
||||||
|
while(work) {
|
||||||
|
if(!find_page(work->thread) || marked(work->thread)) {
|
||||||
|
work->thread = GC_resolve(work->thread);
|
||||||
|
prev = work;
|
||||||
|
work = work->next;
|
||||||
|
} else {
|
||||||
|
struct gc_thread_info *next = work->next;
|
||||||
|
|
||||||
|
if(prev) prev->next = next;
|
||||||
|
if(!prev) threads = next;
|
||||||
|
free(work);
|
||||||
|
work = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static int thread_get_owner(void *p)
|
||||||
|
{
|
||||||
|
return ((Scheme_Thread *)p)->gc_info->owner;
|
||||||
|
}
|
||||||
#include "newgc_parts/blame_the_child.c"
|
#include "newgc_parts/blame_the_child.c"
|
||||||
|
|
||||||
int GC_set_account_hook(int type, void *c1, unsigned long b, void *c2)
|
int GC_set_account_hook(int type, void *c1, unsigned long b, void *c2)
|
||||||
|
@ -1355,6 +1309,23 @@ int GC_set_account_hook(int type, void *c1, unsigned long b, void *c2)
|
||||||
set_account_hook(type, c1, c2, b);
|
set_account_hook(type, c1, c2, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NEWGC_BTC_ACCOUNT
|
||||||
|
# define register_thread(t,c) /* */
|
||||||
|
# define register_new_thread(t,c) /* */
|
||||||
|
# define clean_up_thread_list() /* */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void GC_register_thread(void *t, void *c)
|
||||||
|
{
|
||||||
|
register_thread(t, c);
|
||||||
|
}
|
||||||
|
void GC_register_new_thread(void *t, void *c)
|
||||||
|
{
|
||||||
|
register_new_thread(t, c);
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* administration / initialization */
|
/* administration / initialization */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
|
@ -89,6 +89,11 @@ typedef struct NewGC {
|
||||||
void *park[2];
|
void *park[2];
|
||||||
void *park_save[2];
|
void *park_save[2];
|
||||||
|
|
||||||
|
/* blame the child saved off Mark_Proc pointers */
|
||||||
|
Mark_Proc normal_thread_mark;
|
||||||
|
Mark_Proc normal_custodian_mark;
|
||||||
|
Mark_Proc normal_cust_box_mark;
|
||||||
|
|
||||||
mpage *release_pages;
|
mpage *release_pages;
|
||||||
unsigned long stack_base;
|
unsigned long stack_base;
|
||||||
int dumping_avoid_collection; /* dumping coutner flag */
|
int dumping_avoid_collection; /* dumping coutner flag */
|
||||||
|
|
|
@ -180,6 +180,31 @@ inline static void memory_account_mark(struct mpage *page, void *ptr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline static void mark_cust_boxes(Scheme_Custodian *cur)
|
||||||
|
{
|
||||||
|
Scheme_Object *pr, *prev = NULL, *next;
|
||||||
|
GC_Weak_Box *wb;
|
||||||
|
|
||||||
|
/* cust boxes is a list of weak boxes to cust boxes */
|
||||||
|
|
||||||
|
pr = cur->cust_boxes;
|
||||||
|
while (pr) {
|
||||||
|
wb = (GC_Weak_Box *)SCHEME_CAR(pr);
|
||||||
|
next = SCHEME_CDR(pr);
|
||||||
|
if (wb->val) {
|
||||||
|
GC->normal_cust_box_mark(wb->val);
|
||||||
|
prev = pr;
|
||||||
|
} else {
|
||||||
|
if (prev)
|
||||||
|
SCHEME_CDR(prev) = next;
|
||||||
|
else
|
||||||
|
cur->cust_boxes = next;
|
||||||
|
}
|
||||||
|
pr = next;
|
||||||
|
}
|
||||||
|
cur->cust_boxes = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
int BTC_thread_mark(void *p)
|
int BTC_thread_mark(void *p)
|
||||||
{
|
{
|
||||||
return ((struct objhead *)(NUM(p) - WORD_SIZE))->size;
|
return ((struct objhead *)(NUM(p) - WORD_SIZE))->size;
|
||||||
|
@ -188,7 +213,7 @@ int BTC_thread_mark(void *p)
|
||||||
int BTC_custodian_mark(void *p)
|
int BTC_custodian_mark(void *p)
|
||||||
{
|
{
|
||||||
if(custodian_to_owner_set(p) == current_mark_owner)
|
if(custodian_to_owner_set(p) == current_mark_owner)
|
||||||
return normal_custodian_mark(p);
|
return GC->normal_custodian_mark(p);
|
||||||
else
|
else
|
||||||
return ((struct objhead *)(NUM(p) - WORD_SIZE))->size;
|
return ((struct objhead *)(NUM(p) - WORD_SIZE))->size;
|
||||||
}
|
}
|
||||||
|
@ -296,15 +321,16 @@ static void do_btc_accounting(void)
|
||||||
GC->in_unsafe_allocation_mode = 1;
|
GC->in_unsafe_allocation_mode = 1;
|
||||||
GC->unsafe_allocation_abort = btc_overmem_abort;
|
GC->unsafe_allocation_abort = btc_overmem_abort;
|
||||||
|
|
||||||
if(!normal_thread_mark) {
|
if(!GC->normal_thread_mark) {
|
||||||
normal_thread_mark = GC->mark_table[scheme_thread_type];
|
GC->normal_thread_mark = GC->mark_table[scheme_thread_type];
|
||||||
normal_custodian_mark = GC->mark_table[scheme_custodian_type];
|
GC->normal_custodian_mark = GC->mark_table[scheme_custodian_type];
|
||||||
normal_cust_box_mark = GC->mark_table[GC->cust_box_tag];
|
GC->normal_cust_box_mark = GC->mark_table[GC->cust_box_tag];
|
||||||
}
|
}
|
||||||
GC->mark_table[scheme_thread_type] = &BTC_thread_mark;
|
|
||||||
GC->mark_table[scheme_custodian_type] = &BTC_custodian_mark;
|
GC->mark_table[scheme_thread_type] = BTC_thread_mark;
|
||||||
GC->mark_table[GC->ephemeron_tag] = btc_mark_ephemeron;
|
GC->mark_table[scheme_custodian_type] = BTC_custodian_mark;
|
||||||
GC->mark_table[GC->cust_box_tag] = BTC_cust_box_mark;
|
GC->mark_table[GC->ephemeron_tag] = BTC_ephemeron_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++)
|
||||||
|
@ -322,8 +348,7 @@ static void do_btc_accounting(void)
|
||||||
int owner = custodian_to_owner_set(cur);
|
int owner = custodian_to_owner_set(cur);
|
||||||
|
|
||||||
current_mark_owner = owner;
|
current_mark_owner = owner;
|
||||||
GCDEBUG((DEBUGOUTF,"MARKING THREADS OF OWNER %i (CUST %p)\n",
|
GCDEBUG((DEBUGOUTF,"MARKING THREADS OF OWNER %i (CUST %p)\n", owner, cur));
|
||||||
owner, cur));
|
|
||||||
kill_propagation_loop = 0;
|
kill_propagation_loop = 0;
|
||||||
mark_threads(owner);
|
mark_threads(owner);
|
||||||
mark_cust_boxes(cur);
|
mark_cust_boxes(cur);
|
||||||
|
@ -333,15 +358,17 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
GC->mark_table[scheme_thread_type] = normal_thread_mark;
|
GC->mark_table[scheme_thread_type] = GC->normal_thread_mark;
|
||||||
GC->mark_table[scheme_custodian_type] = normal_custodian_mark;
|
GC->mark_table[scheme_custodian_type] = GC->normal_custodian_mark;
|
||||||
GC->mark_table[GC->ephemeron_tag] = mark_ephemeron;
|
GC->mark_table[GC->ephemeron_tag] = mark_ephemeron;
|
||||||
GC->mark_table[GC->cust_box_tag] = normal_cust_box_mark;
|
GC->mark_table[GC->cust_box_tag] = GC->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;
|
||||||
new_btc_mark = !new_btc_mark;
|
new_btc_mark = !new_btc_mark;
|
||||||
}
|
}
|
||||||
|
|
||||||
clear_stack_pages();
|
clear_stack_pages();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
init_weak_boxes zero_weak_boxes
|
init_weak_boxes zero_weak_boxes
|
||||||
GC_malloc_ephemeron
|
GC_malloc_ephemeron
|
||||||
size_ephemeron, mark_ephemeron, fixup_ephemeron
|
size_ephemeron, mark_ephemeron, fixup_ephemeron
|
||||||
btc_mark_ephemeron [ifdef NEW_BTC_ACCOUNT]
|
BTC_ephemeron_mark [ifdef NEW_BTC_ACCOUNT]
|
||||||
init_ephemerons mark_ready_ephemerons zero_remaining_ephemerons
|
init_ephemerons mark_ready_ephemerons zero_remaining_ephemerons
|
||||||
num_last_seen_ephemerons
|
num_last_seen_ephemerons
|
||||||
Requires:
|
Requires:
|
||||||
|
@ -235,7 +235,7 @@ static int mark_ephemeron(void *p)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef NEWGC_BTC_ACCOUNT
|
#ifdef NEWGC_BTC_ACCOUNT
|
||||||
static int btc_mark_ephemeron(void *p)
|
static int BTC_ephemeron_mark(void *p)
|
||||||
{
|
{
|
||||||
GC_Ephemeron *eph = (GC_Ephemeron *)p;
|
GC_Ephemeron *eph = (GC_Ephemeron *)p;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user