GC2 builds with and without blame the child, blame the child is more cleanly separated

svn: r12298
This commit is contained in:
Kevin Tew 2008-11-05 21:09:24 +00:00
parent 03548173f1
commit af34446ec3
4 changed files with 224 additions and 199 deletions

View File

@ -3,6 +3,75 @@
/*****************************************************************************/ /*****************************************************************************/
#ifdef NEWGC_BTC_ACCOUNT #ifdef NEWGC_BTC_ACCOUNT
#include "../src/schpriv.h"
/*****************************************************************************/
/* thread list */
/*****************************************************************************/
inline static int current_owner(Scheme_Custodian *c);
inline static void BTC_register_new_thread(void *t, void *c)
{
GC_Thread_Info *work;
work = (GC_Thread_Info *)malloc(sizeof(GC_Thread_Info));
((Scheme_Thread *)t)->gc_info = work;
work->owner = current_owner((Scheme_Custodian *)c);
work->thread = t;
work->next = GC->thread_infos;
GC->thread_infos = work;
}
inline static void BTC_register_thread(void *t, void *c)
{
GC_Thread_Info *work;
work = ((Scheme_Thread *)t)->gc_info;
work->owner = current_owner((Scheme_Custodian *)c);
}
inline static void mark_threads(int owner)
{
GC_Thread_Info *work;
for(work = GC->thread_infos; 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)
{
GC_Thread_Info *work = GC->thread_infos;
GC_Thread_Info *prev = NULL;
while(work) {
if(!pagemap_find_page(GC->page_maps, work->thread) || marked(work->thread)) {
work->thread = GC_resolve(work->thread);
prev = work;
work = work->next;
} else {
GC_Thread_Info *next = work->next;
if(prev) prev->next = next;
if(!prev) GC->thread_infos = next;
free(work);
work = next;
}
}
}
inline static int thread_get_owner(void *p)
{
return ((Scheme_Thread *)p)->gc_info->owner;
}
#define OWNER_TABLE_INIT_AMT 10 #define OWNER_TABLE_INIT_AMT 10
struct ot_entry { struct ot_entry {
@ -13,7 +82,7 @@ struct ot_entry {
char limit_set, required_set; char limit_set, required_set;
}; };
static struct ot_entry **owner_table = NULL; static THREAD_LOCAL struct ot_entry **owner_table = NULL;
static unsigned int owner_table_top = 0; static unsigned int owner_table_top = 0;
inline static int create_blank_owner_set(void) inline static int create_blank_owner_set(void)
@ -69,7 +138,7 @@ inline static int current_owner(Scheme_Custodian *c)
return custodian_to_owner_set(c); return custodian_to_owner_set(c);
} }
void GC_register_root_custodian(void *_c) void BTC_register_root_custodian(void *_c)
{ {
Scheme_Custodian *c = (Scheme_Custodian *)_c; Scheme_Custodian *c = (Scheme_Custodian *)_c;
@ -152,9 +221,9 @@ inline static unsigned long custodian_usage(void *custodian)
return gcWORDS_TO_BYTES(retval); return gcWORDS_TO_BYTES(retval);
} }
inline static void memory_account_mark(struct mpage *page, void *ptr) inline static void BTC_memory_account_mark(struct mpage *page, void *ptr)
{ {
GCDEBUG((DEBUGOUTF, "memory_account_mark: %p/%p\n", page, ptr)); GCDEBUG((DEBUGOUTF, "BTC_memory_account_mark: %p/%p\n", page, ptr));
if(page->big_page) { if(page->big_page) {
struct objhead *info = (struct objhead *)(NUM(page->addr) + PREFIX_SIZE); struct objhead *info = (struct objhead *)(NUM(page->addr) + PREFIX_SIZE);
@ -302,7 +371,7 @@ static void propagate_accounting_marks(void)
reset_pointer_stack(); reset_pointer_stack();
} }
static void do_btc_accounting(void) static void BTC_do_accounting(void)
{ {
if(GC->really_doing_accounting) { if(GC->really_doing_accounting) {
Scheme_Custodian *cur = owner_table[current_owner(NULL)]->originator; Scheme_Custodian *cur = owner_table[current_owner(NULL)]->originator;
@ -365,25 +434,17 @@ static void do_btc_accounting(void)
clear_stack_pages(); clear_stack_pages();
} }
struct account_hook { inline static void BTC_add_account_hook(int type,void *c1,void *c2,unsigned long b)
int type;
void *c1, *c2;
unsigned long amount;
struct account_hook *next;
};
static struct account_hook *hooks = NULL;
inline static void add_account_hook(int type,void *c1,void *c2,unsigned long b)
{ {
struct account_hook *work; AccountHook *work;
if(!GC->really_doing_accounting) { if(!GC->really_doing_accounting) {
GC->park[0] = c1; GC->park[1] = c2; GC->park[0] = c1;
GC->park[1] = c2;
GC->really_doing_accounting = 1; GC->really_doing_accounting = 1;
garbage_collect(1); garbage_collect(1);
c1 = GC->park[0]; c2 = GC->park[1]; c1 = GC->park[0]; GC->park[0] = NULL;
GC->park[0] = GC->park[1] = NULL; c2 = GC->park[1]; GC->park[1] = NULL;
} }
if (type == MZACCT_LIMIT) if (type == MZACCT_LIMIT)
@ -391,7 +452,7 @@ inline static void add_account_hook(int type,void *c1,void *c2,unsigned long b)
if (type == MZACCT_REQUIRE) if (type == MZACCT_REQUIRE)
GC->reset_required = 1; GC->reset_required = 1;
for(work = hooks; work; work = work->next) { for(work = GC->hooks; work; work = work->next) {
if((work->type == type) && (work->c2 == c2) && (work->c1 == c1)) { if((work->type == type) && (work->c2 == c2) && (work->c1 == c1)) {
if(type == MZACCT_REQUIRE) { if(type == MZACCT_REQUIRE) {
if(b > work->amount) work->amount = b; if(b > work->amount) work->amount = b;
@ -403,26 +464,35 @@ inline static void add_account_hook(int type,void *c1,void *c2,unsigned long b)
} }
if(!work) { if(!work) {
work = malloc(sizeof(struct account_hook)); work = malloc(sizeof(AccountHook));
work->type = type; work->c1 = c1; work->c2 = c2; work->amount = b; work->type = type;
work->next = hooks; hooks = work; work->c1 = c1;
work->c2 = c2;
work->amount = b;
/* push work onto hooks */
work->next = GC->hooks;
GC->hooks = work;
} }
} }
inline static void clean_up_account_hooks() inline static void clean_up_account_hooks()
{ {
struct account_hook *work = hooks, *prev = NULL; AccountHook *work = GC->hooks;
AccountHook *prev = NULL;
while(work) { while(work) {
if((!work->c1 || marked(work->c1)) && marked(work->c2)) { if((!work->c1 || marked(work->c1)) && marked(work->c2)) {
work->c1 = GC_resolve(work->c1); work->c1 = GC_resolve(work->c1);
work->c2 = GC_resolve(work->c2); work->c2 = GC_resolve(work->c2);
prev = work; work = work->next; prev = work;
work = work->next;
} else { } else {
struct account_hook *next = work->next; /* remove work hook */
AccountHook *next = work->next;
if(prev) prev->next = next; if(prev) prev->next = next;
if(!prev) hooks = next; if(!prev) GC->hooks = next;
free(work); free(work);
work = next; work = next;
} }
@ -443,7 +513,7 @@ static unsigned long custodian_super_require(void *c)
if (!owner_table[set]->required_set) { if (!owner_table[set]->required_set) {
unsigned long req = 0, r; unsigned long req = 0, r;
struct account_hook *work = hooks; AccountHook *work = GC->hooks;
while(work) { while(work) {
if ((work->type == MZACCT_REQUIRE) && (c == work->c2)) { if ((work->type == MZACCT_REQUIRE) && (c == work->c2)) {
@ -460,9 +530,10 @@ static unsigned long custodian_super_require(void *c)
return owner_table[set]->super_required; return owner_table[set]->super_required;
} }
inline static void run_account_hooks() inline static void BTC_run_account_hooks()
{ {
struct account_hook *work = hooks, *prev = NULL; AccountHook *work = GC->hooks;
AccountHook *prev = NULL;
while(work) { while(work) {
if( ((work->type == MZACCT_REQUIRE) && if( ((work->type == MZACCT_REQUIRE) &&
@ -472,15 +543,16 @@ inline static void run_account_hooks()
|| ||
((work->type == MZACCT_LIMIT) && ((work->type == MZACCT_LIMIT) &&
(GC_get_memory_use(work->c1) > work->amount))) { (GC_get_memory_use(work->c1) > work->amount))) {
struct account_hook *next = work->next; AccountHook *next = work->next;
if(prev) prev->next = next; if(prev) prev->next = next;
if(!prev) hooks = next; if(!prev) GC->hooks = next;
scheme_schedule_custodian_close(work->c2); scheme_schedule_custodian_close(work->c2);
free(work); free(work);
work = next; work = next;
} else { } else {
prev = work; work = work->next; prev = work;
work = work->next;
} }
} }
} }
@ -502,7 +574,7 @@ static unsigned long custodian_single_time_limit(int set)
/* Check for limits on this custodian or one of its ancestors: */ /* Check for limits on this custodian or one of its ancestors: */
unsigned long limit = (unsigned long)(long)-1; unsigned long limit = (unsigned long)(long)-1;
Scheme_Custodian *orig = owner_table[set]->originator, *c; Scheme_Custodian *orig = owner_table[set]->originator, *c;
struct account_hook *work = hooks; AccountHook *work = GC->hooks;
while(work) { while(work) {
if ((work->type == MZACCT_LIMIT) && (work->c1 == work->c2)) { if ((work->type == MZACCT_LIMIT) && (work->c1 == work->c2)) {
@ -529,23 +601,32 @@ static unsigned long custodian_single_time_limit(int set)
return owner_table[set]->single_time_limit; return owner_table[set]->single_time_limit;
} }
long BTC_get_memory_use(void *o)
# define set_account_hook(a,b,c,d) { add_account_hook(a,b,c,d); return 1; }
# define set_btc_mark(x) (((struct objhead *)(x))->btc_mark = GC->old_btc_mark)
#endif
#ifndef NEWGC_BTC_ACCOUNT
# define clean_up_owner_table() /* */
# define do_btc_accounting() /* */
# define doing_memory_accounting 0
# define memory_account_mark(p,o) /* */
# define set_account_hook(a,b,c,d) return 0
# define clean_up_account_hooks() /* */
# define run_account_hooks() /* */
# define custodian_usage(cust) 0
# define set_btc_mark(x) /* */
static unsigned long custodian_single_time_limit(int set)
{ {
return (unsigned long)(long)-1; Scheme_Object *arg = (Scheme_Object*)o;
if(SAME_TYPE(SCHEME_TYPE(arg), scheme_custodian_type)) {
return custodian_usage(arg);
}
return 0;
} }
int BTC_single_allocation_limit(size_t sizeb) {
/* We're allowed to fail. Check for allocations that exceed a single-time
* limit. Otherwise, the limit doesn't work as intended, because
* a program can allocate a large block that nearly exhausts memory,
* and then a subsequent allocation can fail. As long as the limit
* is much smaller than the actual available memory, and as long as
* GC_out_of_memory protects any user-requested allocation whose size
* is independent of any existing object, then we can enforce the limit. */
return (custodian_single_time_limit(thread_get_owner(scheme_current_thread)) < sizeb);
}
static inline void BTC_clean_up() {
clean_up_thread_list();
clean_up_owner_table();
clean_up_account_hooks();
}
# define BTC_set_btc_mark(x) (((struct objhead *)(x))->btc_mark = GC->old_btc_mark)
#endif #endif

View File

@ -1,3 +1,4 @@
#include "../src/schpriv.h"
#if defined(MZ_PRECISE_GC) && !defined(USE_COMPACT_3M_GC) #if defined(MZ_PRECISE_GC) && !defined(USE_COMPACT_3M_GC)

View File

@ -34,7 +34,6 @@
#include "platforms.h" #include "platforms.h"
#include "gc2.h" #include "gc2.h"
#include "gc2_dump.h" #include "gc2_dump.h"
#include "../src/schpriv.h"
/* the number of tags to use for tagged objects */ /* the number of tags to use for tagged objects */
#define NUMBER_OF_TAGS 512 #define NUMBER_OF_TAGS 512
@ -85,6 +84,7 @@ static THREAD_LOCAL NewGC *GC;
/* This turns on blame-the-child automatic memory accounting */ /* This turns on blame-the-child automatic memory accounting */
/* #define NEWGC_BTC_ACCOUNT */ /* #define NEWGC_BTC_ACCOUNT */
/* #undef NEWGC_BTC_ACCOUNT */
/* This turns on memory tracing */ /* This turns on memory tracing */
/* #define NEWGC_MEMORY_TRACE */ /* #define NEWGC_MEMORY_TRACE */
@ -383,8 +383,9 @@ static void free_mpage(struct mpage *page)
free(page); free(page);
} }
static unsigned long custodian_single_time_limit(int set); #ifdef NEWGC_BTC_ACCOUNT
inline static int thread_get_owner(void *p); static inline int BTC_single_allocation_limit(size_t sizeb);
#endif
/* the core allocation functions */ /* the core allocation functions */
static void *allocate_big(size_t sizeb, int type) static void *allocate_big(size_t sizeb, int type)
@ -392,7 +393,9 @@ static void *allocate_big(size_t sizeb, int type)
mpage *bpage; mpage *bpage;
void *addr; void *addr;
#ifdef NEWGC_BTC_ACCOUNT
if(GC_out_of_memory) { if(GC_out_of_memory) {
if (BTC_single_allocation_limit(sizeb)) {
/* We're allowed to fail. Check for allocations that exceed a single-time /* We're allowed to fail. Check for allocations that exceed a single-time
limit. Otherwise, the limit doesn't work as intended, because limit. Otherwise, the limit doesn't work as intended, because
a program can allocate a large block that nearly exhausts memory, a program can allocate a large block that nearly exhausts memory,
@ -400,10 +403,10 @@ static void *allocate_big(size_t sizeb, int type)
is much smaller than the actual available memory, and as long as is much smaller than the actual available memory, and as long as
GC_out_of_memory protects any user-requested allocation whose size GC_out_of_memory protects any user-requested allocation whose size
is independent of any existing object, then we can enforce the limit. */ is independent of any existing object, then we can enforce the limit. */
if (custodian_single_time_limit(thread_get_owner(scheme_current_thread)) < sizeb) {
GC_out_of_memory(); GC_out_of_memory();
} }
} }
#endif
/* the actual size of this is the size, ceilinged to the next largest word, /* the actual size of this is the size, ceilinged to the next largest word,
plus one word for the object header. plus one word for the object header.
@ -1238,94 +1241,43 @@ inline static void reset_pointer_stack(void)
} }
/*****************************************************************************/ /*****************************************************************************/
/* thread list */ /* BLAME THE CHILD */
/*****************************************************************************/ /*****************************************************************************/
#ifdef NEWGC_BTC_ACCOUNT #ifdef NEWGC_BTC_ACCOUNT
inline static int current_owner(Scheme_Custodian *c); # include "blame_the_child.c"
#else
inline static void register_new_thread(void *t, void *c)
{
GC_Thread_Info *work;
work = (GC_Thread_Info *)malloc(sizeof(GC_Thread_Info));
((Scheme_Thread *)t)->gc_info = work;
work->owner = current_owner((Scheme_Custodian *)c);
work->thread = t;
work->next = GC->thread_infos;
GC->thread_infos = work;
}
inline static void register_thread(void *t, void *c)
{
GC_Thread_Info *work;
work = ((Scheme_Thread *)t)->gc_info;
work->owner = current_owner((Scheme_Custodian *)c);
}
inline static void mark_threads(int owner)
{
GC_Thread_Info *work;
for(work = GC->thread_infos; 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)
{
GC_Thread_Info *work = GC->thread_infos;
GC_Thread_Info *prev = NULL;
while(work) {
if(!pagemap_find_page(GC->page_maps, work->thread) || marked(work->thread)) {
work->thread = GC_resolve(work->thread);
prev = work;
work = work->next;
} else {
GC_Thread_Info *next = work->next;
if(prev) prev->next = next;
if(!prev) GC->thread_infos = next;
free(work);
work = next;
}
}
}
inline static int thread_get_owner(void *p)
{
return ((Scheme_Thread *)p)->gc_info->owner;
}
#include "blame_the_child.c"
int GC_set_account_hook(int type, void *c1, unsigned long b, void *c2)
{
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() /* */ # define clean_up_thread_list() /* */
#endif #endif
void GC_register_root_custodian(void *c)
{
#ifdef NEWGC_BTC_ACCOUNT
BTC_register_root_custodian(c);
#endif
}
int GC_set_account_hook(int type, void *c1, unsigned long b, void *c2)
{
#ifdef NEWGC_BTC_ACCOUNT
BTC_add_account_hook(type, c1, c2, b);
return 1;
#else
return 0;
#endif
}
void GC_register_thread(void *t, void *c) void GC_register_thread(void *t, void *c)
{ {
register_thread(t, c); #ifdef NEWGC_BTC_ACCOUNT
BTC_register_thread(t, c);
#endif
} }
void GC_register_new_thread(void *t, void *c) void GC_register_new_thread(void *t, void *c)
{ {
register_new_thread(t, c); #ifdef NEWGC_BTC_ACCOUNT
BTC_register_new_thread(t, c);
#endif
} }
/*****************************************************************************/ /*****************************************************************************/
@ -1417,20 +1369,12 @@ void GC_register_traversers(short tag, Size_Proc size, Mark_Proc mark,
long GC_get_memory_use(void *o) long GC_get_memory_use(void *o)
{ {
Scheme_Object *arg = (Scheme_Object*)o; #ifdef NEWGC_BTC_ACCOUNT
unsigned long retval = 0; if(o) {
return BTC_get_memory_use(o);
if(arg) {
if(SCHEME_PROCP(arg)) {
retval = 0;
} else if(SAME_TYPE(SCHEME_TYPE(arg), scheme_custodian_type)) {
retval = custodian_usage(arg);
} }
} else { #endif
retval = gen0_size_in_use() + GC->memory_in_use; return gen0_size_in_use() + GC->memory_in_use;
}
return retval;
} }
/*****************************************************************************/ /*****************************************************************************/
@ -1459,7 +1403,11 @@ void GC_mark(const void *const_p)
} }
/* toss this over to the BTC mark routine if we're doing accounting */ /* toss this over to the BTC mark routine if we're doing accounting */
if(GC->doing_memory_accounting) { memory_account_mark(page,p); return; } if(GC->doing_memory_accounting) {
#ifdef NEWGC_BTC_ACCOUNT
BTC_memory_account_mark(page, p); return;
#endif
}
if(page->big_page) { if(page->big_page) {
/* This is a bigpage. The first thing we do is see if its been marked /* This is a bigpage. The first thing we do is see if its been marked
@ -1490,7 +1438,9 @@ void GC_mark(const void *const_p)
/* if we're doing memory accounting, then we need to make sure the /* if we're doing memory accounting, then we need to make sure the
btc_mark is right */ btc_mark is right */
set_btc_mark(NUM(page->addr) + PREFIX_SIZE); #ifdef NEWGC_BTC_ACCOUNT
BTC_set_btc_mark(NUM(page->addr) + PREFIX_SIZE);
#endif
} }
page->marked_on = 1; page->marked_on = 1;
@ -1589,7 +1539,9 @@ void GC_mark(const void *const_p)
((struct objhead *)newplace)->mark = 1; ((struct objhead *)newplace)->mark = 1;
/* if we're doing memory accounting, then we need the btc_mark /* if we're doing memory accounting, then we need the btc_mark
to be set properly */ to be set properly */
set_btc_mark(newplace); #ifdef NEWGC_BTC_ACCOUNT
BTC_set_btc_mark(newplace);
#endif
/* drop the new location of the object into the forwarding space /* drop the new location of the object into the forwarding space
and into the mark queue */ and into the mark queue */
newplace = PTR(NUM(newplace) + WORD_SIZE); newplace = PTR(NUM(newplace) + WORD_SIZE);
@ -2421,9 +2373,9 @@ static void garbage_collect(int force_full)
/* do some cleanup structures that either change state based on the /* do some cleanup structures that either change state based on the
heap state after collection or that become useless based on changes heap state after collection or that become useless based on changes
in state after collection */ in state after collection */
clean_up_thread_list(); #ifdef NEWGC_BTC_ACCOUNT
clean_up_owner_table(); BTC_clean_up();
clean_up_account_hooks(); #endif
TIME_STEP("cleaned"); TIME_STEP("cleaned");
repair_finalizer_structs(); repair_finalizer_structs();
repair_weak_finalizer_structs(); repair_weak_finalizer_structs();
@ -2437,8 +2389,10 @@ static void garbage_collect(int force_full)
TIME_STEP("cleaned heap"); TIME_STEP("cleaned heap");
reset_nursery(); reset_nursery();
TIME_STEP("reset nursurey"); TIME_STEP("reset nursurey");
#ifdef NEWGC_BTC_ACCOUNT
if (gc->gc_full) if (gc->gc_full)
do_btc_accounting(); BTC_do_accounting();
#endif
TIME_STEP("accounted"); TIME_STEP("accounted");
if (gc->generations_available) if (gc->generations_available)
protect_old_pages(); protect_old_pages();
@ -2513,7 +2467,9 @@ static void garbage_collect(int force_full)
f->f(f->p, f->data); f->f(f->p, f->data);
GC_variable_stack = saved_gc_variable_stack; GC_variable_stack = saved_gc_variable_stack;
} }
run_account_hooks(); #ifdef NEWGC_BTC_ACCOUNT
BTC_run_account_hooks();
#endif
gc->running_finalizers = 0; gc->running_finalizers = 0;
gc->park[0] = gc->park_save[0]; gc->park[0] = gc->park_save[0];

View File

@ -1,41 +1,5 @@
#include "commongc_internal.h" #include "commongc_internal.h"
#include "gc2_obj.h"
#if defined(MZ_PRECISE_GC) && !defined(USE_COMPACT_3M_GC)
/* This is the log base 2 of the standard memory page size. 14 means 2^14,
which is 16k. This seems to be a good size for most platforms.
Under Windows as of 2008, however, the allocation granularity is 64k. */
#ifdef _WIN32
# define LOG_APAGE_SIZE 16
#else
# define LOG_APAGE_SIZE 14
#endif
#ifdef SIXTY_FOUR_BIT_INTEGERS
# define OBJH_WORD_SIZE 8
#else
# define OBJH_WORD_SIZE 4
#endif
struct objhead {
unsigned long hash : ((8*OBJH_WORD_SIZE) - (4+3+LOG_APAGE_SIZE));
/* the type and size of the object */
unsigned long type : 3;
/* these are the various mark bits we use */
unsigned long mark : 1;
unsigned long btc_mark : 1;
/* these are used for compaction et al*/
unsigned long moved : 1;
unsigned long dead : 1;
unsigned long size : LOG_APAGE_SIZE;
};
XFORM_NONGCING extern int GC_is_allocated(void *p);
#define OBJHEAD_HAS_HASH_BITS
#define OBJHEAD_HASH_BITS(p) ((struct objhead *)((void **)p - 1))->hash
#endif
typedef struct mpage { typedef struct mpage {
struct mpage *next; struct mpage *next;
@ -83,6 +47,26 @@ typedef struct GC_Thread_Info {
struct GC_Thread_Info *next; struct GC_Thread_Info *next;
} GC_Thread_Info; } GC_Thread_Info;
typedef struct AccountHook {
int type;
void *c1;
void *c2;
unsigned long amount;
struct AccountHook *next;
} AccountHook;
/*
struct ot_entry {
Scheme_Custodian *originator;
Scheme_Custodian **members;
unsigned long memory_use;
unsigned long single_time_limit;
unsigned long super_required;
char limit_set;
char required_set;
};
*/
#ifdef SIXTY_FOUR_BIT_INTEGERS #ifdef SIXTY_FOUR_BIT_INTEGERS
typedef mpage ****PageMap; typedef mpage ****PageMap;
#else #else
@ -138,8 +122,11 @@ typedef struct NewGC {
unsigned int reset_required :1; unsigned int reset_required :1;
unsigned int kill_propagation_loop :1; unsigned int kill_propagation_loop :1;
unsigned int current_mark_owner; unsigned int current_mark_owner;
//static struct ot_entry **owner_table = NULL; /* ot_entry **owner_table; */
unsigned int owner_table_top; unsigned int owner_table_top;
AccountHook *hooks;
unsigned long number_of_gc_runs; unsigned long number_of_gc_runs;