[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Help-smalltalk] faster startup 4/n - last easy installment
From: |
Paolo Bonzini |
Subject: |
[Help-smalltalk] faster startup 4/n - last easy installment |
Date: |
Mon, 18 Dec 2006 11:38:38 +0100 |
User-agent: |
Thunderbird 1.5.0.8 (Macintosh/20061025) |
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 <address@hidden>
* 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. */
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Help-smalltalk] faster startup 4/n - last easy installment,
Paolo Bonzini <=