prep SGC for 64-bit machines

svn: r3637
This commit is contained in:
Matthew Flatt 2006-07-06 21:46:46 +00:00
parent caf1eb6f0e
commit c3c98ebd6c
4 changed files with 83 additions and 30 deletions

View File

@ -26,7 +26,7 @@ test: $(OBJS) test.o
gcobjects: $(OBJS) gcobjects: $(OBJS)
sgc.o: $(srcdir)/sgc.c $(srcdir)/autostat.inc $(srcdir)/collect.inc $(srcdir)/splay.c sgc.o: $(srcdir)/sgc.c $(srcdir)/autostat.inc $(srcdir)/collect.inc $(srcdir)/../utils/splay.c
$(CC) $(CFLAGS) -I.. -c $(srcdir)/sgc.c -o sgc.o $(CC) $(CFLAGS) -I.. -c $(srcdir)/sgc.c -o sgc.o
test.o: $(srcdir)/test.c test.o: $(srcdir)/test.c

View File

@ -26,24 +26,13 @@
*/ */
#ifdef __palmos__
# include <PalmOS.h>
# define _LINUX_TYPES_H /* Blocks types.h */
#endif
#include <stdlib.h> #include <stdlib.h>
#include <setjmp.h> #include <setjmp.h>
#include <stdio.h> #include <stdio.h>
#ifndef __palmos__
# include <memory.h>
#endif
#include <string.h> #include <string.h>
#include "../sconfig.h" #include "../sconfig.h"
#include "sgc.h" #include "sgc.h"
#ifdef PALMOS_STUFF
typedef jmpbuf jmp_buf[1];
#endif
/****************************************************************************/ /****************************************************************************/
/* Option bundles */ /* Option bundles */
/****************************************************************************/ /****************************************************************************/
@ -193,6 +182,10 @@ typedef jmpbuf jmp_buf[1];
#define DUMP_SECTOR_MAP 1 #define DUMP_SECTOR_MAP 1
/* GC_dump prints detail information about existing /* GC_dump prints detail information about existing
sectors. */ sectors. */
#ifdef SIXTY_FOUR_BIT_INTEGERS
# undef DUMP_SECTOR_MAP
# define DUMP_SECTOR_MAP 0
#endif
#define DUMP_BLOCK_MAPS 1 /* 0 */ #define DUMP_BLOCK_MAPS 1 /* 0 */
/* GC_dump prints detail information about block and /* GC_dump prints detail information about block and
@ -283,8 +276,15 @@ typedef jmpbuf jmp_buf[1];
#endif #endif
/* System-specific alignment of pointers. */ /* System-specific alignment of pointers. */
#ifdef SIXTY_FOUR_BIT_INTEGERS
# define PTR_ALIGNMENT 8
# define LOG_PTR_SIZE 3
# define LOW_32_BITS(x) (x & 0xFFFFFFFF)
#else
# define PTR_ALIGNMENT 4 # define PTR_ALIGNMENT 4
# define LOG_PTR_SIZE 2 # define LOG_PTR_SIZE 2
# define LOW_32_BITS(x) x
#endif
# define PTR_SIZE (1 << LOG_PTR_SIZE) # define PTR_SIZE (1 << LOG_PTR_SIZE)
#define DOUBLE_SIZE sizeof(double) #define DOUBLE_SIZE sizeof(double)
@ -293,11 +293,7 @@ typedef jmpbuf jmp_buf[1];
Since it should be a power of 2, LOG_SECTOR_SEGMENT_SIZE is Since it should be a power of 2, LOG_SECTOR_SEGMENT_SIZE is
specified directly. A larger block size speeds up GC, but wastes specified directly. A larger block size speeds up GC, but wastes
more unallocated bytes in same-size buckets. */ more unallocated bytes in same-size buckets. */
#ifdef __palmos__
# define LOG_SECTOR_SEGMENT_SIZE 9
#else
#define LOG_SECTOR_SEGMENT_SIZE 12 #define LOG_SECTOR_SEGMENT_SIZE 12
#endif
#define SECTOR_SEGMENT_SIZE (1 << LOG_SECTOR_SEGMENT_SIZE) #define SECTOR_SEGMENT_SIZE (1 << LOG_SECTOR_SEGMENT_SIZE)
#define SECTOR_SEGMENT_MASK (~(SECTOR_SEGMENT_SIZE-1)) #define SECTOR_SEGMENT_MASK (~(SECTOR_SEGMENT_SIZE-1))
@ -311,20 +307,24 @@ typedef jmpbuf jmp_buf[1];
malloc() to avoid waste when obtaining the proper alignment. */ malloc() to avoid waste when obtaining the proper alignment. */
#define SECTOR_SEGMENT_GROUP_SIZE 32 #define SECTOR_SEGMENT_GROUP_SIZE 32
/* Number of bits used in first level table for checking existance of /* Number of bits used in 32-bit level table for checking existance of
a sector. Creates a table of (1 << SECTOR_LOOKUP_SHIFT) pointers a sector. Creates a table of (1 << SECTOR_LOOKUP_SHIFT) pointers
to individual page tables of size SECTOR_LOOKUP_PAGESIZE. */ to individual page tables of size SECTOR_LOOKUP_PAGESIZE. */
#define SECTOR_LOOKUP_PAGESETBITS 12 #define SECTOR_LOOKUP_PAGESETBITS 12
#define SECTOR_LOOKUP_SHIFT ((PTR_SIZE*8) - SECTOR_LOOKUP_PAGESETBITS) #define LOG_MAP_PTR_SIZE 2
#define LOG_SECTOR_LOOKUP_PAGESIZE ((PTR_SIZE*8) - SECTOR_LOOKUP_PAGESETBITS - LOG_SECTOR_SEGMENT_SIZE) #define MAP_PTR_SIZE 4
#define SECTOR_LOOKUP_SHIFT ((MAP_PTR_SIZE*8) - SECTOR_LOOKUP_PAGESETBITS)
#define LOG_SECTOR_LOOKUP_PAGESIZE ((MAP_PTR_SIZE*8) - SECTOR_LOOKUP_PAGESETBITS - LOG_SECTOR_SEGMENT_SIZE)
#define SECTOR_LOOKUP_PAGESIZE (1 << LOG_SECTOR_LOOKUP_PAGESIZE) #define SECTOR_LOOKUP_PAGESIZE (1 << LOG_SECTOR_LOOKUP_PAGESIZE)
#define SECTOR_LOOKUP_PAGEMASK (SECTOR_LOOKUP_PAGESIZE - 1) #define SECTOR_LOOKUP_PAGEMASK (SECTOR_LOOKUP_PAGESIZE - 1)
#define SECTOR_LOOKUP_PAGETABLE(x) (x >> SECTOR_LOOKUP_SHIFT) #define SECTOR_LOOKUP_PAGETABLE(x) (LOW_32_BITS(x) >> SECTOR_LOOKUP_SHIFT)
#define SECTOR_LOOKUP_PAGEPOS(x) ((x >> LOG_SECTOR_SEGMENT_SIZE) & SECTOR_LOOKUP_PAGEMASK) #define SECTOR_LOOKUP_PAGEPOS(x) ((LOW_32_BITS(x) >> LOG_SECTOR_SEGMENT_SIZE) & SECTOR_LOOKUP_PAGEMASK)
#define LOG_SECTOR_PAGEREC_SIZE (LOG_MAP_PTR_SIZE + 1)
#define LOG_SECTOR_PAGEREC_SIZE (LOG_PTR_SIZE + 1)
/***************************************************************************/ /***************************************************************************/
@ -569,7 +569,45 @@ typedef struct {
is deallocated, but 0 => not in any sector */ is deallocated, but 0 => not in any sector */
} SectorPage; } SectorPage;
#ifdef SIXTY_FOUR_BIT_INTEGERS
static SectorPage ***sector_pagetablesss[1 << 16];
# define DECL_SECTOR_PAGETABLES SectorPage **sector_pagetables;
# define GET_SECTOR_PAGETABLES(p) sector_pagetables = create_sector_pagetables(p);
# define FIND_SECTOR_PAGETABLES(p) sector_pagetables = get_sector_pagetables(p); if (!sector_pagetables) return NULL
inline static SectorPage **create_sector_pagetables(unsigned long p) {
unsigned long pos;
SectorPage ***sector_pagetabless, **sector_pagetables;
pos = (unsigned long)p >> 48;
sector_pagetabless = sector_pagetablesss[pos];
if (!sector_pagetabless) {
sector_pagetabless = (SectorPage ***)malloc_plain_sector(sizeof(SectorPage **) * (1 << 16));
sector_pagetablesss[pos] = sector_pagetabless;
}
pos = ((unsigned long)p >> 32) & ((1 << 16) - 1);
sector_pagetables = sector_pagetabless[pos];
if (!sector_pagetables) {
sector_pagetables = (SectorPage **)malloc_plain_sector(sizeof(SectorPage *) * (1 << USEFUL_ADDR_BITS));
sector_pagetabless[pos] = sector_pagetables;
}
return sector_pagetables;
}
inline static SectorPage **get_sector_pagetables(unsigned long p) {
unsigned long pos;
SectorPage ***sector_pagetabless;
pos = (unsigned long)p >> 48;
sector_pagetabless = sector_pagetablesss[pos];
if (!sector_pagetabless)
return NULL;
pos = ((unsigned long)p >> 32) & ((1 << 16) - 1);
return sector_pagetabless[pos];
}
#else
static SectorPage **sector_pagetables; static SectorPage **sector_pagetables;
# define DECL_SECTOR_PAGETABLES /**/
# define GET_SECTOR_PAGETABLES(p) /**/
# define FIND_SECTOR_PAGETABLES(p) /**/
#endif
#if !RELEASE_UNUSED_SECTORS #if !RELEASE_UNUSED_SECTORS
# include "../utils/splay.c" # include "../utils/splay.c"
@ -970,6 +1008,7 @@ static void register_sector(void *naya, int need, long kind)
unsigned long ns, orig_ns; unsigned long ns, orig_ns;
int pagetableindex, pageindex, i; int pagetableindex, pageindex, i;
SectorPage *pagetable; SectorPage *pagetable;
DECL_SECTOR_PAGETABLES;
orig_ns = ns = PTR_TO_INT(naya); orig_ns = ns = PTR_TO_INT(naya);
if (!sector_low_plausible || (ns < sector_low_plausible)) if (!sector_low_plausible || (ns < sector_low_plausible))
@ -980,6 +1019,7 @@ static void register_sector(void *naya, int need, long kind)
/* Register pages as existing: */ /* Register pages as existing: */
for (i = need; i--; ns += SECTOR_SEGMENT_SIZE) { for (i = need; i--; ns += SECTOR_SEGMENT_SIZE) {
GET_SECTOR_PAGETABLES(ns);
pagetableindex = SECTOR_LOOKUP_PAGETABLE(ns); pagetableindex = SECTOR_LOOKUP_PAGETABLE(ns);
pagetable = sector_pagetables[pagetableindex]; pagetable = sector_pagetables[pagetableindex];
if (!pagetable) { if (!pagetable) {
@ -1021,6 +1061,7 @@ static void *malloc_sector(long size, long kind, int no_new)
num_sector_allocs++; num_sector_allocs++;
#ifndef SIXTY_FOUR_BIT_INTEGERS
if (!sector_pagetables) { if (!sector_pagetables) {
int c = (SECTOR_LOOKUP_PAGESETBITS + LOG_PTR_SIZE) - LOG_SECTOR_SEGMENT_SIZE; int c = (SECTOR_LOOKUP_PAGESETBITS + LOG_PTR_SIZE) - LOG_SECTOR_SEGMENT_SIZE;
if (c < 0) if (c < 0)
@ -1031,6 +1072,7 @@ static void *malloc_sector(long size, long kind, int no_new)
for (i = 0; i < (1 << SECTOR_LOOKUP_PAGESETBITS); i++) for (i = 0; i < (1 << SECTOR_LOOKUP_PAGESETBITS); i++)
sector_pagetables[i] = NULL; sector_pagetables[i] = NULL;
} }
#endif
need = (size + SECTOR_SEGMENT_SIZE - 1) >> LOG_SECTOR_SEGMENT_SIZE; need = (size + SECTOR_SEGMENT_SIZE - 1) >> LOG_SECTOR_SEGMENT_SIZE;
@ -1096,8 +1138,10 @@ static void free_sector(void *p)
/* Determine the size: */ /* Determine the size: */
t = s; t = s;
while(1) { while(1) {
DECL_SECTOR_PAGETABLES;
long pagetableindex = SECTOR_LOOKUP_PAGETABLE(t); long pagetableindex = SECTOR_LOOKUP_PAGETABLE(t);
long pageindex = SECTOR_LOOKUP_PAGEPOS(t); long pageindex = SECTOR_LOOKUP_PAGEPOS(t);
GET_SECTOR_PAGETABLES(t);
if (sector_pagetables[pagetableindex] if (sector_pagetables[pagetableindex]
&& (sector_pagetables[pagetableindex][pageindex].start == s)) { && (sector_pagetables[pagetableindex][pageindex].start == s)) {
sector_pagetables[pagetableindex][pageindex].kind = sector_kind_freed; sector_pagetables[pagetableindex][pageindex].kind = sector_kind_freed;
@ -1153,10 +1197,14 @@ static void free_sector(void *p)
#ifdef WIN32 #ifdef WIN32
static int is_sector_segment(void *p) static int is_sector_segment(void *p)
{ {
DECL_SECTOR_PAGETABLES;
unsigned long s = PTR_TO_INT(p); unsigned long s = PTR_TO_INT(p);
long pagetableindex = SECTOR_LOOKUP_PAGETABLE(s); long pagetableindex = SECTOR_LOOKUP_PAGETABLE(s);
long pageindex = SECTOR_LOOKUP_PAGEPOS(s); long pageindex = SECTOR_LOOKUP_PAGEPOS(s);
FIND_SECTOR_PAGETABLES(p);
if (!sector_pagetables) return 0;
return (sector_pagetables[pagetableindex] return (sector_pagetables[pagetableindex]
&& sector_pagetables[pagetableindex][pageindex].start); && sector_pagetables[pagetableindex][pageindex].start);
} }
@ -1599,6 +1647,9 @@ static void *find_ptr(void *d, int *_size,
int find_anyway) int find_anyway)
{ {
unsigned long p = PTR_TO_INT(d); unsigned long p = PTR_TO_INT(d);
DECL_SECTOR_PAGETABLES;
FIND_SECTOR_PAGETABLES(p);
if (!sector_pagetables) if (!sector_pagetables)
return NULL; return NULL;
@ -4656,7 +4707,7 @@ void GC_gcollect(void)
{ {
long dummy; long dummy;
if (!sector_pagetables) if (!sector_mem_use)
return; return;
FLUSH_REGISTER_WINDOWS; FLUSH_REGISTER_WINDOWS;
@ -4669,7 +4720,7 @@ int GC_trace_count(int *stack, int *roots, int *uncollectable, int *final)
#if ALLOW_TRACE_COUNT #if ALLOW_TRACE_COUNT
int j; int j;
if (!sector_pagetables) if (!sector_mem_use)
return 0; return 0;
for (j = 0; j < num_common_sets; j++) { for (j = 0; j < num_common_sets; j++) {
@ -4706,7 +4757,7 @@ void GC_trace_path(void)
#if ALLOW_TRACE_PATH #if ALLOW_TRACE_PATH
int j; int j;
if (!sector_pagetables) if (!sector_mem_use)
return; return;
for (j = 0; j < num_common_sets; j++) { for (j = 0; j < num_common_sets; j++) {

View File

@ -4,6 +4,7 @@
#ifndef MZ_PRECISE_GC #ifndef MZ_PRECISE_GC
# ifdef USE_SENORA_GC # ifdef USE_SENORA_GC
extern void *GC_base(void *d);
# define GC_is_marked(p) GC_base(p) # define GC_is_marked(p) GC_base(p)
# else # else
extern MZ_DLLIMPORT int GC_is_marked(void *); extern MZ_DLLIMPORT int GC_is_marked(void *);

View File

@ -1793,6 +1793,7 @@ typedef struct Scheme_Ephemeron {
static Scheme_Ephemeron *ephemerons, *done_ephemerons; /* not registered as a root! */ static Scheme_Ephemeron *ephemerons, *done_ephemerons; /* not registered as a root! */
#ifdef USE_SENORA_GC #ifdef USE_SENORA_GC
extern void *GC_base(void *d);
# define GC_is_marked(p) GC_base(p) # define GC_is_marked(p) GC_base(p)
# define GC_did_mark_stack_overflow() 0 # define GC_did_mark_stack_overflow() 0
#else #else