FloatArrayPlugin & 64bitting

Ian Piumarta ian.piumarta at inria.fr
Fri Apr 29 06:42:07 UTC 2005


On Apr 28, 2005, at 18:12, Tim Rowledge wrote:

> FloatArrayPlugin doesn't feel well when we generate it from the 64bit 
> VMMaker alpha. It has a clause:-
>
> 	}
> 	rcvrPtr = ((float *) (interpreterProxy->firstIndexableField(rcvr)));
>
> 	/* Check if any of the argument's values is zero */
>
> 	argPtr = ((float *) (interpreterProxy->firstIndexableField(arg)));
> 	for (i = 0; i <= (length - 1); i += 1) {
> 		if ((longAt(argPtr + i)) == 0) {
> 			return interpreterProxy->primitiveFail();
> 		}
> which upsets the typing of longAt since it expects an sqInt. I can 
> trivially alter it to cast the rcvrPtr to an sqInt for the use of the 
> longAt and it compiles/runs ok.

Casting is not allowed between pointers and integers (or, as in this 
case, between pointers and oops).  It only works for you because oops 
are the same as the address of the object in memory to which they refer 
when running on 32-bit hardware.  This is almost guaranteed not to be 
the case on 64-bit hardware.

> I have no idea if a 64bit machine will have floats of 64 bits (ie the 
> same as sqInt) or if they stay 32bit (ie we have to use plain int, 
> which may upset longAt on a 64bit machine) or what. And since I have 
> no 64bit setup, I can't say I'm massively bothered right now. But 
> somebody probably is and if anyone cares to suggest the nicest fix 
> I'll happily include it.

In general, on LP64 machines, float remains 32 bits and double 64 bits. 
  So the dirty solution would be to use an int accessor.  If you look in 
sqMemoryAccess.h you will find pointer versions of all the at[put] 
functions.  So...

Not having the context handy (i.e., not knowing what precedes/follows 
the code in question) this might be a suitable first approximation 
(note that firstIndexableField returns a pointer, not an int):

	float *argPtr;
...
	/* Check if any of the argument's values is zero */

	argPtr = ((float *) (interpreterProxy->firstIndexableField(arg)));
	for (i = 0; i <= (length - 1); i += 1) {
		if ((intAtPointer(argPtr + i)) == 0) {
			return interpreterProxy->primitiveFail();
		}

but that begs the question: why are we testing for integer 0 in an 
array of floats?  Even if 0.0 happens to have all 0 bits, it would seem 
better to implement floatAtPointer() in sqMemoryAccess.h and compare 
against 0.0 (assuming the compiler and runtime agree on what 
constitutes floating 0 -- floating equality is a dodgy concept wherever 
it occurs).

Then again, if it ain't broken don't fix it.  Change the longAt() to 
intAtPointer() and the code should have the same semantics as before, 
not require any casting (other than the void * from firstIndexable to 
float *) and work on 64-bit platforms too, even when oops do not 
correspond to addresses.

Cheers,
Ian




More information about the Vm-dev mailing list