Eliot Miranda uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-eem.1323.mcz
==================== Summary ====================
Name: Kernel-eem.1323
Author: eem
Time: 15 April 2020, 4:46:14.261016 pm
UUID: 5ea740f0-f4c6-4808-b7b6-2e3aee87aa91
Ancestors: Kernel-eem.1322
Update the ClassBuilder and instance migration, given the changes in Collections-eem.885. See http://forum.world.st/How-to-become-immediate-objects-td5114931.html.
=============== Diff against Kernel-eem.1322 ===============
Item was changed:
----- Method: ClassBuilder>>update:to: (in category 'class mutation') -----
update: oldClass to: newClass
"Convert oldClass, all its instances and possibly its meta class into newClass,
instances of newClass and possibly its meta class. The process is surprisingly
simple in its implementation and surprisingly complex in its nuances and potentially
bad side effects.
We can rely on two assumptions (which are critical):
#1: The method #updateInstancesFrom: will not create any lasting pointers to
'old' instances ('old' is quote on quote since #updateInstancesFrom: will do
a become of the old vs. the new instances and therefore it will not create
pointers to *new* instances before the #become: which are *old* afterwards)
#2: The non-preemptive execution of the critical piece of code guarantees that
nobody can get a hold by 'other means' (such as process interruption and
reflection) on the old instances.
Given the above two, we know that after #updateInstancesFrom: there are no pointers
to any old instances. After the forwarding become there will be no pointers to the old
class or meta class either.
Andreas Raab, 2/27/2003 23:42"
| meta |
meta := oldClass isMeta.
"Note: Everything from here on will run without the ability to get interrupted
to prevent any other process to create new instances of the old class."
["Note: The following removal may look somewhat obscure and needs an explanation.
When we mutate the class hierarchy we create new classes for any existing subclass.
So it may look as if we don't have to remove the old class from its superclass. However,
at the top of the hierarchy (the first class we reshape) that superclass itself is not newly
created so therefore it will hold both the oldClass and newClass in its (obsolete or not)
subclasses. Since the #become: below will transparently replace the pointers to oldClass
with newClass the superclass would have newClass in its subclasses TWICE. With rather
unclear effects if we consider that we may convert the meta-class hierarchy itself (which
is derived from the non-meta class hierarchy).
Due to this problem ALL classes are removed from their superclass just prior to converting
them. Here, breaking the superclass/subclass invariant really doesn't matter since we will
effectively remove the oldClass (becomeForward:) just a few lines below."
oldClass superclass removeSubclass: oldClass.
oldClass superclass removeObsoleteSubclass: oldClass.
"make sure that the VM cache is clean"
oldClass methodDict do: [:cm | cm flushCache].
"Convert the instances of oldClass into instances of newClass"
newClass updateInstancesFrom: oldClass.
meta
ifTrue:
+ [{oldClass} elementsForwardIdentityAndHashTo: {newClass}.
- [oldClass becomeForward: newClass.
oldClass updateMethodBindingsTo: oldClass binding]
ifFalse:
+ [{oldClass. oldClass class} elementsForwardIdentityAndHashTo: {newClass. newClass class}.
- [{oldClass. oldClass class} elementsForwardIdentityTo: {newClass. newClass class}.
oldClass updateMethodBindingsTo: oldClass binding.
oldClass class updateMethodBindingsTo: oldClass class binding].
"eem 5/31/2014 07:22 At this point there used to be a garbage collect whose purpose was
to ensure no old instances existed after the becomeForward:. Without the GC it was possible
to resurrect old instances using e.g. allInstancesDo:. This was because the becomeForward:
updated references from the old objects to new objects but didn't destroy the old objects.
But as of late 2013/early 2014 becomeForward: has been modified to free all the old objects."]
valueUnpreemptively!
Item was changed:
----- Method: ClassDescription>>updateInstances:from:isMeta: (in category 'initialize-release') -----
updateInstances: oldInstances from: oldClass isMeta: isMeta
"Recreate any existing instances of the argument, oldClass, as instances of the receiver,
which is a newly changed class. Permute variables as necessary, and forward old instances
to new instances. Answer nil to defeat old clients that expect an array of old instances.
The old behaviour, which necessitated a global GC, exchanged identities and answered
the old instances. But no clients used the result. This way we avoid the unnecessary GC,"
| map variable instSize newInstances |
oldInstances isEmpty ifTrue:
[^nil]. "no instances to convert"
isMeta ifTrue:
[(oldInstances size = 1
and: [self soleInstance class == self
or: [self soleInstance class == oldClass]]) ifFalse:
[^self error: 'Metaclasses can only have one instance']].
map := self instVarMappingFrom: oldClass.
variable := self isVariable.
instSize := self instSize.
newInstances := Array new: oldInstances size.
1 to: oldInstances size do:
[:i|
newInstances
at: i
put: (self newInstanceFrom: (oldInstances at: i) variable: variable size: instSize map: map)].
"Now perform a bulk mutation of old instances into new ones"
+ oldInstances elementsForwardIdentityAndHashTo: newInstances.
- oldInstances elementsForwardIdentityTo: newInstances.
^nil!
Eliot Miranda uploaded a new version of Collections to project The Trunk:
http://source.squeak.org/trunk/Collections-eem.885.mcz
==================== Summary ====================
Name: Collections-eem.885
Author: eem
Time: 15 April 2020, 4:37:54.800631 pm
UUID: 45d219d3-6ed0-4401-a820-44eebe21d71a
Ancestors: Collections-eem.883, Collections-dtl.884
Switch elementsForwardIdentityTo: to not copy the hash, see http://forum.world.st/How-to-become-immediate-objects-td5114931.html.
Add elementsForwardIdentityAndHashTo: for the old behavior.
=============== Diff against Collections-dtl.884 ===============
Item was added:
+ ----- Method: Array>>elementsForwardIdentityAndHashTo: (in category 'converting') -----
+ elementsForwardIdentityAndHashTo: otherArray
+ "This primitive performs a bulk mutation, causing all pointers to the elements of the
+ receiver to be replaced by pointers to the corresponding elements of otherArray.
+ The identityHashes remain with the pointers rather than with the objects so that
+ the objects in this array should still be properly indexed in any existing hashed
+ structures after the mutation."
+ <primitive: 72 error: ec>
+ ec == #'no modification' ifTrue:
+ [^self modificationForbiddenFor: otherArray becomeSelector: #elementsForwardIdentityAndHashTo:].
+ ec == #'bad receiver' ifTrue:
+ [^self error: 'receiver must be of class Array'].
+ ec == #'bad argument' ifTrue:
+ [^self error: (otherArray class == Array
+ ifTrue: ['arg must be of class Array']
+ ifFalse: ['receiver and argument must have the same size'])].
+ ec == #'inappropriate operation' ifTrue:
+ [^self error: 'can''t become immediates such as SmallIntegers or Characters'].
+ ec == #'object is pinned' ifTrue:
+ [^self error: 'can''t become pinned objects'].
+ ec == #'insufficient object memory' ifTrue:
+ [self error: 'The virtual machine is out-of-date. Please upgrade.'].
+ self primitiveFailed!
Item was changed:
----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') -----
elementsForwardIdentityTo: otherArray
"This primitive performs a bulk mutation, causing all pointers to the elements of the
receiver to be replaced by pointers to the corresponding elements of otherArray.
+ The identityHashes are not copied to the target objects so that the objects in otherArray
+ should still be properly indexed in any existing hashed structures after the mutation."
+ <primitive: 248 error: ec>
- The identityHashes remain with the pointers rather than with the objects so that
- the objects in this array should still be properly indexed in any existing hashed
- structures after the mutation."
- <primitive: 72 error: ec>
ec == #'no modification' ifTrue:
[^self modificationForbiddenFor: otherArray becomeSelector: #elementsForwardIdentityTo:].
ec == #'bad receiver' ifTrue:
[^self error: 'receiver must be of class Array'].
ec == #'bad argument' ifTrue:
[^self error: (otherArray class == Array
ifTrue: ['arg must be of class Array']
ifFalse: ['receiver and argument must have the same size'])].
ec == #'inappropriate operation' ifTrue:
[^self error: 'can''t become immediates such as SmallIntegers or Characters'].
ec == #'object is pinned' ifTrue:
[^self error: 'can''t become pinned objects'].
ec == #'insufficient object memory' ifTrue:
[self error: 'The virtual machine is out-of-date. Please upgrade.'].
self primitiveFailed!
Eliot Miranda uploaded a new version of System to project The Trunk:
http://source.squeak.org/trunk/System-eem.1152.mcz
==================== Summary ====================
Name: System-eem.1152
Author: eem
Time: 15 April 2020, 4:11:22.143513 pm
UUID: 3e0d01fb-556b-4a58-926d-417c7b193a4e
Ancestors: System-mt.1151
Change some SystemNavigation methods to use selectorsDo:; messagesDo: should be deprecated at some point.
=============== Diff against System-mt.1151 ===============
Item was changed:
----- Method: SystemNavigation>>allUnimplementedCalls (in category 'query') -----
allUnimplementedCalls
"Answer a collection of each message that is sent by an expression in a method but is not implemented by any object in the system."
| result implementedMessages |
implementedMessages := self allImplementedMessages.
result := OrderedCollection new.
self allSelectorsAndMethodsDo: [ :behavior :selector :method |
+ method selectorsDo: [ :each |
- method messagesDo: [ :each |
(implementedMessages includes: each) ifFalse: [
result add: (String streamContents: [ :stream |
stream
nextPutAll: behavior name;
space;
nextPutAll: selector;
space;
nextPutAll: 'calls: ';
nextPutAll: each ]) ] ] ].
^result!
Item was changed:
----- Method: SystemNavigation>>allUnimplementedNonPrimitiveCalls (in category 'query') -----
allUnimplementedNonPrimitiveCalls
"Answer an collection of each message that is sent by an expression in a method but is not implemented by any object in the system. This list won't include primitive methods."
| result implementedMessages |
implementedMessages := self allImplementedMessages.
result := OrderedCollection new.
self allSelectorsAndMethodsDo: [ :behavior :selector :method |
method primitive = 0 ifTrue: [
+ method selectorsDo: [ :each |
- method messagesDo: [ :each |
(implementedMessages includes: each) ifFalse: [
result add: (String streamContents: [ :stream |
stream
nextPutAll: behavior name;
space;
nextPutAll: selector;
space;
nextPutAll: 'calls: ';
nextPutAll: each ]) ] ] ] ].
^result!
Item was changed:
----- Method: SystemNavigation>>unimplemented (in category 'query') -----
unimplemented
"Answer an collection of each message that is sent by an expression in a method but is not implemented by any object in the system."
| implemented unimplemented |
implemented := self allImplementedMessages.
unimplemented := IdentityDictionary new.
self allSelectorsAndMethodsDo: [ :behavior :selector :method |
+ method selectorsDo: [ :each |
- method messagesDo: [ :each |
| entry |
(implemented includes: each) ifFalse: [
entry := unimplemented
at: each
ifPresent: [ :oldEntry |
oldEntry copyWith: behavior name, '>', selector ]
ifAbsent: [
{ behavior name, '>', selector } ].
unimplemented at: each put: entry ] ] ].
^unimplemented!
Hello,
I just noticed that the top-level RootProject, when entered, makes the
VM take a lot of CPU (a full core on my system, which amounts to 100%).
I'm on windows 8.1.
Is this expected?
Stef
Marcel Taeumel uploaded a new version of Tools to project The Trunk:
http://source.squeak.org/trunk/Tools-mt.958.mcz
==================== Summary ====================
Name: Tools-mt.958
Author: mt
Time: 15 April 2020, 5:55:35.334699 pm
UUID: 8d488e07-f7e5-5a47-9861-a23cb62b6871
Ancestors: Tools-mt.957
For MVC projects, fixes high CPU load during menu invocation.
Note that #controlActivity is only used when PopUpMenu is invoked from within an MVC project. Yes, we should clean up this part in the future.
Complements ST80-mt.251.
=============== Diff against Tools-mt.957 ===============
Item was changed:
----- Method: PopUpMenu>>controlActivity (in category 'basic control sequence') -----
controlActivity
"Do whatever a menu must do - now with keyboard support."
| didNotMove downPos |
didNotMove := true.
Sensor anyButtonPressed
ifFalse:
[didNotMove := false.
Sensor waitButtonOrKeyboard].
+
-
Sensor keyboardPressed ifFalse: [self manageMarker].
(didNotMove and: [selection = 0])
ifTrue:
[downPos := Sensor cursorPoint.
[didNotMove and: [Sensor anyButtonPressed]]
whileTrue:
+ [ Project current world activeController interActivityPause.
+ (downPos dist: Sensor cursorPoint) < 2 ifFalse: [didNotMove := false]].
- [(downPos dist: Sensor cursorPoint) < 2 ifFalse: [didNotMove := false]].
didNotMove ifTrue: [Sensor waitButtonOrKeyboard]].
[Sensor keyboardPressed] whileTrue:
[self readKeyboard ifTrue: [^ self].
Sensor waitButtonOrKeyboard].
+ [Sensor anyButtonPressed] whileTrue: [
+ ScheduledControllers activeController interActivityPause.
+ self manageMarker]!
- [Sensor anyButtonPressed] whileTrue: [self manageMarker]!
Marcel Taeumel uploaded a new version of ST80 to project The Trunk:
http://source.squeak.org/trunk/ST80-mt.251.mcz
==================== Summary ====================
Name: ST80-mt.251
Author: mt
Time: 15 April 2020, 5:53:42.145699 pm
UUID: 07f97eb2-f0c8-df4c-9f7b-fa6225418264
Ancestors: ST80-mt.250
For MVC projects, fixes high CPU load during empty world and while scrolling lists.
=============== Diff against ST80-mt.250 ===============
Item was changed:
----- Method: Controller>>controlLoop (in category 'basic control sequence') -----
controlLoop
"Sent by Controller|startUp as part of the standard control sequence.
Controller|controlLoop sends the message Controller|isControlActive to test
for loop termination. As long as true is returned, the loop continues.
When false is returned, the loop ends. Each time through the loop, the
message Controller|controlActivity is sent."
+ [self interActivityPause. self isControlActive] whileTrue: [
+ self controlActivity. Processor yield]!
- [self isControlActive] whileTrue: [
- self interActivityPause. self controlActivity. Processor yield]!
Item was changed:
----- Method: ScrollController>>scrollAbsolute (in category 'private') -----
scrollAbsolute
| markerOutline oldY markerForm |
self changeCursor: Cursor rightArrow.
oldY := -1.
sensor anyButtonPressed ifTrue:
[markerOutline := marker deepCopy.
markerForm := Form fromDisplay: marker.
Display fill: marker fillColor: scrollBar insideColor.
Display border: markerOutline width: 1 fillColor: Color gray.
markerForm
follow:
[oldY ~= sensor cursorPoint y
ifTrue:
[oldY := sensor cursorPoint y.
marker := marker translateBy:
0 @ ((oldY - marker center y
min: scrollBar inside bottom - marker bottom)
max: scrollBar inside top - marker top).
self scrollView].
marker origin]
+ while: [
+ self interActivityPause.
+ sensor anyButtonPressed].
- while: [sensor anyButtonPressed].
Display fill: markerOutline fillColor: scrollBar insideColor.
self moveMarker]!