Eliot Miranda uploaded a new version of System to project The Trunk:
http://source.squeak.org/trunk/System-eem.1422.mcz
==================== Summary ====================
Name: System-eem.1422
Author: eem
Time: 11 August 2023, 5:28:50.658058 pm
UUID: e09b0643-71d9-4b48-9b54-5d898b1381a2
Ancestors: System-mt.1421
Up the lowSpaceThreshold by the size of newSpace, if on Spur. This allows the low-space mechanism to function in current trunk images.
=============== Diff against System-mt.1421 ===============
Item was changed:
----- Method: SmalltalkImage>>lowSpaceThreshold (in category 'memory space') -----
lowSpaceThreshold
"Answer the low space threshold. When the amount of free memory (after garbage collection)
falls below this limit, the system is in serious danger of completely exhausting memory and
crashing. This limit should be made high enough to allow the user open a debugger to diagnose
a problem or to save the image. In a stack-based VM such as Cog contexts for activations in
+ the stack zone will have to be created as the debugger opens, requiring additional headroom.
+ In a scavenging VM, as in the Spur memory manager/object representation, the scavenger
+ may attempt to tenure all of new space, so the threshold must be larger than the size of eden."
- the stack zone will have to be created as the debugger opens, requiring additional headroom."
+ | newSpaceBytes slotsForDebugger slotsForContextsOnStackPages |
+ "newSpace = pastSpace+futureSpace+eden= 1/7 + 1/7 + 5/7. Ungar's generation scavenger
+ paper uses these ratios; so does Spur. At any one time eden and only one of the survivor spaces
+ is in use, so using the total newSpace size is 1/6 larger than the maximum tenurable memory."
+ newSpaceBytes := (Smalltalk vmParameterAt: 44 ifAbsent: 0) // 5 * 7.
- | slotsForDebugger slotsForContextsOnStackPages |
slotsForDebugger := 65536. "Arbitrary guess"
slotsForContextsOnStackPages :=
(self vmParameterAt: 42 ifAbsent: nil)
ifNil: [0]
ifNotNil:
[:numStackPages| | headerSize numActivationsPerPage maxContextSize |
numActivationsPerPage := 40. "Design goal of the Cog & Stack VMs"
headerSize := 8 / self wordSize. "64-bits for Spur"
maxContextSize := thisContext class instSize + CompiledMethod fullFrameSize + headerSize.
numStackPages * numActivationsPerPage * maxContextSize].
+ ^slotsForDebugger + slotsForContextsOnStackPages * self wordSize max: newSpaceBytes!
- ^slotsForDebugger + slotsForContextsOnStackPages * self wordSize!
Marcel Taeumel uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-mt.2121.mcz
==================== Summary ====================
Name: Morphic-mt.2121
Author: mt
Time: 11 August 2023, 12:43:21.630243 pm
UUID: 74380a65-c494-2e44-b617-9491b2cbfde3
Ancestors: Morphic-mt.2120
Add scale-factor support for soft (and hard) shadows.
Note that we might want to add a fast-path for hard shadows as those could be implemented with one or two simple #fillRectangle: calls and no cache. If translucent morph colors should not be supported anymore, this would even work for morphs with #roundedCorners...
If memory is an issue, disable shadows via:
Morph useSoftDropShadow: false.
Preferences disable: #menuAppearance3d.
=============== Diff against Morphic-mt.2120 ===============
Item was changed:
----- Method: Morph>>drawDropShadowOn: (in category 'drawing') -----
drawDropShadowOn: aCanvas
"Rectangular shadow with support for rounded corners."
+ | shadowOffset shadowBounds |
+ shadowBounds := (shadowOffset := self shadowOffsetDisplayScaled) isRectangle
+ ifTrue: [self bounds outsetBy: shadowOffset]
+ ifFalse: [self bounds translateBy: (shadowOffset negated max: 0@0)].
- | shadowBounds |
- shadowBounds := self shadowOffset isRectangle
- ifTrue: [self bounds outsetBy: self shadowOffset]
- ifFalse: [self bounds translateBy: (self shadowOffset negated max: 0@0)].
"Only redraw the shadow if the shadow area is affected."
+ ((aCanvas clipRect intersects: shadowBounds)
+ and: [((self bounds insetBy: (self wantsRoundedCorners ifFalse: [0] ifTrue: [self cornerRadius])) containsRect: aCanvas clipRect) not])
+ ifTrue: [
+ (self hasProperty: #dropShadow)
+ ifFalse: [self updateDropShadowCache].
+ aCanvas
+ translucentImage: (self valueOfProperty: #dropShadow)
+ at: shadowBounds topLeft].!
- ((aCanvas clipRect intersects: shadowBounds) and: [((self bounds insetBy: (self wantsRoundedCorners ifFalse: [0] ifTrue: [self cornerRadius])) containsRect: aCanvas clipRect) not])
- ifTrue: [
- (self hasProperty: #dropShadow)
- ifFalse: [self updateDropShadowCache].
- aCanvas
- translucentImage: (self valueOfProperty: #dropShadow)
- at: shadowBounds topLeft].!
Item was changed:
----- Method: Morph>>expandFullBoundsForDropShadow: (in category 'drawing') -----
expandFullBoundsForDropShadow: aRectangle
"Return an expanded rectangle for an eventual drop shadow"
- | delta box |
+ | shadowOffset delta box |
+ (shadowOffset := self shadowOffsetDisplayScaled) isRectangle
+ ifTrue: [^ aRectangle outsetBy: shadowOffset].
- self shadowOffset isRectangle
- ifTrue: [^ aRectangle outsetBy: self shadowOffset].
box := aRectangle.
+ delta := shadowOffset.
- delta := self shadowOffset.
box := delta x >= 0
ifTrue:[box right: aRectangle right + delta x]
ifFalse:[box left: aRectangle left + delta x].
box := delta y >= 0
ifTrue:[box bottom: aRectangle bottom + delta y]
ifFalse:[box top: aRectangle top + delta y].
^box!
Item was added:
+ ----- Method: Morph>>shadowOffsetDisplayScaled (in category 'drop shadows') -----
+ shadowOffsetDisplayScaled
+
+ | scale shadowOffset |
+ scale := RealEstateAgent scaleFactor.
+ ^ (shadowOffset := self shadowOffset) isRectangle
+ ifTrue: [(shadowOffset topLeft * scale) truncated corner: (shadowOffset bottomRight * scale) truncated]
+ ifFalse: [(shadowOffset * scale) truncated]!
Item was changed:
----- Method: Morph>>updateDropShadowCache (in category 'drawing') -----
updateDropShadowCache
"Draws the receiver's drop shadow into a separate form (or cache) to be used repeatedly in #drawDropShadowOn:, which is itself guarded via #hasDropShadow (see #fullDrawOn:).
Note that this cache is not so much about performance as it is about visual aesthetics. While the shadow itself is just one or more repeated calls to fill/frame a (rounded rectangle), we finally cut out (or mask or erase) the inner portion so that translucent receiver's wont look awkward. This is not possible with direct drawing calls to BitBlt onto Display.
Also note that with the advent of the Spur object memory (http://www.mirandabanda.org/cogblog/category/spur/) in the OpenSmalltalk VM, we got a different garbage collector (GC) that does not yet have the most efficient incremental collection strategies. As an effect, repeated invalidation of the drop-shadow cache now entails frequent full-GC pauses and thus noticeable lags (or stuttering) in the environment. This has been the case since the release of Squeak 5.0, where we started to use the Spur object memory and hence the new GC.
To make the full-GC pauses less noticeable, we started to temporarily disable the drop shadow in situations where responsiveness is importent. For example, we do this for frequently used morphs such as all system windows when being resized using their corner (or edge) grips. You can get an overview of thus points by browsing senders of #targetHadDropShadow and #hasDropShadow: (or actually the code 'hasDropShadow: false', which typically starts the temporary disabling of the shadow).
+ February 2022: We are currently working on improving the incremental compaction in the OpenSmalltalk VM. Once that issue has been solved, we can remove that source code that disables the drop shadow temporarily.
+
+ March 2023: We might want to #hibernate unused shadows. Also, #scaleFactor support was added."
- February 2022: We are currently working on improving the incremental compaction in the OpenSmalltalk VM. Once that issue has been solved, we can remove that source code that disables the drop shadow temporarily."
+ | shadowOffset shadowBounds shadowColor shadowRadius offset form canvas drawBlock localBounds mask maskCanvas |
- | shadowOffset shadowBounds offset form canvas drawBlock localBounds mask maskCanvas |
self flag: #hasDropShadow. "Marker for senders browsing."
self flag: #targetHadDropShadow. "Marker for senders browsing."
+ (shadowOffset := self shadowOffsetDisplayScaled) isRectangle
- (shadowOffset := self shadowOffset) isRectangle
ifTrue: [
shadowBounds := 0@0 corner: (self bounds outsetBy: shadowOffset) extent.
offset := 0@0.
localBounds := shadowOffset topLeft extent: self extent ]
ifFalse: [
| extent |
extent := self extent.
shadowBounds := 0@0 corner: extent + shadowOffset abs.
offset := shadowOffset max: 0@0.
localBounds := (shadowOffset negated max: 0@0) extent: extent ].
form := Form extent: shadowBounds extent depth: Display depth.
canvas := form getCanvas.
+ shadowColor := self shadowColor.
+ shadowRadius := self wantsRoundedCorners ifTrue: [self cornerRadius max: 20 px] ifFalse: [20 px].
drawBlock := self useSoftDropShadow
+ ifFalse: [self wantsRoundedCorners
+ ifTrue: [ [:c | c fillRoundRect: localBounds radius: shadowRadius fillStyle: shadowColor] ]
+ ifFalse: [ [:c | c fillRectangle: localBounds fillStyle: shadowColor] ]]
- ifFalse: [
- [:c | self wantsRoundedCorners
- ifTrue: [c fillRoundRect: localBounds radius: self cornerRadius fillStyle: self shadowColor]
- ifFalse: [c fillRectangle: localBounds fillStyle: self shadowColor]]]
ifTrue: [
+ [:c | | a ad o od r rd |
+ a := shadowColor alpha.
+ ad := a.
+ o := -1.
+ od := RealEstateAgent scaleFactor.
+ r := shadowRadius.
+ rd := od.
+ 10 timesRepeat: [ | offsetHere alphaHere radiusHere |
+ offsetHere := (o :=
+ o + od) truncated.
+ alphaHere := (a := a + ad).
+ radiusHere := (r := r - rd) truncated.
+ c
+ fillRoundRect: (shadowBounds insetBy: offsetHere)
+ radius: radiusHere
+ fillStyle: (shadowColor alpha: alphaHere)]] ].
- [:c | self wantsRoundedCorners
- ifTrue: [0 to: 9 do: [:i |
- c
- fillRoundRect: (shadowBounds insetBy: i)
- radius: (self cornerRadius max: 20) -i
- fillStyle: (self shadowColor alpha: self shadowColor alpha * (i+1))]]
- ifFalse: [0 to: 9 do: [:i |
- c
- fillRoundRect: (shadowBounds insetBy: i) radius: 20-i
- fillStyle: (self shadowColor alpha: self shadowColor alpha * (i+1))]]]].
canvas
translateBy: offset
during: [ :shadowCanvas | drawBlock value: shadowCanvas].
"Support transparent morph colors without having the shadow to shine through.."
mask := Form extent: shadowBounds extent depth: Display depth.
maskCanvas := mask getCanvas.
self wantsRoundedCorners
ifTrue: [maskCanvas fillRoundRect: (localBounds insetBy: self borderWidth) radius: self cornerRadius fillStyle: Color black]
ifFalse: [maskCanvas fillRectangle: (localBounds insetBy: self borderWidth) fillStyle: Color black].
mask
displayOn: form
at: 0@0
rule: Form erase.
self setProperty: #dropShadow toValue: form.!
Marcel Taeumel uploaded a new version of System to project The Trunk:
http://source.squeak.org/trunk/System-mt.1421.mcz
==================== Summary ====================
Name: System-mt.1421
Author: mt
Time: 11 August 2023, 12:37:11.021243 pm
UUID: d0effb9a-4bd4-ba49-91b6-ec52e8ab437d
Ancestors: System-mt.1420
... I forgot to commit the postscript ...
=============== Diff against System-mt.1420 ===============
Item was changed:
+ (PackageInfo named: 'System') postscript: 'Smalltalk installLowSpaceWatcher.'!
- (PackageInfo named: 'System') postscript: 'ExtendedClipboardWinInterface initialize..'!
Marcel Taeumel uploaded a new version of System to project The Trunk:
http://source.squeak.org/trunk/System-mt.1420.mcz
==================== Summary ====================
Name: System-mt.1420
Author: mt
Time: 10 August 2023, 10:29:48.325968 am
UUID: b9808160-125f-0241-9b23-b20b33273bf2
Ancestors: System-mt.1419
For low-space warnings, make preference #logDebuggerStackToFile work again.
=============== Diff against System-mt.1419 ===============
Item was changed:
----- Method: SmalltalkImage>>lowSpaceWatcher (in category 'memory space') -----
lowSpaceWatcher
"Wait until the low space semaphore is signalled, then take appropriate actions."
| free preemptedProcess |
self garbageCollectMost <= self lowSpaceThreshold
ifTrue: [self garbageCollect <= self lowSpaceThreshold
ifTrue: ["free space must be above threshold before
starting low space watcher"
^ Beeper beep]].
Smalltalk specialObjectsArray at: 23 put: nil. "process causing low space will be saved here"
LowSpaceSemaphore := Semaphore new.
self primLowSpaceSemaphore: LowSpaceSemaphore.
self primSignalAtBytesLeft: self lowSpaceThreshold. "enable low space interrupts"
LowSpaceSemaphore wait. "wait for a low space condition..."
self primSignalAtBytesLeft: 0. "disable low space interrupts"
self primLowSpaceSemaphore: nil.
LowSpaceProcess := nil.
"The process that was active at the time of the low space interrupt."
+ preemptedProcess := (Smalltalk specialObjectsArray at: 23)
+ ifNil: [Processor preemptedProcess "if in-image signal of OutOfMemory"].
- preemptedProcess := Smalltalk specialObjectsArray at: 23.
Smalltalk specialObjectsArray at: 23 put: nil.
"Note: user now unprotected until the low space watcher is re-installed"
self memoryHogs isEmpty
ifFalse: [free := self bytesLeft.
self memoryHogs
do: [ :hog | hog freeSomeSpace ].
self bytesLeft > free
ifTrue: [ ^ self installLowSpaceWatcher ]].
Preferences logDebuggerStackToFile ifTrue: [
self
logError: 'Space is low'
inContext: preemptedProcess suspendedContext
to: 'LowSpaceDebug.log'].
Project current
interruptName: 'Space is low'
message: self lowSpaceChoices
preemptedProcess: preemptedProcess
!
Marcel Taeumel uploaded a new version of Collections to project The Trunk:
http://source.squeak.org/trunk/Collections-mt.1048.mcz
==================== Summary ====================
Name: Collections-mt.1048
Author: mt
Time: 2 August 2023, 10:47:45.179314 am
UUID: 87f828cf-6d3f-414e-82b7-a53244f9d19c
Ancestors: Collections-dtl.1047
Makes #withoutDuplicates available to more kinds of collections. Offer #copyWithoutDuplicates as an alias matching the more explicit #copyWithout* protocol as we are always creating copies, even if the receiver does not contain any duplicates.
Do not allow duplicate removal for Bitset, CharacterSet, Heap, Matrix.
=============== Diff against Collections-dtl.1047 ===============
Item was added:
+ ----- Method: Bag>>withoutDuplicates (in category 'copying') -----
+ withoutDuplicates
+ "Overwritten for better performance. We already know about the unique items in the receiver."
+
+ ^ self species basicNew
+ setContents: (contents collect: [:count | 1]);
+ yourself!
Item was added:
+ ----- Method: Bitset>>withoutDuplicates (in category 'copying') -----
+ withoutDuplicates
+
+ self shouldNotImplement.!
Item was added:
+ ----- Method: CharacterSet>>withoutDuplicates (in category 'copying') -----
+ withoutDuplicates
+
+ self shouldNotImplement.!
Item was added:
+ ----- Method: Collection>>copyWithoutDuplicates (in category 'copying') -----
+ copyWithoutDuplicates
+ "Convenience for the original #withoutDuplicates matching the copy-without protocol."
+
+ ^ self withoutDuplicates!
Item was added:
+ ----- Method: Collection>>withoutDuplicates (in category 'copying') -----
+ withoutDuplicates
+ "Answer a copy of the receiver that preserves order but eliminates any duplicates."
+
+ | seen |
+ seen := Set new: self size.
+ ^ self select: [:each | seen ifAbsentAdd: each]!
Item was added:
+ ----- Method: Heap>>withoutDuplicates (in category 'copying') -----
+ withoutDuplicates
+
+ self shouldNotImplement.!
Item was added:
+ ----- Method: Matrix>>withoutDuplicates (in category 'copying') -----
+ withoutDuplicates
+
+ self shouldNotImplement.!
Item was removed:
- ----- Method: SequenceableCollection>>withoutDuplicates (in category 'copying') -----
- withoutDuplicates
- "Answer a copy of the receiver that preserves order but eliminates any duplicates."
- | seen |
- seen := Set new: self size.
- ^self select: [:each| seen ifAbsentAdd: each]!
Item was added:
+ ----- Method: Set>>withoutDuplicates (in category 'copying') -----
+ withoutDuplicates
+ "Overwritten for better performance. We already know about the unique items in the receiver."
+
+ ^ self copy!
Marcel Taeumel uploaded a new version of System to project The Trunk:
http://source.squeak.org/trunk/System-mt.1419.mcz
==================== Summary ====================
Name: System-mt.1419
Author: mt
Time: 10 August 2023, 10:00:12.66062 am
UUID: f31524e9-118a-6241-bdf7-71b8ff3a7e30
Ancestors: System-dtl.1418
Complements Collections-mt.1049
=============== Diff against System-dtl.1418 ===============
Item was added:
+ ----- Method: WeakRegistry>>copyWithoutDuplicates (in category 'copying') -----
+ copyWithoutDuplicates
+
+ self shouldNotImplement.!
Marcel Taeumel uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-mt.1519.mcz
==================== Summary ====================
Name: Kernel-mt.1519
Author: mt
Time: 10 August 2023, 9:59:32.01762 am
UUID: b33a4757-113b-6542-b28f-08991dd78522
Ancestors: Kernel-mt.1518
Complements Collections-mt.1049
=============== Diff against Kernel-mt.1518 ===============
Item was added:
+ ----- Method: DependentsArray>>copyWithoutDuplicates (in category 'copying') -----
+ copyWithoutDuplicates
+
+ self shouldNotImplement.!