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 @@
* Much hacked by Paul Werkowski
* 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,
/* Check if the fault is within the dynamic space. */
if (page_index != -1) {
/* Un-protect the page */
/* Un-protect the page */
/* The page should have been marked write_protected */
if (page_table[page_index].write_protected != 1)
fprintf(stderr,"*** Sigbus in page not marked as write protected");
/* The page should have been marked write_protected */
if (!PAGE_WRITE_PROTECTED(page_index))
fprintf(stderr,"*** Sigbus in page not marked as write protected");
os_protect(page_address(page_index), 4096, OS_VM_PROT_ALL);
page_table[page_index].write_protected = 0;
page_table[page_index].write_protected_cleared = 1;
#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
os_protect(page_address(page_index), 4096, OS_VM_PROT_ALL);
page_table[page_index].flags &= ~PAGE_WRITE_PROTECTED_MASK;
page_table[page_index].flags |= PAGE_WRITE_PROTECT_CLEARED_MASK;
return;
return;
}
#endif
......
......@@ -15,7 +15,7 @@
* GENCGC support by Douglas Crosher, 1996, 1997.
* 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)
/* Check if the fault is within the dynamic space. */
if ( page_index!=-1 ) {
/* Un-protect the page */
/* The page should have been marked write_protected */
if (page_table[page_index].write_protected != 1)
/* The page should have been marked write protected */
if (!PAGE_WRITE_PROTECTED(page_index))
fprintf(stderr,"*** Sigsegv in page not marked as write protected");
os_protect(page_address(page_index), 4096, OS_VM_PROT_ALL);
page_table[page_index].write_protected = 0;
page_table[page_index].write_protected_cleared = 1;
page_table[page_index].flags &= ~PAGE_WRITE_PROTECTED_MASK;
page_table[page_index].flags |= PAGE_WRITE_PROTECT_CLEARED_MASK;
return;
}
......
This diff is collapsed.
......@@ -7,7 +7,7 @@
*
* 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 *);
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 {
/* 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. */
unsigned write_protected :1,
/* 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. */
write_protected_cleared :1,
/* The region the page is allocated to: 0 for a free page; 1 for
boxed objects; 2 for unboxed objects. If the page is free the
following slots are invalid (well the bytes_used must be 0). */
allocated :2,
/* 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;
/*
* Page flags.
*/
unsigned flags;
/*
* It is important to know the offset to the first object in the
* 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;
/* The number of bytes of this page that are used. This may be less
than the actual bytes used for pages within the current
allocation regions. It should be 0 for all unallocated pages (not
hard to achieve). */
int bytes_used;
/* It is important to know the offset to the first object in the
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;
/*
* The number of bytes of this page that are used. This may be less
* than the actual bytes used for pages within the current
* allocation regions. It should be 0 for all unallocated pages (not
* hard to achieve).
*/
int bytes_used;
};
#define FREE_PAGE 0
#define BOXED_PAGE 1
#define UNBOXED_PAGE 2
/* The number of pages needed for the dynamic space - rounding up. */
#define NUM_PAGES ((DYNAMIC_SPACE_SIZE+4095)/4096)
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 {
/* These two are needed for quick allocation */
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