Skip to content
Snippets Groups Projects
Commit e7e59d7d authored by dtc's avatar dtc
Browse files

Improve the packing of information into the page table, reducing the

table size by 25%, and move to a fixed layout of the page flags to
better support future atomic operations for threaded code.
parent 2bf0de4c
No related branches found
No related tags found
No related merge requests found
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
* Much hacked by Paul Werkowski * Much hacked by Paul Werkowski
* GENCGC support by Douglas Crosher, 1996, 1997. * GENCGC support by Douglas Crosher, 1996, 1997.
* *
* $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/FreeBSD-os.c,v 1.3 1999/02/25 12:41:02 pw Exp $ * $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/FreeBSD-os.c,v 1.4 1999/08/25 14:25:06 dtc Exp $
* *
*/ */
...@@ -183,40 +183,17 @@ sigbus_handler(int signal, int code, struct sigcontext *context, ...@@ -183,40 +183,17 @@ sigbus_handler(int signal, int code, struct sigcontext *context,
/* Check if the fault is within the dynamic space. */ /* Check if the fault is within the dynamic space. */
if (page_index != -1) { if (page_index != -1) {
/* Un-protect the page */ /* Un-protect the page */
/* The page should have been marked write_protected */ /* The page should have been marked write_protected */
if (page_table[page_index].write_protected != 1) if (!PAGE_WRITE_PROTECTED(page_index))
fprintf(stderr,"*** Sigbus in page not marked as write protected"); fprintf(stderr,"*** Sigbus in page not marked as write protected");
os_protect(page_address(page_index), 4096, OS_VM_PROT_ALL); os_protect(page_address(page_index), 4096, OS_VM_PROT_ALL);
page_table[page_index].write_protected = 0; page_table[page_index].flags &= ~PAGE_WRITE_PROTECTED_MASK;
page_table[page_index].write_protected_cleared = 1; page_table[page_index].flags |= PAGE_WRITE_PROTECT_CLEARED_MASK;
#if SIGBUS_VERBOSE
fprintf(stderr,"* page: gen=%d bytes_used=%d first_object_offset=%d dont_move=%d\n",
page_table[page_index].gen,
page_table[page_index].bytes_used,
page_table[page_index].first_object_offset,
page_table[page_index].dont_move);
fprintf(stderr,"* data: %x %x %x %x\n",
*(((long *)fault_addr)-1),
*(((long *)fault_addr)-0),
*(((long *)fault_addr)+1),
*(((long *)fault_addr)+2));
{
int pi2 = find_page_index(*(((long *)fault_addr)-0));
if ( pi2!=-1 )
fprintf(stderr,"* pi2: gen=%d bytes_used=%d first_object_offset=%d dont_move=%d\n",
page_table[pi2].gen,
page_table[pi2].bytes_used,
page_table[pi2].first_object_offset,
page_table[pi2].dont_move);
}
#endif
return; return;
} }
#endif #endif
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* GENCGC support by Douglas Crosher, 1996, 1997. * GENCGC support by Douglas Crosher, 1996, 1997.
* Alpha support by Julian Dolby, 1999. * Alpha support by Julian Dolby, 1999.
* *
* $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/Linux-os.c,v 1.7 1999/02/22 11:26:41 dtc Exp $ * $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/Linux-os.c,v 1.8 1999/08/25 14:25:06 dtc Exp $
* *
*/ */
...@@ -268,12 +268,12 @@ void sigsegv_handler(HANDLER_ARGS) ...@@ -268,12 +268,12 @@ void sigsegv_handler(HANDLER_ARGS)
/* Check if the fault is within the dynamic space. */ /* Check if the fault is within the dynamic space. */
if ( page_index!=-1 ) { if ( page_index!=-1 ) {
/* Un-protect the page */ /* Un-protect the page */
/* The page should have been marked write_protected */ /* The page should have been marked write protected */
if (page_table[page_index].write_protected != 1) if (!PAGE_WRITE_PROTECTED(page_index))
fprintf(stderr,"*** Sigsegv in page not marked as write protected"); fprintf(stderr,"*** Sigsegv in page not marked as write protected");
os_protect(page_address(page_index), 4096, OS_VM_PROT_ALL); os_protect(page_address(page_index), 4096, OS_VM_PROT_ALL);
page_table[page_index].write_protected = 0; page_table[page_index].flags &= ~PAGE_WRITE_PROTECTED_MASK;
page_table[page_index].write_protected_cleared = 1; page_table[page_index].flags |= PAGE_WRITE_PROTECT_CLEARED_MASK;
return; return;
} }
......
This diff is collapsed.
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* Douglas Crosher, 1996, 1997. * Douglas Crosher, 1996, 1997.
* *
* $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/gencgc.h,v 1.1 1997/11/25 17:59:20 dtc Exp $ * $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/gencgc.h,v 1.2 1999/08/25 14:25:07 dtc Exp $
* *
*/ */
...@@ -19,57 +19,114 @@ inline int find_page_index(void *); ...@@ -19,57 +19,114 @@ inline int find_page_index(void *);
inline void *page_address(int); inline void *page_address(int);
/*
* Set when the page is write protected. If it is writen into it is
* made writable and this flag is cleared. This should always reflect
* the actual write_protect status of a page.
*/
#define PAGE_WRITE_PROTECTED_MASK 0x00000010
#define PAGE_WRITE_PROTECTED(page) \
(page_table[page].flags & PAGE_WRITE_PROTECTED_MASK)
/*
* This flag is set when the above write protect flag is clear by the
* sigbus handler. This is useful for re-scavenging pages that are
* written during a GC.
*/
#define PAGE_WRITE_PROTECT_CLEARED_MASK 0x00000020
#define PAGE_WRITE_PROTECT_CLEARED(page) \
(page_table[page].flags & PAGE_WRITE_PROTECT_CLEARED_MASK)
/*
* Page allocated flag: 0 for a free page; 1 when allocated. If
* the page is free then the following slots are invalid - well
* the bytes_used must be 0.
*/
#define PAGE_ALLOCATED_MASK 0x00000040
#define PAGE_ALLOCATED(page) (page_table[page].flags & PAGE_ALLOCATED_MASK)
/*
* Unboxed region flag: 1 for unboxed objects, 0 for boxed objects.
*/
#define PAGE_UNBOXED_MASK 0x00000080
#define PAGE_UNBOXED_SHIFT 7
#define PAGE_UNBOXED(page) (page_table[page].flags & PAGE_UNBOXED_MASK)
#define PAGE_UNBOXED_VAL(page) (PAGE_UNBOXED(page) >> PAGE_UNBOXED_SHIFT)
/*
* If this page should not be moved during a GC then this flag is
* set. It's only valid during a GC for allocated pages.
*/
#define PAGE_DONT_MOVE_MASK 0x00000100
#define PAGE_DONT_MOVE(page) \
(page_table[page].flags & PAGE_DONT_MOVE_MASK)
/*
* If the page is part of a large object then this flag is set. No
* other objects should be allocated to these pages. This is only
* valid when the page is allocated.
*/
#define PAGE_LARGE_OBJECT_MASK 0x00000200
#define PAGE_LARGE_OBJECT_SHIFT 9
#define PAGE_LARGE_OBJECT(page) \
(page_table[page].flags & PAGE_LARGE_OBJECT_MASK)
#define PAGE_LARGE_OBJECT_VAL(page) \
(PAGE_LARGE_OBJECT(page) >> PAGE_LARGE_OBJECT_SHIFT)
/*
* The generation that this page belongs to. This should be valid for
* all pages that may have objects allocated, even current allocation
* region pages - this allows the space of an object to be easily
* determined.
*/
#define PAGE_GENERATION_MASK 0x0000000f
#define PAGE_GENERATION(page) \
(page_table[page].flags & PAGE_GENERATION_MASK)
#define PAGE_FLAGS(page, mask) (page_table[page].flags & (mask))
#define PAGE_FLAGS_UPDATE(page, mmask, mflags) \
(page_table[page].flags = (page_table[page].flags & ~(mmask)) | (mflags))
struct page { struct page {
/* Set when the page is write protected. If it is writen into it /*
is made writable and this flag is cleared. This should always * Page flags.
reflect the actual write_protect status of a page. */ */
unsigned write_protected :1,
/* This flag is set when the above write protect flag is clear by unsigned flags;
the sigbus handler. This is useful for re-scavenging pages that
are written during a GC. */ /*
write_protected_cleared :1, * It is important to know the offset to the first object in the
/* The region the page is allocated to: 0 for a free page; 1 for * page. Currently it's only important to know if an object starts
boxed objects; 2 for unboxed objects. If the page is free the * at the begining of the page in which case the offset would be 0
following slots are invalid (well the bytes_used must be 0). */ */
allocated :2, int first_object_offset;
/* If this page should not be moved during a GC then this flag is
set. It's only valid during a GC for allocated pages. */
dont_move :1,
/* If the page is part of a large object then this flag is set. No
other objects should be allocated to these pages. This is only
valid when the page is allocated. */
large_object :1;
/* The generation that this page belongs to. This should be valid
for all pages that may have objects allocated, even current
allocation region pages - this allows the space of an object to
be easily determined. */
int gen;
/* The number of bytes of this page that are used. This may be less /*
than the actual bytes used for pages within the current * The number of bytes of this page that are used. This may be less
allocation regions. It should be 0 for all unallocated pages (not * than the actual bytes used for pages within the current
hard to achieve). */ * allocation regions. It should be 0 for all unallocated pages (not
int bytes_used; * hard to achieve).
*/
/* It is important to know the offset to the first object in the int bytes_used;
page. Currently it's only important to know if an object starts
at the begining of the page in which case the offset would be 0 */
int first_object_offset;
}; };
#define FREE_PAGE 0
#define BOXED_PAGE 1
#define UNBOXED_PAGE 2
/* The number of pages needed for the dynamic space - rounding up. */ /* The number of pages needed for the dynamic space - rounding up. */
#define NUM_PAGES ((DYNAMIC_SPACE_SIZE+4095)/4096) #define NUM_PAGES ((DYNAMIC_SPACE_SIZE+4095)/4096)
extern struct page page_table[NUM_PAGES]; extern struct page page_table[NUM_PAGES];
/* Abstract out the data for an allocation region allowing a single /*
routine to be used for allocation and closing. */ * Abstract out the data for an allocation region allowing a single
* routine to be used for allocation and closing.
*/
struct alloc_region { struct alloc_region {
/* These two are needed for quick allocation */ /* These two are needed for quick allocation */
void *free_pointer; void *free_pointer;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment