Moved page_map to NewGC struct
svn: r12276
This commit is contained in:
parent
88a778fc12
commit
2276702c19
|
@ -51,3 +51,19 @@ typedef struct GC_Immobile_Box {
|
||||||
struct GC_Immobile_Box *prev;
|
struct GC_Immobile_Box *prev;
|
||||||
} GC_Immobile_Box;
|
} GC_Immobile_Box;
|
||||||
|
|
||||||
|
typedef struct finalizer {
|
||||||
|
char eager_level;
|
||||||
|
char tagged;
|
||||||
|
void *p;
|
||||||
|
GC_finalization_proc f;
|
||||||
|
void *data;
|
||||||
|
#if CHECKS
|
||||||
|
long size;
|
||||||
|
#endif
|
||||||
|
struct finalizer *next;
|
||||||
|
/* Patched after GC: */
|
||||||
|
struct finalizer *prev;
|
||||||
|
struct finalizer *left;
|
||||||
|
struct finalizer *right;
|
||||||
|
} Fnl;
|
||||||
|
|
||||||
|
|
|
@ -13,10 +13,10 @@
|
||||||
#include "gc2.h"
|
#include "gc2.h"
|
||||||
|
|
||||||
#define NUMBER_OF_TAGS 512
|
#define NUMBER_OF_TAGS 512
|
||||||
#include "newgc_internal.h"
|
#include "compactgc_internal.h"
|
||||||
#include "../src/schpriv.h"
|
#include "../src/schpriv.h"
|
||||||
|
|
||||||
static THREAD_LOCAL NewGC *GC;
|
static THREAD_LOCAL CompactGC *GC;
|
||||||
|
|
||||||
/**************** Configuration ****************/
|
/**************** Configuration ****************/
|
||||||
|
|
||||||
|
|
|
@ -1 +1,21 @@
|
||||||
#include "commongc_internal.h"
|
#include "commongc_internal.h"
|
||||||
|
|
||||||
|
typedef struct CompactGC {
|
||||||
|
void *park[2];
|
||||||
|
void *park_save[2];
|
||||||
|
|
||||||
|
unsigned short weak_array_tag;
|
||||||
|
unsigned short weak_box_tag;
|
||||||
|
unsigned short ephemeron_tag;
|
||||||
|
unsigned short cust_box_tag;
|
||||||
|
|
||||||
|
Roots roots;
|
||||||
|
GC_Weak_Array *weak_arrays;
|
||||||
|
GC_Weak_Box *weak_boxes;
|
||||||
|
GC_Ephemeron *ephemerons;
|
||||||
|
int num_last_seen_ephemerons;
|
||||||
|
} CompactGC;
|
||||||
|
|
||||||
|
void CompactGC_initialize(CompactGC *newgc) {
|
||||||
|
memset(newgc, 0, sizeof(CompactGC));
|
||||||
|
}
|
||||||
|
|
|
@ -39,6 +39,18 @@
|
||||||
/* 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
|
||||||
|
|
||||||
|
#ifdef SIXTY_FOUR_BIT_INTEGERS
|
||||||
|
#define PAGEMAP64_LEVEL1_SIZE (1 << 16)
|
||||||
|
#define PAGEMAP64_LEVEL2_SIZE (1 << 16)
|
||||||
|
#define PAGEMAP64_LEVEL3_SIZE (1 << (32 - LOG_APAGE_SIZE))
|
||||||
|
#define PAGEMAP64_LEVEL1_BITS(p) (((unsigned long)(p)) >> 48)
|
||||||
|
#define PAGEMAP64_LEVEL2_BITS(p) ((((unsigned long)(p)) >> 32) & ((PAGEMAP64_LEVEL2_SIZE) - 1))
|
||||||
|
#define PAGEMAP64_LEVEL3_BITS(p) ((((unsigned long)(p)) >> LOG_APAGE_SIZE) & ((PAGEMAP64_LEVEL3_SIZE) - 1))
|
||||||
|
#else
|
||||||
|
#define PAGEMAP32_SIZE (1 << (32 - LOG_APAGE_SIZE))
|
||||||
|
#define PAGEMAP32_BITS(x) (NUM(x) >> LOG_APAGE_SIZE)
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "newgc_internal.h"
|
#include "newgc_internal.h"
|
||||||
static THREAD_LOCAL NewGC *GC;
|
static THREAD_LOCAL NewGC *GC;
|
||||||
|
|
||||||
|
@ -88,12 +100,6 @@ static THREAD_LOCAL NewGC *GC;
|
||||||
#define PTR(x) ((void*)(x))
|
#define PTR(x) ((void*)(x))
|
||||||
#define PPTR(x) ((void**)(x))
|
#define PPTR(x) ((void**)(x))
|
||||||
#define NUM(x) ((unsigned long)(x))
|
#define NUM(x) ((unsigned long)(x))
|
||||||
#define USEFUL_ADDR_BITS (32 - LOG_APAGE_SIZE)
|
|
||||||
#ifdef SIXTY_FOUR_BIT_INTEGERS
|
|
||||||
# define ADDR_BITS(x) ((NUM(x) >> LOG_APAGE_SIZE) & ((1 << USEFUL_ADDR_BITS) - 1))
|
|
||||||
#else
|
|
||||||
# define ADDR_BITS(x) (NUM(x) >> LOG_APAGE_SIZE)
|
|
||||||
#endif
|
|
||||||
#define WORD_SIZE (1 << LOG_WORD_SIZE)
|
#define WORD_SIZE (1 << LOG_WORD_SIZE)
|
||||||
#define WORD_BITS (8 * WORD_SIZE)
|
#define WORD_BITS (8 * WORD_SIZE)
|
||||||
#define APAGE_SIZE (1 << LOG_APAGE_SIZE)
|
#define APAGE_SIZE (1 << LOG_APAGE_SIZE)
|
||||||
|
@ -184,6 +190,105 @@ int GC_mtrace_union_current_with(int newval)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Page Map Routines */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
/* the page map makes a nice mapping from addresses to pages, allowing
|
||||||
|
fairly fast lookup. this is useful. */
|
||||||
|
|
||||||
|
inline static void pagemap_set(void *p, mpage *value) {
|
||||||
|
#ifdef SIXTY_FOUR_BIT_INTEGERS
|
||||||
|
unsigned long pos;
|
||||||
|
mpage ***page_maps;
|
||||||
|
mapge **page_map;
|
||||||
|
|
||||||
|
pos = PAGEMAP64_LEVEL1_BITS(p);
|
||||||
|
page_maps = GC->page_mapss[pos];
|
||||||
|
if (!page_maps) {
|
||||||
|
page_maps = (mpage ***)calloc(PAGEMAP64_LEVEL2_SIZE, sizeof(mpage **));
|
||||||
|
page_mapss[pos] = page_maps;
|
||||||
|
}
|
||||||
|
pos = PAGEMAP64_LEVEL2_BITS(p);
|
||||||
|
page_map = page_maps[pos];
|
||||||
|
if (!page_map) {
|
||||||
|
page_map = (mpage **)calloc(PAGEMAP64_LEVEL3_SIZE, sizeof(mpage *));
|
||||||
|
page_maps[pos] = page_map;
|
||||||
|
}
|
||||||
|
page_map[PAGEMAP64_LEVEL3_BITS(p)] = value;
|
||||||
|
#else
|
||||||
|
GC->page_map[PAGEMAP32_BITS(p)] = value;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static struct mpage *pagemap_find_page(void *p) {
|
||||||
|
#ifdef SIXTY_FOUR_BIT_INTEGERS
|
||||||
|
mpage ***page_maps;
|
||||||
|
mpage **page_map;
|
||||||
|
|
||||||
|
page_maps = GC->page_mapss[PAGEMAP64_LEVEL1_BITS(p)];
|
||||||
|
if (!page_maps) return NULL;
|
||||||
|
page_map = page_maps[PAGEMAP64_LEVEL2_BITS(p)];
|
||||||
|
if (!page_map) return NULL;
|
||||||
|
return page_map[PAGEMAP64_LEVEL3_BITS(p)];
|
||||||
|
#else
|
||||||
|
return GC->page_map[PAGEMAP32_BITS(p)];
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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
|
||||||
|
map itself serves two important purposes:
|
||||||
|
|
||||||
|
Between collections, it maps pointers to write-protected pages, so that
|
||||||
|
the write-barrier can identify what page a write has happened to and
|
||||||
|
mark it as potentially containing pointers from gen 1 to gen 0.
|
||||||
|
|
||||||
|
During collections, it maps pointers to "from" pages. */
|
||||||
|
|
||||||
|
/* pagemap_modify_with_size could be optimized more for the 64 bit case
|
||||||
|
repeatedly calling pagemap_set for the 64 bit case is not optimal */
|
||||||
|
inline static void pagemap_modify_with_size(mpage *page, long size, mpage *val) {
|
||||||
|
void *p = page->addr;
|
||||||
|
|
||||||
|
while(size > 0) {
|
||||||
|
pagemap_set(p, val);
|
||||||
|
size -= APAGE_SIZE;
|
||||||
|
p = (char *)p + APAGE_SIZE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static void pagemap_modify(mpage *page, mpage *val) {
|
||||||
|
long size = page->big_page ? page->size : APAGE_SIZE;
|
||||||
|
pagemap_modify_with_size(page, size, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static void pagemap_add(struct mpage *page)
|
||||||
|
{
|
||||||
|
pagemap_modify(page, page);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static void pagemap_add_with_size(struct mpage *page, long size)
|
||||||
|
{
|
||||||
|
pagemap_modify_with_size(page, size, page);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static void pagemap_remove(struct mpage *page)
|
||||||
|
{
|
||||||
|
pagemap_modify(page, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static void pagemap_remove_with_size(struct mpage *page, long size)
|
||||||
|
{
|
||||||
|
pagemap_modify_with_size(page, size, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
int GC_is_allocated(void *p)
|
||||||
|
{
|
||||||
|
return !!pagemap_find_page(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Allocation */
|
/* Allocation */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -236,46 +341,6 @@ static const char *type_name[PAGE_TYPES] = {
|
||||||
"big"
|
"big"
|
||||||
};
|
};
|
||||||
|
|
||||||
/* the page map makes a nice mapping from addresses to pages, allowing
|
|
||||||
fairly fast lookup. this is useful. */
|
|
||||||
#ifdef SIXTY_FOUR_BIT_INTEGERS
|
|
||||||
static struct mpage ***page_mapss[1 << 16];
|
|
||||||
# define DECL_PAGE_MAP struct mpage **page_map;
|
|
||||||
# define GET_PAGE_MAP(p) page_map = create_page_map(p);
|
|
||||||
# define FIND_PAGE_MAP(p) page_map = get_page_map(p); if (!page_map) return NULL
|
|
||||||
inline static struct mpage **create_page_map(void *p) {
|
|
||||||
unsigned long pos;
|
|
||||||
struct mpage ***page_maps, **page_map;
|
|
||||||
pos = (unsigned long)p >> 48;
|
|
||||||
page_maps = page_mapss[pos];
|
|
||||||
if (!page_maps) {
|
|
||||||
page_maps = (struct mpage ***)calloc(1 << 16, sizeof(struct mpage **));
|
|
||||||
page_mapss[pos] = page_maps;
|
|
||||||
}
|
|
||||||
pos = ((unsigned long)p >> 32) & ((1 << 16) - 1);
|
|
||||||
page_map = page_maps[pos];
|
|
||||||
if (!page_map) {
|
|
||||||
page_map = (struct mpage **)calloc(1 << USEFUL_ADDR_BITS, sizeof(struct mpage *));
|
|
||||||
page_maps[pos] = page_map;
|
|
||||||
}
|
|
||||||
return page_map;
|
|
||||||
}
|
|
||||||
inline static struct mpage **get_page_map(void *p) {
|
|
||||||
unsigned long pos;
|
|
||||||
struct mpage ***page_maps;
|
|
||||||
pos = (unsigned long)p >> 48;
|
|
||||||
page_maps = page_mapss[pos];
|
|
||||||
if (!page_maps)
|
|
||||||
return NULL;
|
|
||||||
pos = ((unsigned long)p >> 32) & ((1 << 16) - 1);
|
|
||||||
return page_maps[pos];
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
static struct mpage *page_map[1 << USEFUL_ADDR_BITS];
|
|
||||||
# define DECL_PAGE_MAP /**/
|
|
||||||
# define GET_PAGE_MAP(p) /**/
|
|
||||||
# define FIND_PAGE_MAP(p) /**/
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Generation 0. Generation 0 is a set of very large pages in a list(GC->gen0.pages),
|
/* Generation 0. Generation 0 is a set of very large pages in a list(GC->gen0.pages),
|
||||||
plus a set of smaller bigpages in a separate list(GC->gen0.big_pages).
|
plus a set of smaller bigpages in a separate list(GC->gen0.big_pages).
|
||||||
|
@ -297,50 +362,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 */
|
||||||
|
|
||||||
/* 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
|
|
||||||
map itself serves two important purposes:
|
|
||||||
|
|
||||||
Between collections, it maps pointers to write-protected pages, so that
|
|
||||||
the write-barrier can identify what page a write has happened to and
|
|
||||||
mark it as potentially containing pointers from gen 1 to gen 0.
|
|
||||||
|
|
||||||
During collections, it maps pointers to "from" pages. */
|
|
||||||
#define modify_page_map(addr, page, val) { \
|
|
||||||
long size_left = page->big_page ? page->size : APAGE_SIZE; \
|
|
||||||
void *p = addr; \
|
|
||||||
DECL_PAGE_MAP; \
|
|
||||||
\
|
|
||||||
while(size_left > 0) { \
|
|
||||||
GET_PAGE_MAP(p); \
|
|
||||||
page_map[ADDR_BITS(p)] = val; \
|
|
||||||
size_left -= APAGE_SIZE; \
|
|
||||||
p = (char *)p + APAGE_SIZE; \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
|
|
||||||
inline static void pagemap_add(struct mpage *page)
|
|
||||||
{
|
|
||||||
modify_page_map(page->addr, page, page);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline static void pagemap_remove(struct mpage *page)
|
|
||||||
{
|
|
||||||
modify_page_map(page->addr, page, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline static mpage *pagemap_find_page(void *p)
|
|
||||||
{
|
|
||||||
DECL_PAGE_MAP;
|
|
||||||
FIND_PAGE_MAP(p);
|
|
||||||
return page_map[ADDR_BITS(p)];
|
|
||||||
}
|
|
||||||
|
|
||||||
int GC_is_allocated(void *p)
|
|
||||||
{
|
|
||||||
return !!pagemap_find_page(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
static size_t round_to_apage_size(size_t sizeb)
|
static size_t round_to_apage_size(size_t sizeb)
|
||||||
{
|
{
|
||||||
sizeb += APAGE_SIZE - 1;
|
sizeb += APAGE_SIZE - 1;
|
||||||
|
@ -362,6 +383,8 @@ static void free_mpage(struct mpage *page)
|
||||||
free(page);
|
free(page);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static unsigned long custodian_single_time_limit(int set);
|
static unsigned long custodian_single_time_limit(int set);
|
||||||
inline static int thread_get_owner(void *p);
|
inline static int thread_get_owner(void *p);
|
||||||
|
|
||||||
|
@ -453,17 +476,21 @@ static void *allocate_big(size_t sizeb, int type)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
inline static struct mpage *gen0_create_new_mpage() {
|
inline static struct mpage *gen0_create_new_mpage() {
|
||||||
struct mpage *work;
|
mpage *newmpage;
|
||||||
work = malloc_mpage();
|
|
||||||
work->addr = malloc_dirty_pages(GEN0_PAGE_SIZE, APAGE_SIZE);
|
|
||||||
|
|
||||||
work->big_page = 1; /* until added */
|
newmpage = malloc_mpage();
|
||||||
work->size = GEN0_PAGE_SIZE; /* until added */
|
newmpage->addr = malloc_dirty_pages(GEN0_PAGE_SIZE, APAGE_SIZE);
|
||||||
pagemap_add(work);
|
newmpage->big_page = 0;
|
||||||
work->size = PREFIX_SIZE;
|
newmpage->size = PREFIX_SIZE;
|
||||||
work->big_page = 0;
|
pagemap_add_with_size(newmpage, GEN0_PAGE_SIZE);
|
||||||
|
|
||||||
return work;
|
return newmpage;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static void gen0_free_mpage(mpage *page) {
|
||||||
|
pagemap_remove_with_size(page, GEN0_PAGE_SIZE);
|
||||||
|
free_pages(page->addr, GEN0_PAGE_SIZE);
|
||||||
|
free_mpage(page);
|
||||||
}
|
}
|
||||||
|
|
||||||
//#define OVERFLOWS_GEN0(ptr) ((ptr) > (NUM(GC->gen0.curr_alloc_page->addr) + GEN0_PAGE_SIZE))
|
//#define OVERFLOWS_GEN0(ptr) ((ptr) > (NUM(GC->gen0.curr_alloc_page->addr) + GEN0_PAGE_SIZE))
|
||||||
|
|
|
@ -71,22 +71,6 @@ typedef struct Gen0 {
|
||||||
unsigned long max_size;
|
unsigned long max_size;
|
||||||
} Gen0;
|
} Gen0;
|
||||||
|
|
||||||
typedef struct finalizer {
|
|
||||||
char eager_level;
|
|
||||||
char tagged;
|
|
||||||
void *p;
|
|
||||||
GC_finalization_proc f;
|
|
||||||
void *data;
|
|
||||||
#if CHECKS
|
|
||||||
long size;
|
|
||||||
#endif
|
|
||||||
struct finalizer *next;
|
|
||||||
/* Patched after GC: */
|
|
||||||
struct finalizer *prev;
|
|
||||||
struct finalizer *left;
|
|
||||||
struct finalizer *right;
|
|
||||||
} Fnl;
|
|
||||||
|
|
||||||
typedef struct Weak_Finalizer {
|
typedef struct Weak_Finalizer {
|
||||||
void *p;
|
void *p;
|
||||||
int offset;
|
int offset;
|
||||||
|
@ -105,6 +89,11 @@ typedef struct NewGC {
|
||||||
Gen0 gen0;
|
Gen0 gen0;
|
||||||
Mark_Proc *mark_table; /* the table of mark procs */
|
Mark_Proc *mark_table; /* the table of mark procs */
|
||||||
Fixup_Proc *fixup_table; /* the table of repair procs */
|
Fixup_Proc *fixup_table; /* the table of repair procs */
|
||||||
|
#ifdef SIXTY_FOUR_BIT_INTEGERS
|
||||||
|
mpage ****page_mapss;
|
||||||
|
#else
|
||||||
|
mpage **page_map;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Finalization */
|
/* Finalization */
|
||||||
Fnl *run_queue;
|
Fnl *run_queue;
|
||||||
|
@ -121,9 +110,6 @@ typedef struct NewGC {
|
||||||
void (*unsafe_allocation_abort)();
|
void (*unsafe_allocation_abort)();
|
||||||
unsigned long memory_in_use; /* the amount of memory in use */
|
unsigned long memory_in_use; /* the amount of memory in use */
|
||||||
|
|
||||||
void *park[2];
|
|
||||||
void *park_save[2];
|
|
||||||
|
|
||||||
/* blame the child saved off Mark_Proc pointers */
|
/* blame the child saved off Mark_Proc pointers */
|
||||||
Mark_Proc normal_thread_mark;
|
Mark_Proc normal_thread_mark;
|
||||||
Mark_Proc normal_custodian_mark;
|
Mark_Proc normal_custodian_mark;
|
||||||
|
@ -145,6 +131,12 @@ typedef struct NewGC {
|
||||||
unsigned long num_minor_collects;
|
unsigned long num_minor_collects;
|
||||||
unsigned long num_major_collects;
|
unsigned long num_major_collects;
|
||||||
|
|
||||||
|
GC_Immobile_Box *immobile_boxes;
|
||||||
|
|
||||||
|
/* Common with CompactGC */
|
||||||
|
void *park[2];
|
||||||
|
void *park_save[2];
|
||||||
|
|
||||||
unsigned short weak_array_tag;
|
unsigned short weak_array_tag;
|
||||||
unsigned short weak_box_tag;
|
unsigned short weak_box_tag;
|
||||||
unsigned short ephemeron_tag;
|
unsigned short ephemeron_tag;
|
||||||
|
@ -155,13 +147,18 @@ typedef struct NewGC {
|
||||||
GC_Weak_Box *weak_boxes;
|
GC_Weak_Box *weak_boxes;
|
||||||
GC_Ephemeron *ephemerons;
|
GC_Ephemeron *ephemerons;
|
||||||
int num_last_seen_ephemerons;
|
int num_last_seen_ephemerons;
|
||||||
GC_Immobile_Box *immobile_boxes;
|
|
||||||
} NewGC;
|
} 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->mark_table = malloc(NUMBER_OF_TAGS * sizeof (Mark_Proc));
|
||||||
newgc->fixup_table = malloc(NUMBER_OF_TAGS * sizeof (Fixup_Proc));
|
newgc->fixup_table = malloc(NUMBER_OF_TAGS * sizeof (Fixup_Proc));
|
||||||
|
#ifdef SIXTY_FOUR_BIT_INTEGERS
|
||||||
|
newgc->page_mapss = malloc(PAGEMAP64_LEVEL1_SIZE * sizeof (mpage***));
|
||||||
|
#else
|
||||||
|
newgc->page_map = malloc(PAGEMAP32_SIZE * sizeof (mpage*));
|
||||||
|
#endif
|
||||||
|
|
||||||
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;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user