[Vm-dev] Time primHighResClock truncated to 32 bits in 64 bits VMs.

Eliot Miranda eliot.miranda at gmail.com
Thu Dec 28 17:00:00 UTC 2017


Hi Juan,

On Thu, Dec 28, 2017 at 4:32 AM, Juan Vuletich <JuanVuletich at zoho.com>
wrote:

>
> Hi Folks,
>
> In 32 bit Cog VMs, `Time primHighResClock` answers LargePositiveInteger,
> presumably up to 64 bits. This would mean a rollover in 167 years on a
> 3.5GHz machine.
>
> But on 64 bit Cog and Stack Spur VMs, it answers a SmallInteger that is
> truncated to 32 bits. This means a rollover in about one second.
>

Are you sure?  What's a test case?  When I look at the source I don't see
where this is happening:

platforms/Cross/vm/sq.h:sqLong ioHighResClock(void);

InterpreterPrimitives>>primitiveHighResClock
"Return the value of the high resolution clock if this system has any. The
exact frequency of the high res clock is undefined specifically so that we
can use processor dependent instructions (like RDTSC). The only use for the
high res clock is for profiling where we can allocate time based on
sub-msec resolution of the high res clock. If no high-resolution counter is
available, the platform should return zero."
<export: true>
self pop: 1.
self push: (self positive64BitIntegerFor: self ioHighResClock).

And positive64BitIntegerFor: does not truncate to 32-bits:

StackInterpreter>>positive64BitIntegerFor: integerValue
<api>
<var: 'integerValue' type: #usqLong>
<var: 'highWord' type: #'unsigned int'>
"Answer a Large Positive Integer object for the given integer value.  N.B.
will *not* cause a GC."
| newLargeInteger highWord sz |
objectMemory hasSixtyFourBitImmediates
ifTrue:
[(self cCode: [integerValue] inSmalltalk: [integerValue bitAnd: 1 << 64 -
1]) <= objectMemory maxSmallInteger ifTrue:
[^objectMemory integerObjectOf: integerValue].
sz := 8]
ifFalse:
[(highWord := integerValue >> 32) = 0 ifTrue:
[^self positive32BitIntegerFor: integerValue].
sz := 5.
(highWord := highWord >> 8) = 0 ifFalse:
[sz := sz + 1.
(highWord := highWord >> 8) = 0 ifFalse:
[sz := sz + 1.
(highWord := highWord >> 8) = 0 ifFalse:[sz := sz + 1]]]].
newLargeInteger := objectMemory
eeInstantiateSmallClassIndex: ClassLargePositiveIntegerCompactIndex
format: (objectMemory byteFormatForNumBytes: sz)
numSlots: 8 / objectMemory bytesPerOop.
objectMemory storeLong64: 0 ofObject: newLargeInteger withValue:
(objectMemory byteSwapped64IfBigEndian: integerValue).
^newLargeInteger


So on my reading, on 64-bits this answers un-truncated non-negative
SmallIntegers up to 60 bits in length, and then overflows into 8 byte
LargePositiveIntegers.


> I guesss this is a bug. Answering a SmallInteger, truncating the CPU 64
> bit counter to 60 bits would be ok. I think it makes sense to restrict
> answer to SmallInteger to avoid allocation, and a rollover every 41 years
> is not too much :)
>
> Thanks,
>
> --
> Juan Vuletich
> www.cuis-smalltalk.org
> https://github.com/Cuis-Smalltalk/Cuis-Smalltalk-Dev
> @JuanVuletich
>
>
>


-- 
_,,,^..^,,,_
best, Eliot
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20171228/815c7cf1/attachment.html>


More information about the Vm-dev mailing list