[Vm-dev] intAt from sqMemoryAccess.h does not extend sign
David T. Lewis
lewis at mail.msen.com
Tue Nov 8 15:08:01 UTC 2016
On Tue, Nov 08, 2016 at 03:19:50PM +0100, Nicolas Cellier wrote:
>
> Hi David,
> Sorry, I've no linux/mac vm available currently to exhibit the problem.
Hi Nicolas,
I was using this pre-built Spur VM:
Virtual Machine
---------------
/usr/local/lib/squeak/5.0-201607171247_64/squeak
Croquet Closure Cog[Spur] VM [CoInterpreterPrimitives VMMaker.oscog-eem.1902]
Unix built on Jul 17 2016 14:02:20 Compiler: 4.6.3
platform sources revision VM: r201607171247 https://github.com/OpenSmalltalk/opensmalltalk-vm.git $ Date: Sun Jul 17 14:47:17 2016 +0200 $ Plugins: r201607171247 https://github.com/OpenSmalltalk/opensmalltalk-vm.git $
CoInterpreter VMMaker.oscog-eem.1902 uuid: d5860bb5-b41c-4337-90d4-c2abc979248d Jul 17 2016
StackToRegisterMappingCogit VMMaker.oscog-eem.1902 uuid: d5860bb5-b41c-4337-90d4-c2abc979248d Jul 17 2016
Unfortunately I cannot compile Cog/Spur on my Ubuntu PC (build system issues),
so I cannot be of much help beyond that.
But just for my own understanding, is it the case that IntegerArray access
does not work for you on a 64 bit image on Windows?
Note, the #ifdef USE_INLINE_MEMORY_ACCESSORS is very old. I think that Ian
wrote it (Tim might know better). The only memory access code that I wrote
is the Smalltalk (slang) version in the VMMaker repository, but that is
not relevant here.
Dave
> But if you look at github head revision
>
> https://raw.githubusercontent.com/OpenSmalltalk/opensmalltalk-vm/Cog/spur64src/vm/gcc3x-cointerp.c
>
> then you'll find this code:
>
> primitiveIntegerAt(void)
> { DECL_MAYBE_SQ_GLOBAL_STRUCT
> sqInt addr;
> ... snip declarations of no interest ...
> sqInt value;
> ... snip long preamble to check parameter types ...
>
> /* for zero indexing */
> addr = (rcvr + BaseHeaderSize) + ((index - 1) * 4);
> value = intAt(addr);
> /* begin pop: */
> GIV(stackPointer) += 2 * BytesPerWord;
> if ((((((usqInt) value) >> 60) + 1) & 15) <= 1) {
> /* begin pushInteger: */
> longAtput((sp = GIV(stackPointer) - BytesPerWord), ((value << 3) | 1));
> GIV(stackPointer) = sp;
> }
> else {
> ... snip this branch is never reached ...
> }
> }
>
> Above code clearly can't work if the 32bit contents of addr is not
> sign-extended into the 64bits value...
> So I don't know which version you used exactly,
> ...UNLESS...
> there might be another reason for the mismatch in:
>
> https://github.com/OpenSmalltalk/opensmalltalk-vm/blob/Cog/platforms/Cross/vm/sqMemoryAccess.h
>
> You can see that the two possible compiler branches don't agree and won't
> behave the same sign-wise:
>
> #ifdef USE_INLINE_MEMORY_ACCESSORS
> /* Use static inline functions when the compiler produces efficient
> code for small accessors.
> These are preferred because static type checking will prevent
> inadvertent confusion of pointers and oops. */
> ... snip ...
> static inline sqInt intAtPointer(char *ptr) { return
> (sqInt)(*((unsigned int *)ptr)); }
> static inline sqInt intAtPointerput(char *ptr, int val) { return
> (sqInt)(*((unsigned int *)ptr)= val); }
> ... snip ...
>
> #else /* USE_INLINE_MEMORY_ACCESSORS */
> /* Use macros when static inline functions aren't efficient. */
> ... snip ...
> # define intAtPointer(ptr) ((sqInt)(*((int *)(ptr))))
> # define intAtPointerput(ptr,val) ((sqInt)(*((int *)(ptr))= (int)(val)))
> ... snip ...
> #endif /* USE_INLINE_MEMORY_ACCESSORS */
>
> I presume you (or someone else) arranged to not USE_INLINE_MEMORY_ACCESSORS
> Though it seems to be the default to use them on macosx (I'm just invoking
> ./mvm).
>
> The two branches should better adopt the same (sane) behavior, shouldn't
> they?
>
> 2016-11-08 14:23 GMT+01:00 David T. Lewis <lewis at mail.msen.com>:
>
> >
> > On Tue, Nov 08, 2016 at 03:29:05AM +0100, Nicolas Cellier wrote:
> > >
> > > In this code:
> > >
> > > static inline sqInt intAtPointer(char *ptr) { return
> > > (sqInt)(*((unsigned int *)ptr)); }
> > > static inline sqInt intAtPointerput(char *ptr, int val) { return
> > > (sqInt)(*((unsigned int *)ptr)= val); }
> > >
> > > the usage of unsigned int is questionable...
> > > It means that intAt and long32At won't perform sign extension in 64bits
> > > Spur VM.
> > > Since it returns a signed result (sqInt), that's troubling.
> > >
> > > The sole real sender of intAt seems to be primitiveIntegerAt: which fails
> > > for this reason on 64bits spur when fed with negative integers.
> >
> >
> > Can you give an example of the failure? I tried on 64-bit Spur and also
> > on image format 68002 (64-bit V3) on Linux, and the accesses to elements
> > of an IntegerArray work correctly in both cases.
> >
> >
> > For example:
> >
> > { -1 . -2 . -3 . -4 . 7 . -9 } asIntegerArray ==> an IntegerArray(-1 -2 -3
> > -4 7 -9)
> >
> > Accessing the elements of this IntegerArray works as expected, and I can
> > see
> > in an inspector that the first element is stored internally as 16rFFFFFFFF.
> >
> > Is there something else that is failing?
> >
> > Dave
> >
> >
> > >
> > > For long32At, it's difficult to analyze: many senders!
> > >
> > > IMO, if we don't want a signed quantity, we should better write
> > > unsignedLong32At (or use lowcode uint32AtPointer which answers a 32 bits
> > > result)
> >
> >
More information about the Vm-dev
mailing list