Split definitions out to header file, beginning of re-entry gc

svn: r12248
This commit is contained in:
Kevin Tew 2008-11-05 21:04:10 +00:00
parent 58eaf2a88a
commit d290f569bf
6 changed files with 202 additions and 61 deletions

View File

@ -0,0 +1,46 @@
typedef short Type_Tag;
typedef struct Roots {
long count;
long size;
/* roots is a array of longs, logically grouped into start and end pairs.
* [ start0, end0, start1, end1, ... ]
*/
unsigned long *roots;
int nothing_new;
} Roots;
/* The GC_Weak_Array structure is not externally visible, but
clients expect a specific structure. See README for more
information. */
typedef struct GC_Weak_Array {
Type_Tag type;
short keyex;
long count;
void *replace_val;
struct GC_Weak_Array *next;
void *data[1]; /* must be the 5th longword! */
} GC_Weak_Array;
/* The GC_Weak_Box struct is not externally visible, but
first three fields are mandated by the GC interface */
typedef struct GC_Weak_Box {
Type_Tag type;
short keyex;
void *val;
/* The rest is up to us: */
void **secondary_erase;
int soffset;
struct GC_Weak_Box *next;
} GC_Weak_Box;
/* The GC_Ephemeron struct is not externally visible, but
first three fields are mandated by the GC interface */
typedef struct GC_Ephemeron {
Type_Tag type;
short keyex;
void *key;
void *val;
/* The rest is up to us: */
struct GC_Ephemeron *next;
} GC_Ephemeron;

View File

@ -10,6 +10,10 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "newgc_internal.h"
#include "../src/schpriv.h"
static THREAD_LOCAL NewGC *GC;
/**************** Configuration ****************/
@ -79,7 +83,6 @@
#define INCREMENT_CYCLE_COUNT_GROWTH 1048576
typedef short Type_Tag;
#include "gc2.h"
#include "gc2_dump.h"
@ -2867,63 +2870,74 @@ static long started, rightnow, old;
# define PRINTTIME(x) /* empty */
#endif
static void do_roots(int fixup)
static void mark_roots()
{
ImmobileBox *ib;
int i;
for (i = 0; i < roots_count; i += 2) {
void **s = (void **)roots[i];
void **e = (void **)roots[i + 1];
for (i = 0; i < roots->count; i += 2) {
void **s = (void **)roots->roots[i];
void **e = (void **)roots->roots[i + 1];
while (s < e) {
if (fixup) {
gcFIXUP(*s);
} else {
#if RECORD_MARK_SRC
mark_src = s;
mark_type = MTYPE_ROOT;
mark_src = s;
mark_type = MTYPE_ROOT;
#endif
gcMARK(*s);
}
gcMARK(*s);
s++;
}
}
if (fixup)
GC_fixup_variable_stack(GC_variable_stack,
0,
(void *)(GC_get_thread_stack_base
? GC_get_thread_stack_base()
: stack_base),
NULL);
else {
#if RECORD_MARK_SRC
record_stack_source = 1;
record_stack_source = 1;
#endif
GC_mark_variable_stack(GC_variable_stack,
0,
(void *)(GC_get_thread_stack_base
? GC_get_thread_stack_base()
: stack_base),
NULL);
GC_mark_variable_stack(GC_variable_stack,
0,
(void *)(GC_get_thread_stack_base
? GC_get_thread_stack_base()
: stack_base),
NULL);
#if RECORD_MARK_SRC
record_stack_source = 0;
record_stack_source = 0;
#endif
}
/* Do immobiles: */
for (ib = immobile; ib; ib = ib->next) {
if (fixup) {
gcFIXUP(ib->p);
} else {
#if RECORD_MARK_SRC
mark_src = ib;
mark_type = MTYPE_IMMOBILE;
mark_src = ib;
mark_type = MTYPE_IMMOBILE;
#endif
gcMARK(ib->p);
gcMARK(ib->p);
}
}
static void fixup_roots()
{
ImmobileBox *ib;
int i;
for (i = 0; i < roots->count; i += 2) {
void **s = (void **)roots->roots[i];
void **e = (void **)roots->roots[i + 1];
while (s < e) {
gcFIXUP(*s);
s++;
}
}
GC_fixup_variable_stack(GC_variable_stack,
0,
(void *)(GC_get_thread_stack_base
? GC_get_thread_stack_base()
: stack_base),
NULL);
/* Do immobiles: */
for (ib = immobile; ib; ib = ib->next) {
gcFIXUP(ib->p);
}
}
static void gcollect(int full)
@ -3033,7 +3047,7 @@ static void gcollect(int full)
mark_calls = mark_hits = mark_recalls = mark_colors = mark_many = mark_slow = 0;
#endif
do_roots(0);
mark_roots();
{
Fnl *f;
@ -3392,7 +3406,7 @@ static void gcollect(int full)
scanned_pages = 0;
do_roots(1);
fixup_roots();
{
Fnl *f;

View File

@ -0,0 +1 @@
#include "commongc_internal.h"

View File

@ -36,6 +36,8 @@
#include "newgc_internal.h"
#include "../src/schpriv.h"
static THREAD_LOCAL NewGC *GC;
#ifdef _WIN32
# include <windows.h>
# define bzero(m, s) memset(m, 0, s)
@ -1292,15 +1294,11 @@ inline static void reset_weak_finalizers(void)
/* weak boxes and arrays */
/*****************************************************************************/
static unsigned short weak_array_tag;
static unsigned short weak_box_tag;
static unsigned short ephemeron_tag;
#define is_marked(p) marked(p)
#define weak_box_resolve(p) GC_resolve(p)
#include "weak.c"
#undef is_marked
#undef weak_box_resolve
/*****************************************************************************/
/* thread list */
@ -1317,7 +1315,6 @@ struct gc_thread_info {
static Mark_Proc normal_thread_mark = NULL, normal_custodian_mark = NULL, normal_cust_box_mark = NULL;
static struct gc_thread_info *threads = NULL;
static unsigned short cust_box_tag;
inline static void register_new_thread(void *t, void *c)
{
@ -1523,7 +1520,7 @@ inline static void reset_pointer_stack(void)
int_top->top = PPTR(int_top) + 4;
}
#include "newgc_parts/btc.c"
#include "newgc_parts/blame_the_child.c"
int GC_set_account_hook(int type, void *c1, unsigned long b, void *c2)
{
@ -1569,14 +1566,18 @@ void GC_init_type_tags(int count, int pair, int mutable_pair, int weakbox, int e
{
static int initialized = 0;
weak_box_tag = weakbox;
ephemeron_tag = ephemeron;
weak_array_tag = weakarray;
# ifdef NEWGC_BTC_ACCOUNT
cust_box_tag = custbox;
# endif
if(!initialized) {
GC = malloc(sizeof(NewGC));
NewGC_initialize(GC);
GC->weak_box_tag = weakbox;
GC->ephemeron_tag = ephemeron;
GC->weak_array_tag = weakarray;
# ifdef NEWGC_BTC_ACCOUNT
GC->cust_box_tag = custbox;
# endif
initialized = 1;
/* Our best guess at what the OS will let us allocate: */
max_heap_size = determine_max_heap_size();
@ -1589,18 +1590,19 @@ void GC_init_type_tags(int count, int pair, int mutable_pair, int weakbox, int e
resize_gen0(INIT_GEN0_SIZE);
GC_register_traversers(weak_box_tag, size_weak_box, mark_weak_box,
fixup_weak_box, 0, 0);
GC_register_traversers(ephemeron_tag, size_ephemeron, mark_ephemeron,
fixup_ephemeron, 0, 0);
GC_register_traversers(weak_array_tag, size_weak_array, mark_weak_array,
fixup_weak_array, 0, 0);
GC_register_traversers(GC->weak_box_tag, size_weak_box, mark_weak_box, fixup_weak_box, 0, 0);
GC_register_traversers(GC->ephemeron_tag, size_ephemeron, mark_ephemeron, fixup_ephemeron, 0, 0);
GC_register_traversers(GC->weak_array_tag, size_weak_array, mark_weak_array, fixup_weak_array, 0, 0);
initialize_signal_handler();
GC_add_roots(&park, (char *)&park + sizeof(park) + 1);
GC_add_roots(&park_save, (char *)&park_save + sizeof(park_save) + 1);
initialize_protect_page_ranges(malloc_dirty_pages(APAGE_SIZE, APAGE_SIZE), APAGE_SIZE);
}
else {
GCPRINT(GCOUTF, "HEY WHATS UP.\n");
abort();
}
}
void GC_gcollect(void)

View File

@ -0,0 +1,78 @@
/*****************************************************************************/
/* Backtrace */
/*****************************************************************************/
#if MZ_GC_BACKTRACE
static void backtrace_new_page(struct mpage *page)
{
/* This is a little wastefull for big pages, because we'll
only use the first few words: */
page->backtrace = (void **)malloc_pages(APAGE_SIZE, APAGE_SIZE);
}
static void free_backtrace(struct mpage *page)
{
free_pages(page->backtrace, APAGE_SIZE);
}
static void *bt_source;
static int bt_type;
static void set_backtrace_source(void *source, int type)
{
bt_source = source;
bt_type = type;
}
static void record_backtrace(struct mpage *page, void *ptr)
/* ptr is after objhead */
{
unsigned long delta;
delta = PPTR(ptr) - PPTR(page->addr);
page->backtrace[delta - 1] = bt_source;
((long *)page->backtrace)[delta] = bt_type;
}
static void copy_backtrace_source(struct mpage *to_page, void *to_ptr,
struct mpage *from_page, void *from_ptr)
/* ptrs are at objhead */
{
unsigned long to_delta, from_delta;
to_delta = PPTR(to_ptr) - PPTR(to_page->addr);
from_delta = PPTR(from_ptr) - PPTR(from_page->addr);
to_page->backtrace[to_delta] = from_page->backtrace[from_delta];
to_page->backtrace[to_delta+1] = from_page->backtrace[from_delta+1];
}
static void *get_backtrace(struct mpage *page, void *ptr)
/* ptr is after objhead */
{
unsigned long delta;
if (page->big_page)
ptr = PTR(page->addr + PREFIX_SIZE + WORD_SIZE);
delta = PPTR(ptr) - PPTR(page->addr);
return page->backtrace[delta - 1];
}
# define BT_STACK (PAGE_TYPES + 0)
# define BT_ROOT (PAGE_TYPES + 1)
# define BT_FINALIZER (PAGE_TYPES + 2)
# define BT_WEAKLINK (PAGE_TYPES + 3)
# define BT_IMMOBILE (PAGE_TYPES + 4)
#else
# define backtrace_new_page(page) /* */
# define free_backtrace(page) /* */
# define set_backtrace_source(ptr, type) /* */
# define record_backtrace(page, ptr) /* */
# define copy_backtrace_source(to_page, to_ptr, from_page, from_ptr) /* */
#endif

View File

@ -97,7 +97,7 @@ void *GC_malloc_weak_array(size_t size_in_bytes, void *replace_val)
replace_val = park[0];
park[0] = NULL;
w->type = weak_array_tag;
w->type = GC->weak_array_tag;
w->replace_val = replace_val;
w->count = (size_in_bytes >> LOG_WORD_SIZE);
@ -178,7 +178,7 @@ void *GC_malloc_weak_box(void *p, void **secondary, int soffset)
secondary = (void **)park[1];
park[1] = NULL;
w->type = weak_box_tag;
w->type = GC->weak_box_tag;
w->val = p;
w->secondary_erase = secondary;
w->soffset = soffset;
@ -272,7 +272,7 @@ void *GC_malloc_ephemeron(void *k, void *v)
v = park[1];
park[1] = NULL;
eph->type = ephemeron_tag;
eph->type = GC->ephemeron_tag;
eph->key = k;
eph->val = v;