* that don't have pointers to younger generations? */
boolean enable_page_protection = 1;
+/* Should we unmap a page and re-mmap it to have it zero filled? */
+#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
+/* comment from cmucl-2.4.8: This can waste a lot of swap on FreeBSD
+ * so don't unmap there.
+ *
+ * The CMU CL comment didn't specify a version, but was probably an
+ * old version of FreeBSD (pre-4.0), so this might no longer be true.
+ * OTOH, if it is true, this behavior might exist on OpenBSD too, so
+ * for now we don't unmap there either. -- WHN 2001-04-07 */
+boolean gencgc_unmap_zero = 0;
+#else
+boolean gencgc_unmap_zero = 1;
+#endif
+
/* the minimum size (in bytes) for a large object*/
unsigned large_object_size = 4 * PAGE_BYTES;
/* the verbosity level. All non-error messages are disabled at level 0;
* and only a few rare messages are printed at level 1. */
-unsigned gencgc_verbose = (QSHOW ? 1 : 0);
+#ifdef QSHOW
+unsigned gencgc_verbose = 1;
+#else
+unsigned gencgc_verbose = 0;
+#endif
/* FIXME: At some point enable the various error-checking things below
* and see what they say. */
/* Calculate the start address for the given page number. */
-static inline void *
+inline void *
page_address(int page_num)
{
return (heap_base + (page_num * PAGE_BYTES));
return count;
}
-#if QSHOW
+#ifdef QSHOW
static int
count_dont_move_pages(void)
{
unsigned d2 = *((unsigned char *)p - 2);
unsigned d3 = *((unsigned char *)p - 3);
unsigned d4 = *((unsigned char *)p - 4);
-#if QSHOW
+#ifdef QSHOW
unsigned d5 = *((unsigned char *)p - 5);
unsigned d6 = *((unsigned char *)p - 6);
#endif
}
\f
-/* Scan an area looking for an object which encloses the given pointer.
- * Return the object start on success or NULL on failure. */
-static lispobj *
-search_space(lispobj *start, size_t words, lispobj *pointer)
-{
- while (words > 0) {
- size_t count = 1;
- lispobj thing = *start;
-
- /* If thing is an immediate then this is a cons. */
- if (is_lisp_pointer(thing)
- || ((thing & 3) == 0) /* fixnum */
- || (widetag_of(thing) == BASE_CHAR_WIDETAG)
- || (widetag_of(thing) == UNBOUND_MARKER_WIDETAG))
- count = 2;
- else
- count = (sizetab[widetag_of(thing)])(start);
-
- /* Check whether the pointer is within this object. */
- if ((pointer >= start) && (pointer < (start+count))) {
- /* found it! */
- /*FSHOW((stderr,"/found %x in %x %x\n", pointer, start, thing));*/
- return(start);
- }
-
- /* Round up the count. */
- count = CEILING(count,2);
-
- start += count;
- words -= count;
- }
- return (NULL);
-}
-
-lispobj*
-search_read_only_space(lispobj *pointer)
+lispobj *
+search_read_only_space(void *pointer)
{
- lispobj* start = (lispobj*)READ_ONLY_SPACE_START;
- lispobj* end = (lispobj*)SymbolValue(READ_ONLY_SPACE_FREE_POINTER,0);
- if ((pointer < start) || (pointer >= end))
+ lispobj *start = (lispobj *) READ_ONLY_SPACE_START;
+ lispobj *end = (lispobj *) SymbolValue(READ_ONLY_SPACE_FREE_POINTER,0);
+ if ((pointer < (void *)start) || (pointer >= (void *)end))
return NULL;
- return (search_space(start, (pointer+2)-start, pointer));
+ return (search_space(start,
+ (((lispobj *)pointer)+2)-start,
+ (lispobj *) pointer));
}
lispobj *
-search_static_space(lispobj *pointer)
+search_static_space(void *pointer)
{
- lispobj* start = (lispobj*)STATIC_SPACE_START;
- lispobj* end = (lispobj*)SymbolValue(STATIC_SPACE_FREE_POINTER,0);
- if ((pointer < start) || (pointer >= end))
+ lispobj *start = (lispobj *)STATIC_SPACE_START;
+ lispobj *end = (lispobj *)SymbolValue(STATIC_SPACE_FREE_POINTER,0);
+ if ((pointer < (void *)start) || (pointer >= (void *)end))
return NULL;
- return (search_space(start, (pointer+2)-start, pointer));
+ return (search_space(start,
+ (((lispobj *)pointer)+2)-start,
+ (lispobj *) pointer));
}
/* a faster version for searching the dynamic space. This will work even
* if the object is in a current allocation region. */
lispobj *
-search_dynamic_space(lispobj *pointer)
+search_dynamic_space(void *pointer)
{
int page_index = find_page_index(pointer);
lispobj *start;
return NULL;
start = (lispobj *)((void *)page_address(page_index)
+ page_table[page_index].first_object_offset);
- return (search_space(start, (pointer+2)-start, pointer));
+ return (search_space(start,
+ (((lispobj *)pointer)+2)-start,
+ (lispobj *)pointer));
}
/* Is there any possibility that pointer is a valid Lisp object
&& (page_table[last_page].bytes_used != 0)
&& (page_table[last_page].gen == from_space));
- /* Zero pages from first_page to (last_page-1). */
- memset(page_address(first_page), 0, PAGE_BYTES*(last_page-first_page));
+ /* Zero pages from first_page to (last_page-1).
+ *
+ * FIXME: Why not use os_zero(..) function instead of
+ * hand-coding this again? (Check other gencgc_unmap_zero
+ * stuff too. */
+ if (gencgc_unmap_zero) {
+ void *page_start, *addr;
+
+ page_start = (void *)page_address(first_page);
+
+ os_invalidate(page_start, PAGE_BYTES*(last_page-first_page));
+ addr = os_validate(page_start, PAGE_BYTES*(last_page-first_page));
+ if (addr == NULL || addr != page_start) {
+ lose("free_oldspace: page moved, 0x%08x ==> 0x%08x",page_start,
+ addr);
+ }
+ } else {
+ int *page_start;
+
+ page_start = (int *)page_address(first_page);
+ memset(page_start, 0,PAGE_BYTES*(last_page-first_page));
+ }
first_page = last_page;
}
}
-#if QSHOW
+#ifdef QSHOW
if (gencgc_verbose > 1) {
int num_dont_move_pages = count_dont_move_pages();
fprintf(stderr,
new_obj = gc_alloc_with_region(nbytes,0,region,0);
return (new_obj);
}
-
-\f
-/* Find the code object for the given pc, or return NULL on failure.
- *
- * FIXME: PC shouldn't be lispobj*, should it? Maybe void*? */
-lispobj *
-component_ptr_from_pc(lispobj *pc)
-{
- lispobj *object = NULL;
-
- if ( (object = search_read_only_space(pc)) )
- ;
- else if ( (object = search_static_space(pc)) )
- ;
- else
- object = search_dynamic_space(pc);
-
- if (object) /* if we found something */
- if (widetag_of(*object) == CODE_HEADER_WIDETAG) /* if it's a code object */
- return(object);
-
- return (NULL);
-}
\f
/*
* shared support for the OS-dependent signal handlers which
{
int page_index = find_page_index(fault_addr);
-#if defined QSHOW_SIGNALS
+#ifdef QSHOW_SIGNALS
FSHOW((stderr, "heap WP violation? fault_addr=%x, page_index=%d\n",
fault_addr, page_index));
#endif