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