faster startup 4/n - last easy installment

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

faster startup 4/n - last easy installment

Paolo Bonzini
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