I used to think so, but it's not quite true.
The same subroutine should accept stack data pointers and
heap data pointers.
Yes, but
* automatic variables don't have to be on the "hardware stack".
* only those variables which actually are accessed via pointer
need to be in a pointer-accessible space.
So a compiler could put stuff like
* return addresses
* non-array automatic variables which don't have their address taken
* function arguments and return values
* temporary variables
into the stack segment and automatic variables which do have their
address taken into the data segment.
Among other things this means that return addresses are not accessible
with a pointer and can't be overwritten by a buffer overflow. It also
means that the size of the stack segment will almost always be very
small (arrays will (almost) never be there) and that function call and
return are more expensive (you need to maintain a second "stack").
So I'm not sure whether the advantages outweigh the disadvantages.
But that's moot. I don't expect any new segmented architectures, and
existing ones are either obsolete or used in "flat" mode.
This is not what I experience with my system (which has less than 4GB
memory, though). The monsters like Mozilla take more text memory that
data memory (unless one loads a LOT of HTML into the browser).
Mozilla is a monster, but it still uses only about 40 MB of code memory,
which is about 1% of 4 GB:
% perl -e 'while (<>) { my ($b, $e, $p) = /^(\w+)-(\w+) (\S+)/; $s =
hex($e) - hex($b); $s{$p} += $s } for (keys %s) { printf "%s %9d\n",
$_, $s{$_} / 1024 }' /proc/18752/maps |sort -n -k 2
---p 64
rwxp 192
r--s 496
rw-s 768
r-xp 40656
r--p 98524
rw-p 279960
(this is firefox 3.6 running on 32bit linux for about a day)
So if you moved that code into a different segment, you could use 4GB
instead of 3.96GB for data. Doesn't seem like much of an improvement.
(especially if you consider that on most 32-bit OSs the address space is
limited to 2 or 3 GB anyway - lifting that limit would have a much
larger effect).
I see the smiley but I'd like to clarify for our young readers that
32bit Linux uses near pointers. On the 386, a far pointer would be 48
bits.
... but only if you round up to a multiple of 8bit; otherwise 46bit.
[*] AFAIK, Solaris (tries to?) separate code from data AMAP. On
Solaris/i386, are they in different segments?
I don't think so. Sun likes Java. Java uses JIT compilers. JIT compilers
and separated address spaces for code and data don't mesh well.
Do not see how this would be related.
A JIT compiler needs to generate executable code which is immediately
executed by the same process. This is hard to do if the JIT compiler
can't put the code into a place where it can be executed.
AFAI suspect (basing on the sparse info I have seen), the only way to
load code on solaris is to write an executable module on disk, and
dlopen() it.
That would absolutely kill the performance of a JIT compiler. If
Solaris/x86 uses separate code and data segments (which I doubt) then
there is probably some way (maybe with mmap) to map a region of memory
into both the data and the code segment. More likely they use a common
address space and just use mprotect to prevent execution of data which
isn't meant to be code.
hp