This one tries harder to remap the OOP table at the same address where
we had saved it. This obtains the 10% savings promised in part 3. We could try harder (e.g. on Solaris the mmap address is completely disregarded unless you specify MAP_FIXED), but it is not very much worth it for now. The next big thing would be to implement different semantics for the saved objects, in order to avoid the 15% spent in buffer_read and the 8% spent in _gst_mem_alloc. We can probably gain smaller percentages elsewhere just by wasting time upon saving, though. Paolo 2006-12-18 Paolo Bonzini <[hidden email]> * libgst/alloc.c: Adjust calls to _gst_heap_create. * libgst/lib.c: Likewise. * libgst/oop.c: Likewise. * libgst/save.c: Likewise. * libgst/heap.c: Add address parameter to _gst_heap_create. * libgst/heap.h: Likewise for declaration. * libgst/oop.h: Likewise for _gst_init_oop_table declaration. * libgst/sysdep.c: Add address parameter to _gst_osmem_reserve and to the implementations of the function. Support MAP_AUTORESRV as a synonym of MAP_NORESERVE. * libgst/sysdep.h: Likewise for declaration. --- orig/libgst/alloc.c +++ mod/libgst/alloc.c @@ -714,7 +714,7 @@ morecore (size_t size) #ifdef NO_MALLOC_OVERRIDE if (current_heap == NULL) { - just_allocated_heap = _gst_heap_create (MMAP_AREA_SIZE); + just_allocated_heap = _gst_heap_create (NULL, MMAP_AREA_SIZE); if (!just_allocated_heap) return (NULL); current_heap = just_allocated_heap; @@ -746,7 +746,7 @@ morecore (size_t size) if (just_allocated_heap) return (NULL); - just_allocated_heap = _gst_heap_create (MMAP_AREA_SIZE); + just_allocated_heap = _gst_heap_create (NULL, MMAP_AREA_SIZE); if (!just_allocated_heap) return (NULL); --- orig/libgst/heap.c +++ mod/libgst/heap.c @@ -100,7 +100,7 @@ extern int getpagesize (); heap -_gst_heap_create (int size) +_gst_heap_create (PTR address, int size) { struct heap mtemp; struct heap *hdp; @@ -112,6 +112,9 @@ _gst_heap_create (int size) pageround = pagesize - 1; } + if (address) + address -= HEAP_DELTA; + /* We start off with the heap descriptor allocated on the stack, until we build it up enough to call heap_sbrk_internal() to allocate the first page of the region and copy it there. Ensure @@ -121,7 +124,7 @@ _gst_heap_create (int size) hdp = &mtemp; memzero ((char *) hdp, sizeof (mtemp)); hdp->areasize = size; - hdp->base = _gst_osmem_reserve (size); + hdp->base = _gst_osmem_reserve (address, size); if (!hdp->base) return NULL; --- orig/libgst/heap.h +++ mod/libgst/heap.h @@ -55,7 +55,8 @@ typedef char *heap; -/* Initialize access to a heap managed region. +/* Initialize access to a heap managed region of the given SIZE, trying + to put it at the specified address. On success, returns a "heap descriptor" which is used in subsequent calls to other heap package functions. It is explicitly "char *" @@ -63,7 +64,7 @@ typedef char *heap; implementation details. On failure returns NULL. */ -extern heap _gst_heap_create (int size) +extern heap _gst_heap_create (PTR address, int size) ATTRIBUTE_HIDDEN; /* Terminate access to a heap managed region by unmapping all memory pages --- orig/libgst/lib.c +++ mod/libgst/lib.c @@ -528,7 +528,7 @@ gst_init_smalltalk (void) return 1; } - _gst_init_oop_table (INITIAL_OOP_TABLE_SIZE); + _gst_init_oop_table (NULL, INITIAL_OOP_TABLE_SIZE); _gst_init_mem_default (); _gst_init_dictionary (); _gst_init_interpreter (); --- orig/libgst/oop.c +++ mod/libgst/oop.c @@ -426,13 +426,13 @@ void _gst_update_object_memory_oop (OOP } void -_gst_init_oop_table (size_t size) +_gst_init_oop_table (PTR address, size_t size) { int i; oop_heap = NULL; for (i = MAX_OOP_TABLE_SIZE; i && !oop_heap; i >>= 1) - oop_heap = _gst_heap_create (i * sizeof (struct oop_s)); + oop_heap = _gst_heap_create (address, i * sizeof (struct oop_s)); if (!oop_heap) nomemory (true); --- orig/libgst/oop.h +++ mod/libgst/oop.h @@ -323,12 +323,12 @@ extern void _gst_init_mem (size_t eden, int space_grow_rate) ATTRIBUTE_HIDDEN; -/* Initialize an OOP table of SIZE bytes. Initially, all the OOPs are - free list so that's just how we initialize them. We do - as much initialization as we can, but we're called before classses - are defined, so things that have definite classes must wait until - the classes are defined. */ -extern void _gst_init_oop_table (size_t size) +/* Initialize an OOP table of SIZE bytes, trying at the given address if + possible. Initially, all the OOPs are on the free list so that's + just how we initialize them. We do as much initialization as we can, + but we're called before classses are defined, so things that have + definite classes must wait until the classes are defined. */ +extern void _gst_init_oop_table (PTR address, size_t size) ATTRIBUTE_HIDDEN; /* Dump the entire contents of the OOP table. Mainly for debugging --- orig/libgst/save.c +++ mod/libgst/save.c @@ -470,8 +470,8 @@ load_snapshot (int imageFd) header.oldSpaceSize, header.big_object_threshold, header.grow_threshold_percent, header.space_grow_rate); - _gst_init_oop_table (MAX (header.oopTableSize * 2, - INITIAL_OOP_TABLE_SIZE)); + _gst_init_oop_table (header.ot_base, + MAX (header.oopTableSize * 2, INITIAL_OOP_TABLE_SIZE)); ot_delta = (intptr_t) (_gst_mem.ot_base) - header.ot_base; num_used_oops = header.oopTableSize; --- orig/libgst/sysdep.c +++ mod/libgst/sysdep.c @@ -1429,14 +1429,14 @@ _gst_debug (void) typedef struct heap_implementation { mst_Boolean (*check) (); - PTR (*reserve) (size_t); + PTR (*reserve) (PTR, size_t); void (*release) (PTR, size_t); PTR (*commit) (PTR, size_t); void (*decommit) (PTR, size_t); } heap_implementation; #ifdef WIN32 -static PTR win32_reserve (size_t); +static PTR win32_reserve (PTR, size_t); static void win32_release (PTR, size_t); static PTR win32_commit (PTR, size_t); static void win32_decommit (PTR, size_t); @@ -1446,12 +1446,15 @@ struct heap_implementation heap_impl_tab }; #else /* !WIN32 */ +# if defined MAP_AUTORESRV && !defined MAP_NORESERVE +# define MAP_NORESERVE MAP_AUTORESRV +# endif # ifdef MAP_NORESERVE -static PTR noreserve_reserve (size_t); +static PTR noreserve_reserve (PTR, size_t); static void noreserve_decommit (PTR, size_t); #endif static mst_Boolean anon_mmap_check (void); -static PTR anon_mmap_reserve (size_t); +static PTR anon_mmap_reserve (PTR, size_t); static void anon_mmap_release (PTR, size_t); static PTR anon_mmap_commit (PTR, size_t); @@ -1481,7 +1484,7 @@ static int dev_zero = -1; static heap_implementation *impl; PTR -_gst_osmem_reserve (size_t size) +_gst_osmem_reserve (PTR address, size_t size) { if (!impl) { @@ -1489,7 +1492,7 @@ _gst_osmem_reserve (size_t size) The check is done at run-time because it is cheap. */ for (impl = heap_impl_tab; impl->reserve; impl++) if (!impl->check || impl->check ()) - return impl->reserve (size); + return impl->reserve (address, size); /* Not found, check again the next time just in case and return ENOMEM. */ @@ -1498,7 +1501,7 @@ _gst_osmem_reserve (size_t size) return (NULL); } else - return impl->reserve (size); + return impl->reserve (address, size); } void @@ -1563,10 +1566,10 @@ _gst_osmem_free (PTR ptr, size_t size) #ifdef WIN32 PTR -win32_reserve (size_t size) +win32_reserve (PTR address, size_t size) { PTR base; - base = VirtualAlloc(NULL, size, MEM_RESERVE, PAGE_NOACCESS); + base = VirtualAlloc(address, size, MEM_RESERVE, PAGE_NOACCESS); if (!base) errno = ENOMEM; @@ -1603,9 +1606,9 @@ win32_decommit (PTR base, size_t size) is available. */ PTR -noreserve_reserve (size_t size) +noreserve_reserve (PTR address, size_t size) { - PTR result = anon_mmap (NULL, size, PROT_NONE, + PTR result = anon_mmap (address, size, PROT_NONE, MAP_PRIVATE | MAP_NORESERVE); return result == MAP_FAILED ? NULL : result; @@ -1626,11 +1629,11 @@ noreserve_decommit (PTR base, size_t siz static char *baseaddr; PTR -anon_mmap_reserve (size_t size) +anon_mmap_reserve (PTR address, size_t size) { PTR base; - /* We must check for overflows in baseaddr! */ + /* We must check for overflows in baseaddr! Note that we ignore address. */ if (((uintptr_t) baseaddr) + size < (uintptr_t) baseaddr) { errno = ENOMEM; --- orig/libgst/sysdep.h +++ mod/libgst/sysdep.h @@ -243,7 +243,8 @@ extern void _gst_osmem_free (PTR ptr, si ATTRIBUTE_HIDDEN; /* Reserve SIZE bytes of the address space without allocating them. */ -extern PTR _gst_osmem_reserve (size_t size) +extern PTR _gst_osmem_reserve (PTR base, + size_t size) ATTRIBUTE_HIDDEN; /* Release SIZE bytes of the address space starting from BASE. */ _______________________________________________ help-smalltalk mailing list [hidden email] http://lists.gnu.org/mailman/listinfo/help-smalltalk |
Free forum by Nabble | Edit this page |