Signals and Slots in D
Frits van Bommel
fvbommel at REMwOVExCAPSs.nl
Fri Sep 29 01:51:45 PDT 2006
Walter Bright wrote:
> Frank Benoit wrote:
>> Inverting the lsb will not, because it is also a valid ptr to the object.
>> Inverting the msb should always work. Well it should work in the way,
>> that it does not prevent the object from being deleted.
>> But how can it be tested, that the ptr is callable?
>
> I don't think msb will work, either, as there's no guarantee the gc pool
> won't straddle the boundary.
If you consider that you probably don't want your 'hidden' pointers to
be valid for objects they /didn't/ point to either, this gets harder...
I don't think such a simple scheme (XORing with something) can be
guaranteed to work in the general case, unless you assume the GC pool
spans at most half the address space. [1]
Once it gets to be over 2GB (on x86) I think there's basically no way to
make this work.
[1]: If you *do* assume that, (void* p){ return 2 * start_of_gc_pool -
cast(size_t)p; } should provide unique values guaranteed not to point to
the GC pool as long as the original one did. And feeding the returned
value back to it will return the original.
Maybe you could try splitting the pointer up in two parts, stored
separately? (i.e. use more than size_t.sizeof bytes to store it)
This could be literally, storing the upper half and lower half of the
address in different ints.
Another option is also two ints: one pseudo-random, the other pointer
XOR the first.
Yet another one (I like this one, it's pretty much guaranteed to work):
Find some (ptr_bits/2)-bit address range that's guaranteed to not
contain valid pointers. IIRC, both Windows and Linux use the upper GB or
so for kernel address space, so the GC pool should never be located
there on these OSs. Other OSs probably have something similar, if
perhaps in a different location.
Then just store the upper and lower halves in separate ints, whose upper
half ensure the total value is guaranteed to be int the OS-reserved part
of the address space. (e.g. set the upper 16 bits to 1s, the lower 16 to
the parts of the pointer stored)
Another variant of the "kernel-reserved address space" I just thought
of: If you know that the OS the program is compiled on reserves the top
1 GB of address space for itself, store the top two bits of the pointer
set those to one in your stored pointer, and restore them before
returning. Simpler and only uses 34 bits on a 32-bit computer. Of
course, memory allocation granularity means you'll likely still allocate
at least 5 or 8 bytes and thus still "waste" some bytes.
Or you could "just" implement introspection and update the GC to ignore
non-pointers. Then cast the pointer to a size_t for storage so the GC
ignores it :). This one will probably be the most work, but will also
gives some side-benefits[2]. (I believe it's a long-standing feature
request...)
[2]: Or is it the other way around and is this a side-benefit of
implementing introspection? Not sure :).
More information about the Digitalmars-d
mailing list