* 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__)
+/* 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;
/* 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));
&& (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;
* instead. See hpux-os.c for some useful restrictions on actual
* usage. */
-/* FIXME: this should be turned into a pure inline memset where it is used. */
void
os_zero(os_vm_address_t addr, os_vm_size_t length)
{
- memset(addr, 0, length);
+ os_vm_address_t block_start;
+ os_vm_size_t block_size;
+
+#ifdef DEBUG
+ fprintf(stderr,";;; os_zero: addr: 0x%08x, len: 0x%08x\n",addr,length);
+#endif
+
+ block_start = os_round_up_to_page(addr);
+
+ length -= block_start-addr;
+ block_size = os_trunc_size_to_page(length);
+
+ if (block_start > addr)
+ bzero((char *)addr, block_start-addr);
+ if (block_size < length)
+ bzero((char *)block_start+block_size, length-block_size);
+
+ if (block_size != 0) {
+ /* Now deallocate and allocate the block so that it faults in
+ * zero-filled. */
+
+ os_invalidate(block_start, block_size);
+ addr = os_validate(block_start, block_size);
+
+ if (addr == NULL || addr != block_start)
+ lose("os_zero: block moved! 0x%08x ==> 0x%08x",
+ block_start,
+ addr);
+ }
}
os_vm_address_t