On 7 Jul 2009, at 16:31, Niels Grewe wrote:

> I've just tried to compile the svn tree on my 64bit machine and ran  
> into
> the following issue: The ETObjectMirror class in the new reflection  
> code
> uses the address of the object it is mirroring as its hash.
> Unfortunately the unsigned int to which the pointer is cast will cause
> it to be truncated, possibly causing collisions between the hashes of
> mirrors of unrelated objects.


Collisions don't matter with -hash, they are expected.  The  
requirement is that if [a isEqual: b] then [a hash] == [b hash].   
There is no requirement that unrelated objects may not have the same  
hash.

> Unfortunately, GNUstep has not yet made the switch to the Mac OS
> 10.5-style definition of NSUInteger, which would just make this a
> non-issue because it would always be sized properly.

It did a while ago, perhaps you are using an old version.  That said,  
NS[U]integer is equivalent to C99's [u]intptr_t, and since we require  
C99 you can use these instead.  I've just checked, and -hash is  
declared as returning an NSUInteger on GNUstep.

The correct fix for this is just to change the return type of -hash in  
ETReflection.m to match the GNUstep version.

> I've attached a little workaround, which will use the hash of the  
> object
> if available and only fall back to the address otherwise. This way,  
> the
> truncation will only be a problem if you are on 64bit, have more than
> 4GB RAM, and the object does not conform to NSObject, which should be
> quite rare.

Note that you can, and frequently do, get pointers that are above the  
4GB line even if you have less than 4GB of RAM.  Processes still have  
more than 4GB of virtual address space, irrespective of the amount of  
physical RAM on a 64-bit system (typically around 48 bits of space).   
On an operating system with address space randomisation this is very  
common.

> I just wanted to check back prior to commiting that there
> isn't some rationale behind not using -hash at this place.


This looks like an attempt at an optimisation.  The two instances are  
only equal if they point to the same object, so you can use the object  
pointer as a hash, which can make collections slightly more efficient.

-hash is expected to be faster than -isEqual: so it's used as an  
optimisation in a number of collections.  For example, if you tell an  
array to delete any objects equal to an object, it will first scan  
through the array sending -hash to all of the elements.  It will then  
send -isEqual: to the ones that return the same hash as the original.   
This is faster than sending -isEqual: to every object.

David

_______________________________________________
Etoile-dev mailing list
Etoile-dev@gna.org
https://mail.gna.org/listinfo/etoile-dev

Reply via email to