Christoph Thiede uploaded a new version of KernelTests to project The Trunk:
http://source.squeak.org/trunk/KernelTests-jar.449.mcz
==================== Summary ====================
Name: KernelTests-jar.449
Author: jar
Time: 2 January 2024, 12:28:08.184411 pm
UUID: decf5a85-87ad-5849-b692-ee28940eab41
Ancestors: KernelTests-jar.448
Test if #return:from: correctly handles returns to nil contexts
=============== Diff against KernelTests-jar.448 ===============
Item was added:
+ ----- Method: ContextTest>>testBlockCannotReturnToNil (in category 'tests') -----
+ testBlockCannotReturnToNil
+ "Test if #return:from: correctly handles returns to dead or nil contexts."
+
+ | context nextContext |
+ context := [] asContext.
+
+ "assert p is at the last instruction, i.e. a return, and is about to return to a nil context"
+ self assert: context method selector = thisContext method selector.
+ self assert: context sender isNil.
+ self assert: context willReturn.
+ self assert: context atEnd.
+
+ nextContext := context step. "step into a return to a nil sender"
+
+ self assert: nextContext method selector = #cannotReturn:!
Christoph Thiede uploaded a new version of Chronology-Core to project The Treated Inbox:
http://source.squeak.org/treated/Chronology-Core-jar.89.mcz
==================== Summary ====================
Name: Chronology-Core-jar.89
Author: jar
Time: 5 January 2024, 1:35:51.398632 am
UUID: d4f4b018-1b84-1c4a-910e-428004aac88c
Ancestors: Chronology-Core-mt.88
suggest a patch for Christoph's example in https://github.com/squeak-smalltalk/squeak-object-memory/issues/108
=============== Diff against Chronology-Core-mt.88 ===============
Item was changed:
----- Method: BlockClosure>>valueWithin:onTimeout: (in category '*chronology-core') -----
valueWithin: aDuration onTimeout: timeoutBlock
"Evaluate the receiver.
If the evaluation does not complete in less than aDuration evaluate the timeoutBlock instead"
| theProcess delay watchdog tag |
aDuration <= Duration zero ifTrue: [^ timeoutBlock value ].
"the block will be executed in the current process"
theProcess := Processor activeProcess.
delay := aDuration asDelay.
tag := self.
"make a watchdog process"
watchdog := [
delay wait. "wait for timeout or completion"
+ (theProcess notNil and: [theProcess isTerminated not]) ifTrue: [theProcess signalException: (TimedOut new tag: tag)]
- theProcess ifNotNil:[ theProcess signalException: (TimedOut new tag: tag)]
] newProcess.
"Watchdog needs to run at high priority to do its job (but not at timing priority)"
watchdog priority: Processor timingPriority-1.
"catch the timeout signal"
^ [ watchdog resume. "start up the watchdog"
self ensure:[ "evaluate the receiver"
theProcess := nil. "it has completed, so ..."
delay delaySemaphore signal. "arrange for the watchdog to exit"
]] on: TimedOut do: [ :e |
e tag == tag
ifTrue:[ timeoutBlock value ]
ifFalse:[ e pass]].!
Christoph Thiede uploaded a new version of Chronology-Core to project The Trunk:
http://source.squeak.org/trunk/Chronology-Core-jar.91.mcz
==================== Summary ====================
Name: Chronology-Core-jar.91
Author: jar
Time: 7 January 2024, 1:50:33.62718 pm
UUID: 449881a6-d6f2-1748-a77b-16c0a300483c
Ancestors: Chronology-Core-jar.90
an alternative fix of a bug in #valueWithin:onTimeout: described in Chronology-Core-jar.90
FYI: Issue: the method starts a watchdog at high priority before entering the ensure: method. But the active process may terminate before entering the ensure: inside valueWithin:onTimeout:, and thus the cleanup ensure argument block will not be executed during the unwind. As a result the watchod will assume the active process has not completed the watched block and will erroneously signal the TimedOut exception and a failure (BCR exception) inside #signalException will follow.
=============== Diff against Chronology-Core-jar.90 ===============
Item was changed:
----- Method: BlockClosure>>valueWithin:onTimeout: (in category '*chronology-core') -----
valueWithin: aDuration onTimeout: timeoutBlock
"Evaluate the receiver.
If the evaluation does not complete in less than aDuration evaluate the timeoutBlock instead"
| theProcess delay watchdog tag |
aDuration <= Duration zero ifTrue: [^ timeoutBlock value ].
"the block will be executed in the current process"
theProcess := Processor activeProcess.
delay := aDuration asDelay.
tag := self.
"make a watchdog process"
watchdog := [
+ delay wait. "wait for timeout"
+ theProcess signalException: (TimedOut new tag: tag)
- delay wait. "wait for timeout or completion"
- theProcess ifNotNil:[ theProcess signalException: (TimedOut new tag: tag)]
] newProcess.
"Watchdog needs to run at high priority to do its job (but not at timing priority)"
watchdog priority: Processor timingPriority-1.
"catch the timeout signal"
+ ^ [[watchdog resume. "start up the watchdog"
+ self value] ensure: [ "evaluate the receiver"
+ watchdog terminate. "exit the watchdog"
- ^ [ [watchdog resume. "start up the watchdog"
- self value] ensure:[ "evaluate the receiver"
- theProcess := nil. "it has completed, so ..."
- delay delaySemaphore signal. "arrange for the watchdog to exit"
]] on: TimedOut do: [ :e |
e tag == tag
ifTrue:[ timeoutBlock value ]
ifFalse:[ e pass]].!
Christoph Thiede uploaded a new version of Chronology-Core to project The Trunk:
http://source.squeak.org/trunk/Chronology-Core-jar.90.mcz
==================== Summary ====================
Name: Chronology-Core-jar.90
Author: jar
Time: 5 January 2024, 12:03:49.89018 pm
UUID: 498e4b92-020c-2442-bb24-ad77536e626f
Ancestors: Chronology-Core-mt.88
fix a bug in #valueWithin:onTimeout:
see https://github.com/squeak-smalltalk/squeak-object-memory/issues/108
Issue: the method starts a watchdog at high priority before entering the ensure: method. But the active process may terminate before entering the ensure: inside valueWithin:onTimeout:, and thus the cleanup ensure argument block will not be executed during the unwind. As a result the watchod will assume the active process has not completed the watched block and will erroneously signal the TimedOut exception and a failure (BCR exception) inside #signalException will follow.
=============== Diff against Chronology-Core-mt.88 ===============
Item was changed:
----- Method: BlockClosure>>valueWithin:onTimeout: (in category '*chronology-core') -----
valueWithin: aDuration onTimeout: timeoutBlock
"Evaluate the receiver.
If the evaluation does not complete in less than aDuration evaluate the timeoutBlock instead"
| theProcess delay watchdog tag |
aDuration <= Duration zero ifTrue: [^ timeoutBlock value ].
"the block will be executed in the current process"
theProcess := Processor activeProcess.
delay := aDuration asDelay.
tag := self.
"make a watchdog process"
watchdog := [
delay wait. "wait for timeout or completion"
theProcess ifNotNil:[ theProcess signalException: (TimedOut new tag: tag)]
] newProcess.
"Watchdog needs to run at high priority to do its job (but not at timing priority)"
watchdog priority: Processor timingPriority-1.
"catch the timeout signal"
+ ^ [ [watchdog resume. "start up the watchdog"
+ self value] ensure:[ "evaluate the receiver"
- ^ [ watchdog resume. "start up the watchdog"
- self ensure:[ "evaluate the receiver"
theProcess := nil. "it has completed, so ..."
delay delaySemaphore signal. "arrange for the watchdog to exit"
]] on: TimedOut do: [ :e |
e tag == tag
ifTrue:[ timeoutBlock value ]
ifFalse:[ e pass]].!
Marcel Taeumel uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-mt.1551.mcz
==================== Summary ====================
Name: Kernel-mt.1551
Author: mt
Time: 10 January 2024, 6:09:51.670122 pm
UUID: 61ce6dab-9cbd-df43-9d59-a0477314a163
Ancestors: Kernel-mt.1550
Revert but document the latest change for the int-float arithmetic with #/ as it changes precision but should not.
=============== Diff against Kernel-mt.1550 ===============
Item was changed:
----- Method: SmallInteger>>/ (in category 'arithmetic') -----
/ aNumber
"Primitive. This primitive (for /) divides the receiver by the argument
and returns the result if the division is exact. Fail if the result is not a
whole integer. Fail if the argument is 0 or is not a SmallInteger. Optional.
No Lookup. See Object documentation whatIsAPrimitive."
<primitive: 10>
+ ^ super / aNumber
+
+ "In theory, we could also exploit mixed arithmetic speed-up through float
+ primitives. However, the reciprocal approach with multiplication involves
+ two rounding operations instead of one, which changes the resulting precision.
+ { 3.0 / 5.0 . 3.0 * (1.0 / 5.0) }
+ --> #(0.6 0.6000000000000001)
+
^ aNumber isFloat
+ ifTrue: [(1.0 / aNumber) * self ]
+ ifFalse: [super / aNumber]
+ "!
- ifTrue: [(1.0 / aNumber) * self "exploit mixed arithmetic in float primitives"]
- ifFalse: [super / aNumber]!
Marcel Taeumel uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-mt.1545.mcz
==================== Summary ====================
Name: Kernel-mt.1545
Author: mt
Time: 21 December 2023, 5:35:58.67902 pm
UUID: fcde1fb1-0264-7a40-9117-67d9fdd740de
Ancestors: Kernel-mt.1544
Propose different fallback for mixed int-float arithmetics to use VM-backed mixed float-int arithmetics for + - * / . Speed-up is about 7x on my machine.
=============== Diff against Kernel-mt.1544 ===============
Item was changed:
----- Method: SmallInteger>>* (in category 'arithmetic') -----
* aNumber
"Primitive. Multiply the receiver by the argument and answer with the
result if it is a SmallInteger. Fail if the argument or the result is not a
SmallInteger. Essential. No Lookup. See Object documentation whatIsAPrimitive."
<primitive: 9>
+ ^ aNumber isFloat
+ ifTrue: [aNumber * self "exploit mixed arithmetic in float primitives"]
+ ifFalse: [super * aNumber]!
- ^ super * aNumber!
Item was changed:
----- Method: SmallInteger>>+ (in category 'arithmetic') -----
+ aNumber
"Primitive. Add the receiver to the argument and answer with the result
if it is a SmallInteger. Fail if the argument or the result is not a
SmallInteger Essential No Lookup. See Object documentation whatIsAPrimitive."
<primitive: 1>
+ ^ aNumber isFloat
+ ifTrue: [aNumber + self "exploit mixed arithmetic in float primitives"]
+ ifFalse: [super + aNumber]!
- ^ super + aNumber!
Item was changed:
----- Method: SmallInteger>>- (in category 'arithmetic') -----
- aNumber
"Primitive. Subtract the argument from the receiver and answer with the
result if it is a SmallInteger. Fail if the argument or the result is not a
SmallInteger. Essential. No Lookup. See Object documentation
whatIsAPrimitive."
<primitive: 2>
+ ^ aNumber isFloat
+ ifTrue: [aNumber negated + self "exploit mixed arithmetic in float primitives"]
+ ifFalse: [super - aNumber]!
- ^super - aNumber!
Item was changed:
----- Method: SmallInteger>>/ (in category 'arithmetic') -----
/ aNumber
"Primitive. This primitive (for /) divides the receiver by the argument
and returns the result if the division is exact. Fail if the result is not a
whole integer. Fail if the argument is 0 or is not a SmallInteger. Optional.
No Lookup. See Object documentation whatIsAPrimitive."
<primitive: 10>
+ ^ aNumber isFloat
+ ifTrue: [(1.0 / aNumber) * self "exploit mixed arithmetic in float primitives"]
+ ifFalse: [super / aNumber]!
- ^super / aNumber!
Marcel Taeumel uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-mt.1550.mcz
==================== Summary ====================
Name: Kernel-mt.1550
Author: mt
Time: 10 January 2024, 10:09:15.266957 am
UUID: 8f04eaa3-9dff-3d40-83f5-5783afc41380
Ancestors: Kernel-ct.1549, Kernel-mt.1545
Merge Kernel-mt.1545:
- Propose different fallback for mixed int-float arithmetics to use VM-backed mixed float-int arithmetics for + - * / . Speed-up is about 7x on my machine.
No measurable slowdown for non-float fallback paths.
=============== Diff against Kernel-ct.1549 ===============
Item was changed:
----- Method: SmallInteger>>* (in category 'arithmetic') -----
* aNumber
"Primitive. Multiply the receiver by the argument and answer with the
result if it is a SmallInteger. Fail if the argument or the result is not a
SmallInteger. Essential. No Lookup. See Object documentation whatIsAPrimitive."
<primitive: 9>
+ ^ aNumber isFloat
+ ifTrue: [aNumber * self "exploit mixed arithmetic in float primitives"]
+ ifFalse: [super * aNumber]!
- ^ super * aNumber!
Item was changed:
----- Method: SmallInteger>>+ (in category 'arithmetic') -----
+ aNumber
"Primitive. Add the receiver to the argument and answer with the result
if it is a SmallInteger. Fail if the argument or the result is not a
SmallInteger Essential No Lookup. See Object documentation whatIsAPrimitive."
<primitive: 1>
+ ^ aNumber isFloat
+ ifTrue: [aNumber + self "exploit mixed arithmetic in float primitives"]
+ ifFalse: [super + aNumber]!
- ^ super + aNumber!
Item was changed:
----- Method: SmallInteger>>- (in category 'arithmetic') -----
- aNumber
"Primitive. Subtract the argument from the receiver and answer with the
result if it is a SmallInteger. Fail if the argument or the result is not a
SmallInteger. Essential. No Lookup. See Object documentation
whatIsAPrimitive."
<primitive: 2>
+ ^ aNumber isFloat
+ ifTrue: [aNumber negated + self "exploit mixed arithmetic in float primitives"]
+ ifFalse: [super - aNumber]!
- ^super - aNumber!
Item was changed:
----- Method: SmallInteger>>/ (in category 'arithmetic') -----
/ aNumber
"Primitive. This primitive (for /) divides the receiver by the argument
and returns the result if the division is exact. Fail if the result is not a
whole integer. Fail if the argument is 0 or is not a SmallInteger. Optional.
No Lookup. See Object documentation whatIsAPrimitive."
<primitive: 10>
+ ^ aNumber isFloat
+ ifTrue: [(1.0 / aNumber) * self "exploit mixed arithmetic in float primitives"]
+ ifFalse: [super / aNumber]!
- ^super / aNumber!
Christoph Thiede uploaded a new version of System to project The Trunk:
http://source.squeak.org/trunk/System-ct.1444.mcz
==================== Summary ====================
Name: System-ct.1444
Author: ct
Time: 9 January 2024, 8:11:21.160382 pm
UUID: d3468d51-cc4d-a44f-8aad-6900e10ba2cc
Ancestors: System-dtl.1442
MessageTally: Moves clean-up of timed process spying into an ensure block, analogously to sibling methods. Fixes a memory leak.
=============== Diff against System-dtl.1442 ===============
Item was changed:
----- Method: MessageTally>>spyEvery:onProcess:forMilliseconds: (in category 'initialize-release') -----
spyEvery: millisecs onProcess: aProcess forMilliseconds: msecDuration
"Create a spy and spy on the given process at the specified rate."
| myDelay observedProcess sem |
(aProcess isKindOf: Process)
ifFalse: [self error: 'spy needs a Process here'].
self class: aProcess suspendedContext receiver class method: aProcess suspendedContext method.
"set up the probe"
observedProcess := aProcess.
myDelay := Delay forMilliseconds: millisecs.
time0 := Time millisecondClockValue.
endTime := time0 + msecDuration.
sem := Semaphore new.
gcStats := Smalltalk getVMParameters.
Timer ifNotNil: [ self error: 'it seems a tally is already running' ].
Timer := [
[
startTime := Time millisecondClockValue.
myDelay wait.
self
tally: Processor preemptedProcess suspendedContext
in: (observedProcess == Processor preemptedProcess
ifTrue: [ observedProcess ]
ifFalse: [ nil ])
"tally can be > 1 if ran a long primitive"
by: (Time millisecondClockValue - startTime) // millisecs.
startTime < endTime
] whileTrue.
sem signal.
] newProcess.
Timer priority: Processor timingPriority-1.
"activate the probe and evaluate the block"
Timer resume.
"activate the probe and wait for it to finish"
+ [sem wait] ensure: [
+ self class terminateTimerProcess.
+ self computeGCStats.
+ time := Time millisecondClockValue - time0]!
- sem wait.
- self computeGCStats.
- time := Time millisecondClockValue - time0!