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