On 29 Jun 2008, at 10:38, Richard Frith-Macdonald wrote:
On 29 Jun 2008, at 08:54, David Ayers wrote:
Hello David
David Chisnall schrieb:
I think calling mmap directly is the wrong solution here. You
should be
using valloc() with the requested size rounded up to the nearest
page
I'm not sure what advantage valloc() has over mmap() ... all the
examples/recommendations I found on the web were for mmap().
valloc() will return a page from the heap, while mmap() will return
one from the operating system. If you have some complete pages in
your heap then valloc() will avoid the system call. Ideally this
allocation would be done with a per-thread NSZone, so that you can
just bump a pointer to get the allocation, although we probably can't
avoid the write -> execute transition in all cases (except on
platforms that allow W&X - on these having a W&X NSZone could make
things even faster, although slightly less safe).
My tests show that message passing via NSInvocation on GNUstep is
around 175 times greater than direct message passing (which, itself,
is around three to four times more expensive than C function calling),
so let's not make it any worse - considering that 90% of uses of
NSInvocation are for downward funargs, we can probably make it even
better, and it's something I plan on looking at in the near future.
For comparison, NSInvocation on OS X (10.5.3) is 350 times more
expensive than direct message passing and uses a lot more memory (my
simple test program, which doesn't autorelease until the end, used
650MB of RAM on OS X and only 350MB on FreeBSD/GNUstep). Looks like
they could learn something from looking at GNUstep...
size, and then use mprotect to set it as executable. Note that most
sane operating systems (and Vista) are moving to W^X, so you need
to set
it as writeable while creating it, then executable while using it
(i.e.
call mprotect immediately before the return).
Good, point ... the code already uses mprotect if available, but I
also changed it to refrain from trying to map the memory as
executable in the case where we can later use mprotect. This should
avoid problems on systems (I don't have one to test on) where an
attempt to map memory which is both writable and executable would
fail.
My man page for vmalloc states:
The obsolete function valloc() allocates size bytes and
returns a pointer to the allocated memory. The memory address will
be a
multiple of the page
size. It is equivalent to memalign(sysconf(_SC_PAGESIZE),size).
I'm not sure whether you are aware of the fact that this function is
considered obsolete.
Not according to POSIX, however it is recommended that applications
use mmap or malloc if possible. In our case, the ideal solution would
be a dedicated, mmap-backed, NSZone for allocating invocation
trampolines.
Hi Richard,
My man page for mmap states:
MAP_ANON
Synonym for MAP_ANONYMOUS. Deprecated.
So to me it seems the new #ifndef logic is inverted.
Thanks ... I changed that round to use MAP_ANONYMOUS preferentially.
MAP_ANON and MAP_ANONYMOUS are both extensions. One is SysV, the
other is BSD in origin. The correct (POSIX / SUS) way of doing this
is to specify neither and use /dev/zero as the mapping device.
David
_______________________________________________
Gnustep-dev mailing list
Gnustep-dev@gnu.org
http://lists.gnu.org/mailman/listinfo/gnustep-dev